From 64204886af165557792a0a51954ae2a00fa3a02f Mon Sep 17 00:00:00 2001 From: zxu123 Date: Thu, 30 Nov 2017 16:11:59 -0500 Subject: Warn user if we raise with empty while not online To avoid surprise by adding a warning. Right now, when offline, empty result is returned with no log nor error, see https://groups.google.com/forum/#!topic/google-cloud-firestore-discuss/puFl9HVU57I/discussion --- Firestore/Source/Core/FSTEventManager.m | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Firestore/Source/Core/FSTEventManager.m b/Firestore/Source/Core/FSTEventManager.m index 3e1b99b..ec03eb7 100644 --- a/Firestore/Source/Core/FSTEventManager.m +++ b/Firestore/Source/Core/FSTEventManager.m @@ -20,6 +20,7 @@ #import "Firestore/Source/Core/FSTSyncEngine.h" #import "Firestore/Source/Model/FSTDocumentSet.h" #import "Firestore/Source/Util/FSTAssert.h" +#import "Firestore/Source/Util/FSTLogger.h" NS_ASSUME_NONNULL_BEGIN @@ -179,6 +180,11 @@ NS_ASSUME_NONNULL_BEGIN return NO; } + // Warn user if we raise initial event with empty documents while we are not actually online. + if (snapshot.documents.isEmpty && onlineState != FSTOnlineStateHealthy) { + FSTWarn(@"Could not reach Firestore backend."); + } + // Raise data from cache if we have any documents or we are offline return !snapshot.documents.isEmpty || onlineState == FSTOnlineStateFailed; } -- cgit v1.2.3 From 7eebb6ec638425460f958a9e61456311e47b03ba Mon Sep 17 00:00:00 2001 From: Ryan Wilson Date: Mon, 4 Dec 2017 17:30:57 -0500 Subject: Add log to warn users of iOS 7 deprecation. (#527) * Add log warning users of iOS 7 deprecation. * Changed "warning" to "notice". * Removed DEBUG flag --- Firebase/Core/FIRApp.m | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/Firebase/Core/FIRApp.m b/Firebase/Core/FIRApp.m index 835a1a4..242fd79 100644 --- a/Firebase/Core/FIRApp.m +++ b/Firebase/Core/FIRApp.m @@ -20,6 +20,7 @@ #import "Private/FIRBundleUtil.h" #import "Private/FIRLogger.h" #import "Private/FIROptionsInternal.h" +#import "third_party/FIRAppEnvironmentUtil.h" NSString *const kFIRServiceAdMob = @"AdMob"; NSString *const kFIRServiceAuth = @"Auth"; @@ -131,6 +132,22 @@ static FIRApp *sDefaultApp; [FIRApp sendNotificationsToSDKs:sDefaultApp]; sDefaultApp.alreadySentConfigureNotification = YES; } + + if (![FIRAppEnvironmentUtil isFromAppStore]) { + // Support for iOS 7 has been deprecated, but will continue to function for the time being. + // Log a notice for developers who are still targeting iOS 7 as the minimum OS version + // supported. + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ + NSDictionary *info = [[NSBundle mainBundle] infoDictionary]; + + NSString *minVersion = info[@"MinimumOSVersion"]; + if ([minVersion hasPrefix:@"7."]) { + FIRLogNotice(kFIRLoggerCore, @"I-COR000026", @"Support for iOS 7 is deprecated and will " + @"stop working in the future. Please upgrade your app to target iOS 8 or " + @"above."); + } + }); + } } } -- cgit v1.2.3 From f502f42e26e47f163f46d42648e043eda0601cbb Mon Sep 17 00:00:00 2001 From: Zsika Phillip Date: Mon, 4 Dec 2017 17:28:35 -0800 Subject: Fixes stating host (#528) --- Example/Auth/Sample/SettingsViewController.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Example/Auth/Sample/SettingsViewController.m b/Example/Auth/Sample/SettingsViewController.m index de91806..24a6513 100644 --- a/Example/Auth/Sample/SettingsViewController.m +++ b/Example/Auth/Sample/SettingsViewController.m @@ -43,7 +43,7 @@ static NSString *const kSecureTokenRequestClassName = @"FIRSecureTokenRequest"; /** @var kIdentityToolkitSandboxHost @brief The host of Identity Toolkit sandbox server. */ -static NSString *const kIdentityToolkitSandboxHost = @"www-googleapis-staging.sandbox.google.com"; +static NSString *const kIdentityToolkitSandboxHost = @"staging-www.sandbox.googleapis.com"; /** @var kSecureTokenSandboxHost @brief The host of Secure Token Service sandbox server. -- cgit v1.2.3 From ef2a0a2acf7f727b50e5acb6b652ff8551124c9d Mon Sep 17 00:00:00 2001 From: zxu123 Date: Tue, 5 Dec 2017 11:42:31 -0500 Subject: implement log warning for offline status * Move the logic from FSTEventManager to FSTRemoteStore. Pros: per query vs per stream. * Since state can go into unknown normally (e.g. no listener is registered and nobody care the status), we only warns when status is actually offline to avoid confusion. --- Firestore/Source/Core/FSTEventManager.m | 6 ------ Firestore/Source/Remote/FSTRemoteStore.m | 3 +++ 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/Firestore/Source/Core/FSTEventManager.m b/Firestore/Source/Core/FSTEventManager.m index ec03eb7..3e1b99b 100644 --- a/Firestore/Source/Core/FSTEventManager.m +++ b/Firestore/Source/Core/FSTEventManager.m @@ -20,7 +20,6 @@ #import "Firestore/Source/Core/FSTSyncEngine.h" #import "Firestore/Source/Model/FSTDocumentSet.h" #import "Firestore/Source/Util/FSTAssert.h" -#import "Firestore/Source/Util/FSTLogger.h" NS_ASSUME_NONNULL_BEGIN @@ -180,11 +179,6 @@ NS_ASSUME_NONNULL_BEGIN return NO; } - // Warn user if we raise initial event with empty documents while we are not actually online. - if (snapshot.documents.isEmpty && onlineState != FSTOnlineStateHealthy) { - FSTWarn(@"Could not reach Firestore backend."); - } - // Raise data from cache if we have any documents or we are offline return !snapshot.documents.isEmpty || onlineState == FSTOnlineStateFailed; } diff --git a/Firestore/Source/Remote/FSTRemoteStore.m b/Firestore/Source/Remote/FSTRemoteStore.m index f7c3e57..42dab58 100644 --- a/Firestore/Source/Remote/FSTRemoteStore.m +++ b/Firestore/Source/Remote/FSTRemoteStore.m @@ -188,6 +188,9 @@ static const int kOnlineAttemptsBeforeFailure = 2; BOOL didChange = (watchStreamOnlineState != self.watchStreamOnlineState); self.watchStreamOnlineState = watchStreamOnlineState; if (didChange) { + if (watchStreamOnlineState == FSTOnlineStateFailed) { + FSTWarn(@"Could not reach Firestore backend."); + } [self.onlineStateDelegate watchStreamDidChangeOnlineState:watchStreamOnlineState]; } } -- cgit v1.2.3 From a904be723a997ed434a36ce9562794a75673927e Mon Sep 17 00:00:00 2001 From: Paul Beusterien Date: Tue, 5 Dec 2017 15:56:46 -0800 Subject: Document post_install workaround for static library source pod usage (#534) --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 62f3cc3..e14e096 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,10 @@ If your Podfile does not include *use_frameworks!*, you need to workaround a build issue with the FirebaseAnalytics umbrella header. Delete the first four lines of Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FirebaseAnalytics.h or copy [patch/FirebaseAnalytics.h](patch/FirebaseAnalytics.h) to -Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FirebaseAnalytics.h +Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FirebaseAnalytics.h. +See the post_install phase of [Example/Podfile](Example/Podfile) for an example +of applying the workaround automatically - make sure you correct the path of +`patch/FirebaseAnalytics.h`. ## Usage -- cgit v1.2.3 From 125cdc78c68b322d4ff06a906ed32548ade46003 Mon Sep 17 00:00:00 2001 From: zxu123 Date: Wed, 6 Dec 2017 16:16:22 -0500 Subject: refactoring the condition when to warn offline --- Firestore/Source/Remote/FSTRemoteStore.m | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/Firestore/Source/Remote/FSTRemoteStore.m b/Firestore/Source/Remote/FSTRemoteStore.m index 42dab58..063e487 100644 --- a/Firestore/Source/Remote/FSTRemoteStore.m +++ b/Firestore/Source/Remote/FSTRemoteStore.m @@ -110,6 +110,9 @@ static const int kOnlineAttemptsBeforeFailure = 2; /** A count of consecutive failures to open the stream. */ @property(nonatomic, assign) int watchStreamFailures; +/** Whether the client should fire offline warning. */ +@property(nonatomic, assign) BOOL shouldWarnOffline; + #pragma mark Write Stream // The writeStream is null when the network is disabled. The non-null check is performed by // isNetworkEnabled. @@ -146,6 +149,7 @@ static const int kOnlineAttemptsBeforeFailure = 2; _lastBatchSeen = kFSTBatchIDUnknown; _watchStreamOnlineState = FSTOnlineStateUnknown; + _shouldWarnOffline = YES; _pendingWrites = [NSMutableArray array]; } return self; @@ -157,6 +161,7 @@ static const int kOnlineAttemptsBeforeFailure = 2; } - (void)setOnlineStateToHealthy { + self.shouldWarnOffline = NO; [self updateAndNotifyAboutOnlineState:FSTOnlineStateHealthy]; } @@ -179,6 +184,10 @@ static const int kOnlineAttemptsBeforeFailure = 2; } else { self.watchStreamFailures++; if (self.watchStreamFailures >= kOnlineAttemptsBeforeFailure) { + if (self.shouldWarnOffline) { + FSTWarn(@"Could not reach Firestore backend."); + self.shouldWarnOffline = NO; + } [self updateAndNotifyAboutOnlineState:FSTOnlineStateFailed]; } } @@ -188,9 +197,6 @@ static const int kOnlineAttemptsBeforeFailure = 2; BOOL didChange = (watchStreamOnlineState != self.watchStreamOnlineState); self.watchStreamOnlineState = watchStreamOnlineState; if (didChange) { - if (watchStreamOnlineState == FSTOnlineStateFailed) { - FSTWarn(@"Could not reach Firestore backend."); - } [self.onlineStateDelegate watchStreamDidChangeOnlineState:watchStreamOnlineState]; } } -- cgit v1.2.3 From cb5f3efd3ab53561afd7de625d16d014d14374dd Mon Sep 17 00:00:00 2001 From: alexg33 Date: Wed, 6 Dec 2017 15:41:47 -0800 Subject: Updating the Auth header comments for Jazzy syntax (#535) --- .../Auth/Source/Public/FIRAdditionalUserInfo.h | 4 +- Firebase/Auth/Source/Public/FIRAuth.h | 299 +++++++++------------ Firebase/Auth/Source/Public/FIRAuthDataResult.h | 4 +- Firebase/Auth/Source/Public/FIRAuthErrors.h | 44 +-- Firebase/Auth/Source/Public/FIREmailAuthProvider.h | 8 +- .../Auth/Source/Public/FIRFacebookAuthProvider.h | 2 +- .../Auth/Source/Public/FIRGitHubAuthProvider.h | 2 +- .../Auth/Source/Public/FIRGoogleAuthProvider.h | 2 +- Firebase/Auth/Source/Public/FIROAuthProvider.h | 6 +- Firebase/Auth/Source/Public/FIRPhoneAuthProvider.h | 57 ++-- .../Auth/Source/Public/FIRTwitterAuthProvider.h | 2 +- Firebase/Auth/Source/Public/FIRUser.h | 190 ++++++------- 12 files changed, 266 insertions(+), 354 deletions(-) diff --git a/Firebase/Auth/Source/Public/FIRAdditionalUserInfo.h b/Firebase/Auth/Source/Public/FIRAdditionalUserInfo.h index 36dd3aa..4f6947a 100644 --- a/Firebase/Auth/Source/Public/FIRAdditionalUserInfo.h +++ b/Firebase/Auth/Source/Public/FIRAdditionalUserInfo.h @@ -27,8 +27,8 @@ NS_SWIFT_NAME(AdditionalUserInfo) @interface FIRAdditionalUserInfo : NSObject /** @fn init - @brief This class should not be initialized manually. @c FIRAdditionalUserInfo can be retrieved - from from an instance of @c FIRAuthDataResult. + @brief This class should not be initialized manually. `FIRAdditionalUserInfo` can be retrieved + from from an instance of `FIRAuthDataResult`. */ - (instancetype)init NS_UNAVAILABLE; diff --git a/Firebase/Auth/Source/Public/FIRAuth.h b/Firebase/Auth/Source/Public/FIRAuth.h index 42b3ac5..f18a3d0 100644 --- a/Firebase/Auth/Source/Public/FIRAuth.h +++ b/Firebase/Auth/Source/Public/FIRAuth.h @@ -33,7 +33,7 @@ NS_ASSUME_NONNULL_BEGIN /** @typedef FIRAuthStateDidChangeListenerHandle - @brief The type of handle returned by @c FIRAuth.addAuthStateDidChangeListener:. + @brief The type of handle returned by `FIRAuth.addAuthStateDidChangeListener:`. */ typedef id FIRAuthStateDidChangeListenerHandle NS_SWIFT_NAME(AuthStateDidChangeListenerHandle); @@ -48,7 +48,7 @@ typedef void(^FIRAuthStateDidChangeListenerBlock)(FIRAuth *auth, FIRUser *_Nulla NS_SWIFT_NAME(AuthStateDidChangeListenerBlock); /** @typedef FIRIDTokenDidChangeListenerHandle - @brief The type of handle returned by @c FIRAuth.addIDTokenDidChangeListener:. + @brief The type of handle returned by `FIRAuth.addIDTokenDidChangeListener:`. */ typedef id FIRIDTokenDidChangeListenerHandle NS_SWIFT_NAME(IDTokenDidChangeListenerHandle); @@ -75,17 +75,17 @@ typedef void (^FIRAuthDataResultCallback)(FIRAuthDataResult *_Nullable authResul #if defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 /** - @brief The name of the @c NSNotificationCenter notification which is posted when the auth state + @brief The name of the `NSNotificationCenter` notification which is posted when the auth state changes (for example, a new token has been produced, a user signs in or signs out). The - object parameter of the notification is the sender @c FIRAuth instance. + object parameter of the notification is the sender `FIRAuth` instance. */ extern const NSNotificationName FIRAuthStateDidChangeNotification NS_SWIFT_NAME(AuthStateDidChange); #else /** - @brief The name of the @c NSNotificationCenter notification which is posted when the auth state + @brief The name of the `NSNotificationCenter` notification which is posted when the auth state changes (for example, a new token has been produced, a user signs in or signs out). The - object parameter of the notification is the sender @c FIRAuth instance. + object parameter of the notification is the sender `FIRAuth` instance. */ extern NSString *const FIRAuthStateDidChangeNotification NS_SWIFT_NAME(AuthStateDidChangeNotification); @@ -154,8 +154,8 @@ typedef void (^FIRApplyActionCodeCallback)(NSError *_Nullable error) NS_SWIFT_NAME(ApplyActionCodeCallback); /** - @brief Keys used to retrieve operation data from a @c FIRActionCodeInfo object by the - @c dataForKey method. + @brief Keys used to retrieve operation data from a `FIRActionCodeInfo` object by the + `dataForKey` method. */ typedef NS_ENUM(NSInteger, FIRActionDataKey) { /** @@ -239,7 +239,7 @@ NS_SWIFT_NAME(Auth) + (FIRAuth *)auth NS_SWIFT_NAME(auth()); /** @fn authWithApp: - @brief Gets the auth object for a @c FIRApp. + @brief Gets the auth object for a `FIRApp`. @param app The FIRApp for which to retrieve the associated FIRAuth instance. @return The FIRAuth instance associated with the given FIRApp. @@ -247,7 +247,7 @@ NS_SWIFT_NAME(Auth) + (FIRAuth *)authWithApp:(FIRApp *)app NS_SWIFT_NAME(auth(app:)); /** @property app - @brief Gets the @c FIRApp object that this auth object is connected to. + @brief Gets the `FIRApp` object that this auth object is connected to. */ @property(nonatomic, weak, readonly, nullable) FIRApp *app; @@ -256,9 +256,9 @@ NS_SWIFT_NAME(Auth) */ @property(nonatomic, strong, readonly, nullable) FIRUser *currentUser; -/** @proprty languageCode +/** @property languageCode @brief The current user language code. This property can be set to the app's current language by - calling @c useAppLanguage. + calling `useAppLanguage`. @remarks The string used to set this property must be a language code that follows BCP 47. */ @@ -269,13 +269,13 @@ NS_SWIFT_NAME(Auth) @brief The APNs token used for phone number authentication. The type of the token (production or sandbox) will be attempted to be automatcially detected. @remarks If swizzling is disabled, the APNs Token must be set for phone number auth to work, - by either setting this property or by calling @c setAPNSToken:type: + by either setting this property or by calling `setAPNSToken:type:` */ @property(nonatomic, strong, nullable) NSData *APNSToken; #endif /** @fn init - @brief Please access auth instances using @c FIRAuth.auth and @c FIRAuth.authForApp:. + @brief Please access auth instances using `FIRAuth.auth` and `FIRAuth.authForApp:`. */ - (instancetype)init NS_UNAVAILABLE; @@ -289,11 +289,10 @@ NS_SWIFT_NAME(Auth) main thread in the future. @remarks Possible error codes: -
    -
  • @c FIRAuthErrorCodeInvalidEmail - Indicates the email address is malformed.
  • -
- @remarks See @c FIRAuthErrors for a list of error codes that are common to all API methods. + + `FIRAuthErrorCodeInvalidEmail` - Indicates the email address is malformed. + + @remarks See `FIRAuthErrors` for a list of error codes that are common to all API methods. */ - (void)fetchProvidersForEmail:(NSString *)email completion:(nullable FIRProviderQueryCallback)completion; @@ -308,21 +307,16 @@ NS_SWIFT_NAME(Auth) @remarks Possible error codes: -
    -
  • @c FIRAuthErrorCodeOperationNotAllowed - Indicates that email and password + + `FIRAuthErrorCodeOperationNotAllowed` - Indicates that email and password accounts are not enabled. Enable them in the Auth section of the Firebase console. -
  • -
  • @c FIRAuthErrorCodeUserDisabled - Indicates the user's account is disabled. -
  • -
  • @c FIRAuthErrorCodeWrongPassword - Indicates the user attempted + + `FIRAuthErrorCodeUserDisabled` - Indicates the user's account is disabled. + + `FIRAuthErrorCodeWrongPassword` - Indicates the user attempted sign in with an incorrect password. -
  • -
  • @c FIRAuthErrorCodeInvalidEmail - Indicates the email address is malformed. -
  • -
+ + `FIRAuthErrorCodeInvalidEmail` - Indicates the email address is malformed. + - @remarks See @c FIRAuthErrors for a list of error codes that are common to all API methods. + @remarks See `FIRAuthErrors` for a list of error codes that are common to all API methods. */ - (void)signInWithEmail:(NSString *)email password:(NSString *)password @@ -338,31 +332,28 @@ NS_SWIFT_NAME(Auth) @remarks Possible error codes: -
    -
  • @c FIRAuthErrorCodeOperationNotAllowed - Indicates that email and password + + `FIRAuthErrorCodeOperationNotAllowed` - Indicates that email and password accounts are not enabled. Enable them in the Auth section of the Firebase console. -
  • -
  • @c FIRAuthErrorCodeUserDisabled - Indicates the user's account is disabled. -
  • -
  • @c FIRAuthErrorCodeWrongPassword - Indicates the user attempted + + `FIRAuthErrorCodeUserDisabled` - Indicates the user's account is disabled. + + `FIRAuthErrorCodeWrongPassword` - Indicates the user attempted sign in with an incorrect password. -
  • -
  • @c FIRAuthErrorCodeInvalidEmail - Indicates the email address is malformed. -
  • -
+ + `FIRAuthErrorCodeInvalidEmail` - Indicates the email address is malformed. + + + + @remarks See `FIRAuthErrors` for a list of error codes that are common to all API methods. - @remarks See @c FIRAuthErrors for a list of error codes that are common to all API methods. @remarks This method will only exist until the next major Firebase release following 4.x.x. - After the next major release the method @c signInWithEmail:password:completion: will support - the @c FIRAuthDataResultCallback. + After the next major release the method `signInWithEmail:password:completion:` will support + the `FIRAuthDataResultCallback`. */ - (void)signInAndRetrieveDataWithEmail:(NSString *)email password:(NSString *)password completion:(nullable FIRAuthDataResultCallback)completion; /** @fn signInWithCredential:completion: - @brief Convenience method for @c signInAndRetrieveDataWithCredential:completion: This method + @brief Convenience method for `signInAndRetrieveDataWithCredential:completion:` This method doesn't return additional identity provider data. */ - (void)signInWithCredential:(FIRAuthCredential *)credential @@ -378,45 +369,35 @@ NS_SWIFT_NAME(Auth) canceled. Invoked asynchronously on the main thread in the future. @remarks Possible error codes: -
    -
  • @c FIRAuthErrorCodeInvalidCredential - Indicates the supplied credential is invalid. + + + `FIRAuthErrorCodeInvalidCredential` - Indicates the supplied credential is invalid. This could happen if it has expired or it is malformed. -
  • -
  • @c FIRAuthErrorCodeOperationNotAllowed - Indicates that accounts + + `FIRAuthErrorCodeOperationNotAllowed` - Indicates that accounts with the identity provider represented by the credential are not enabled. Enable them in the Auth section of the Firebase console. -
  • -
  • @c FIRAuthErrorCodeAccountExistsWithDifferentCredential - Indicates the email asserted + + `FIRAuthErrorCodeAccountExistsWithDifferentCredential` - Indicates the email asserted by the credential (e.g. the email in a Facebook access token) is already in use by an existing account, that cannot be authenticated with this sign-in method. Call fetchProvidersForEmail for this user’s email and then prompt them to sign in with any of the sign-in providers returned. This error will only be thrown if the "One account per email address" setting is enabled in the Firebase console, under Auth settings. -
  • -
  • @c FIRAuthErrorCodeUserDisabled - Indicates the user's account is disabled. -
  • -
  • @c FIRAuthErrorCodeWrongPassword - Indicates the user attempted sign in with an + + `FIRAuthErrorCodeUserDisabled` - Indicates the user's account is disabled. + + `FIRAuthErrorCodeWrongPassword` - Indicates the user attempted sign in with an incorrect password, if credential is of the type EmailPasswordAuthCredential. -
  • -
  • @c FIRAuthErrorCodeInvalidEmail - Indicates the email address is malformed. -
  • -
  • @c FIRAuthErrorCodeMissingVerificationID - Indicates that the phone auth credential was + + `FIRAuthErrorCodeInvalidEmail` - Indicates the email address is malformed. + + `FIRAuthErrorCodeMissingVerificationID` - Indicates that the phone auth credential was created with an empty verification ID. -
  • -
  • @c FIRAuthErrorCodeMissingVerificationCode - Indicates that the phone auth credential + + `FIRAuthErrorCodeMissingVerificationCode` - Indicates that the phone auth credential was created with an empty verification code. -
  • -
  • @c FIRAuthErrorCodeInvalidVerificationCode - Indicates that the phone auth credential + + `FIRAuthErrorCodeInvalidVerificationCode` - Indicates that the phone auth credential was created with an invalid verification Code. -
  • -
  • @c FIRAuthErrorCodeInvalidVerificationID - Indicates that the phone auth credential was + + `FIRAuthErrorCodeInvalidVerificationID` - Indicates that the phone auth credential was created with an invalid verification ID. -
  • -
  • @c FIRAuthErrorCodeSessionExpired - Indicates that the SMS code has expired. -
  • -
+ + `FIRAuthErrorCodeSessionExpired` - Indicates that the SMS code has expired. + - @remarks See @c FIRAuthErrors for a list of error codes that are common to all API methods. + + @remarks See `FIRAuthErrors` for a list of error codes that are common to all API methods. */ - (void)signInAndRetrieveDataWithCredential:(FIRAuthCredential *)credential completion:(nullable FIRAuthDataResultCallback)completion; @@ -430,13 +411,11 @@ NS_SWIFT_NAME(Auth) If there is any other existing user signed in, that user will be signed out. @remarks Possible error codes: -
    -
  • @c FIRAuthErrorCodeOperationNotAllowed - Indicates that anonymous accounts are + + + `FIRAuthErrorCodeOperationNotAllowed` - Indicates that anonymous accounts are not enabled. Enable them in the Auth section of the Firebase console. -
  • -
- @remarks See @c FIRAuthErrors for a list of error codes that are common to all API methods. + @remarks See `FIRAuthErrors` for a list of error codes that are common to all API methods. */ - (void)signInAnonymouslyWithCompletion:(nullable FIRAuthResultCallback)completion; @@ -449,16 +428,16 @@ NS_SWIFT_NAME(Auth) If there is any other existing user signed in, that user will be signed out. @remarks Possible error codes: -
    -
  • @c FIRAuthErrorCodeOperationNotAllowed - Indicates that anonymous accounts are + + + `FIRAuthErrorCodeOperationNotAllowed` - Indicates that anonymous accounts are not enabled. Enable them in the Auth section of the Firebase console. -
  • -
- @remarks See @c FIRAuthErrors for a list of error codes that are common to all API methods. + + @remarks See `FIRAuthErrors` for a list of error codes that are common to all API methods. + @remarks This method will only exist until the next major Firebase release following 4.x.x. - After the next major release the method @c signInAnonymouslyWithCompletion will support the - @c FIRAuthDataResultCallback. + After the next major release the method `signInAnonymouslyWithCompletion` will support the + `FIRAuthDataResultCallback`. */ - (void)signInAnonymouslyAndRetrieveDataWithCompletion: (nullable FIRAuthDataResultCallback)completion; @@ -471,16 +450,15 @@ NS_SWIFT_NAME(Auth) canceled. Invoked asynchronously on the main thread in the future. @remarks Possible error codes: -
    -
  • @c FIRAuthErrorCodeInvalidCustomToken - Indicates a validation error with + + + `FIRAuthErrorCodeInvalidCustomToken` - Indicates a validation error with the custom token. -
  • -
  • @c FIRAuthErrorCodeCustomTokenMismatch - Indicates the service account and the API key + + `FIRAuthErrorCodeCustomTokenMismatch` - Indicates the service account and the API key belong to different projects. -
  • -
- @remarks See @c FIRAuthErrors for a list of error codes that are common to all API methods. + + + @remarks See `FIRAuthErrors` for a list of error codes that are common to all API methods. */ - (void)signInWithCustomToken:(NSString *)token completion:(nullable FIRAuthResultCallback)completion; @@ -493,19 +471,20 @@ NS_SWIFT_NAME(Auth) canceled. Invoked asynchronously on the main thread in the future. @remarks Possible error codes: -
    -
  • @c FIRAuthErrorCodeInvalidCustomToken - Indicates a validation error with + + + `FIRAuthErrorCodeInvalidCustomToken` - Indicates a validation error with the custom token. -
  • -
  • @c FIRAuthErrorCodeCustomTokenMismatch - Indicates the service account and the API key + + + `FIRAuthErrorCodeCustomTokenMismatch` - Indicates the service account and the API key belong to different projects. -
  • -
- @remarks See @c FIRAuthErrors for a list of error codes that are common to all API methods. + + + @remarks See `FIRAuthErrors` for a list of error codes that are common to all API methods. + @remarks This method will only exist until the next major Firebase release following 4.x.x. - After the next major release the method @c createUserWithEmail:password:completion: will - support the @c FIRAuthDataResultCallback. + After the next major release the method `createUserWithEmail:password:completion:` will + support the `FIRAuthDataResultCallback`. */ - (void)signInAndRetrieveDataWithCustomToken:(NSString *)token completion:(nullable FIRAuthDataResultCallback)completion; @@ -520,23 +499,18 @@ NS_SWIFT_NAME(Auth) canceled. Invoked asynchronously on the main thread in the future. @remarks Possible error codes: -
    -
  • @c FIRAuthErrorCodeInvalidEmail - Indicates the email address is malformed. -
  • -
  • @c FIRAuthErrorCodeEmailAlreadyInUse - Indicates the email used to attempt sign up + + + `FIRAuthErrorCodeInvalidEmail` - Indicates the email address is malformed. + + `FIRAuthErrorCodeEmailAlreadyInUse` - Indicates the email used to attempt sign up already exists. Call fetchProvidersForEmail to check which sign-in mechanisms the user used, and prompt the user to sign in with one of those. -
  • -
  • @c FIRAuthErrorCodeOperationNotAllowed - Indicates that email and password accounts + + `FIRAuthErrorCodeOperationNotAllowed` - Indicates that email and password accounts are not enabled. Enable them in the Auth section of the Firebase console. -
  • -
  • @c FIRAuthErrorCodeWeakPassword - Indicates an attempt to set a password that is + + `FIRAuthErrorCodeWeakPassword` - Indicates an attempt to set a password that is considered too weak. The NSLocalizedFailureReasonErrorKey field in the NSError.userInfo dictionary object will contain more detailed explanation that can be shown to the user. -
  • -
- @remarks See @c FIRAuthErrors for a list of error codes that are common to all API methods. + @remarks See `FIRAuthErrors` for a list of error codes that are common to all API methods. */ - (void)createUserWithEmail:(NSString *)email password:(NSString *)password @@ -551,26 +525,22 @@ NS_SWIFT_NAME(Auth) canceled. Invoked asynchronously on the main thread in the future. @remarks Possible error codes: -
    -
  • @c FIRAuthErrorCodeInvalidEmail - Indicates the email address is malformed. -
  • -
  • @c FIRAuthErrorCodeEmailAlreadyInUse - Indicates the email used to attempt sign up + + + `FIRAuthErrorCodeInvalidEmail` - Indicates the email address is malformed. + + `FIRAuthErrorCodeEmailAlreadyInUse` - Indicates the email used to attempt sign up already exists. Call fetchProvidersForEmail to check which sign-in mechanisms the user used, and prompt the user to sign in with one of those. -
  • -
  • @c FIRAuthErrorCodeOperationNotAllowed - Indicates that email and password accounts + + `FIRAuthErrorCodeOperationNotAllowed` - Indicates that email and password accounts are not enabled. Enable them in the Auth section of the Firebase console. -
  • -
  • @c FIRAuthErrorCodeWeakPassword - Indicates an attempt to set a password that is + + `FIRAuthErrorCodeWeakPassword` - Indicates an attempt to set a password that is considered too weak. The NSLocalizedFailureReasonErrorKey field in the NSError.userInfo dictionary object will contain more detailed explanation that can be shown to the user. -
  • -
- @remarks See @c FIRAuthErrors for a list of error codes that are common to all API methods. + @remarks See `FIRAuthErrors` for a list of error codes that are common to all API methods. + @remarks This method will only exist until the next major Firebase release following 4.x.x. - After the next major release the method @c createUserWithEmail:password:completion: will - support the @c FIRAuthDataResultCallback. + After the next major release the method `createUserWithEmail:password:completion:` will + support the `FIRAuthDataResultCallback`. */ - (void)createUserAndRetrieveDataWithEmail:(NSString *)email password:(NSString *)password @@ -585,20 +555,15 @@ NS_SWIFT_NAME(Auth) asynchronously on the main thread in the future. @remarks Possible error codes: -
    -
  • @c FIRAuthErrorCodeWeakPassword - Indicates an attempt to set a password that is + + + `FIRAuthErrorCodeWeakPassword` - Indicates an attempt to set a password that is considered too weak. -
  • -
  • @c FIRAuthErrorCodeOperationNotAllowed - Indicates the administrator disabled sign + + `FIRAuthErrorCodeOperationNotAllowed` - Indicates the administrator disabled sign in with the specified identity provider. -
  • -
  • @c FIRAuthErrorCodeExpiredActionCode - Indicates the OOB code is expired. -
  • -
  • @c FIRAuthErrorCodeInvalidActionCode - Indicates the OOB code is invalid. -
  • -
+ + `FIRAuthErrorCodeExpiredActionCode` - Indicates the OOB code is expired. + + `FIRAuthErrorCodeInvalidActionCode` - Indicates the OOB code is invalid. - @remarks See @c FIRAuthErrors for a list of error codes that are common to all API methods. + @remarks See `FIRAuthErrors` for a list of error codes that are common to all API methods. */ - (void)confirmPasswordResetWithCode:(NSString *)code newPassword:(NSString *)newPassword @@ -644,17 +609,15 @@ NS_SWIFT_NAME(Auth) asynchronously on the main thread in the future. @remarks Possible error codes: -
    -
  • @c FIRAuthErrorCodeInvalidRecipientEmail - Indicates an invalid recipient email was + + + `FIRAuthErrorCodeInvalidRecipientEmail` - Indicates an invalid recipient email was sent in the request. -
  • -
  • @c FIRAuthErrorCodeInvalidSender - Indicates an invalid sender email is set in + + `FIRAuthErrorCodeInvalidSender` - Indicates an invalid sender email is set in the console for this action. -
  • -
  • @c FIRAuthErrorCodeInvalidMessagePayload - Indicates an invalid email template for + + `FIRAuthErrorCodeInvalidMessagePayload` - Indicates an invalid email template for sending update email. -
  • -
+ + */ - (void)sendPasswordResetWithEmail:(NSString *)email completion:(nullable FIRSendPasswordResetCallback)completion; @@ -663,35 +626,29 @@ NS_SWIFT_NAME(Auth) @brief Initiates a password reset for the given email address and @FIRActionCodeSettings object. @param email The email address of the user. - @param actionCodeSettings An @c FIRActionCodeSettings object containing settings related to + @param actionCodeSettings An `FIRActionCodeSettings` object containing settings related to handling action codes. @param completion Optionally; a block which is invoked when the request finishes. Invoked asynchronously on the main thread in the future. @remarks Possible error codes: -
    -
  • @c FIRAuthErrorCodeInvalidRecipientEmail - Indicates an invalid recipient email was + + + `FIRAuthErrorCodeInvalidRecipientEmail` - Indicates an invalid recipient email was sent in the request. -
  • -
  • @c FIRAuthErrorCodeInvalidSender - Indicates an invalid sender email is set in + + `FIRAuthErrorCodeInvalidSender` - Indicates an invalid sender email is set in the console for this action. -
  • -
  • @c FIRAuthErrorCodeInvalidMessagePayload - Indicates an invalid email template for + + `FIRAuthErrorCodeInvalidMessagePayload` - Indicates an invalid email template for sending update email. -
  • -
  • @c FIRAuthErrorCodeMissingIosBundleID - Indicates that the iOS bundle ID is missing when - @c handleCodeInApp is set to YES. -
  • -
  • @c FIRAuthErrorCodeMissingAndroidPackageName - Indicates that the android package name - is missing when the @c androidInstallApp flag is set to true. -
  • -
  • @c FIRAuthErrorCodeUnauthorizedDomain - Indicates that the domain specified in the + + `FIRAuthErrorCodeMissingIosBundleID` - Indicates that the iOS bundle ID is missing when + `handleCodeInApp` is set to YES. + + `FIRAuthErrorCodeMissingAndroidPackageName` - Indicates that the android package name + is missing when the `androidInstallApp` flag is set to true. + + `FIRAuthErrorCodeUnauthorizedDomain` - Indicates that the domain specified in the continue URL is not whitelisted in the Firebase console. -
  • -
  • @c FIRAuthErrorCodeInvalidContinueURI - Indicates that the domain specified in the + + `FIRAuthErrorCodeInvalidContinueURI` - Indicates that the domain specified in the continue URI is not valid. -
  • -
+ + */ - (void)sendPasswordResetWithEmail:(NSString *)email actionCodeSettings:(FIRActionCodeSettings *)actionCodeSettings @@ -705,12 +662,12 @@ NS_SWIFT_NAME(Auth) @return @YES when the sign out request was successful. @NO otherwise. @remarks Possible error codes: -
    -
  • @c FIRAuthErrorCodeKeychainError - Indicates an error occurred when accessing the - keychain. The @c NSLocalizedFailureReasonErrorKey field in the @c NSError.userInfo + + + `FIRAuthErrorCodeKeychainError` - Indicates an error occurred when accessing the + keychain. The `NSLocalizedFailureReasonErrorKey` field in the `NSError.userInfo` dictionary will contain more information about the error encountered. -
  • -
+ + */ - (BOOL)signOut:(NSError *_Nullable *_Nullable)error; @@ -728,8 +685,8 @@ NS_SWIFT_NAME(Auth) @remarks The block is invoked immediately after adding it according to it's standard invocation semantics, asynchronously on the main thread. Users should pay special attention to making sure the block does not inadvertently retain objects which should not be retained by - the long-lived block. The block itself will be retained by @c FIRAuth until it is - unregistered or until the @c FIRAuth instance is otherwise deallocated. + the long-lived block. The block itself will be retained by `FIRAuth` until it is + unregistered or until the `FIRAuth` instance is otherwise deallocated. @return A handle useful for manually unregistering the block as a listener. */ @@ -757,8 +714,8 @@ NS_SWIFT_NAME(Auth) @remarks The block is invoked immediately after adding it according to it's standard invocation semantics, asynchronously on the main thread. Users should pay special attention to making sure the block does not inadvertently retain objects which should not be retained by - the long-lived block. The block itself will be retained by @c FIRAuth until it is - unregistered or until the @c FIRAuth instance is otherwise deallocated. + the long-lived block. The block itself will be retained by `FIRAuth` until it is + unregistered or until the `FIRAuth` instance is otherwise deallocated. @return A handle useful for manually unregistering the block as a listener. */ @@ -773,14 +730,14 @@ NS_SWIFT_NAME(Auth) - (void)removeIDTokenDidChangeListener:(FIRIDTokenDidChangeListenerHandle)listenerHandle; /** @fn useAppLanguage - @brief Sets @c languageCode to the app's current language. + @brief Sets `languageCode` to the app's current language. */ - (void)useAppLanguage; #if TARGET_OS_IOS /** @fn canHandleURL: - @brief Whether the specific URL is handled by @c FIRAuth . + @brief Whether the specific URL is handled by `FIRAuth` . @param URL The URL received by the application delegate from any of the openURL method. @return Whether or the URL is handled. YES means the URL is for Firebase Auth so the caller should ignore the URL from further processing, and NO means the @@ -794,12 +751,12 @@ NS_SWIFT_NAME(Auth) /** @fn setAPNSToken:type: @brief Sets the APNs token along with its type. @remarks If swizzling is disabled, the APNs Token must be set for phone number auth to work, - by either setting calling this method or by setting the @c APNSToken property. + by either setting calling this method or by setting the `APNSToken` property. */ - (void)setAPNSToken:(NSData *)token type:(FIRAuthAPNSTokenType)type; /** @fn canHandleNotification: - @brief Whether the specific remote notification is handled by @c FIRAuth . + @brief Whether the specific remote notification is handled by `FIRAuth` . @param userInfo A dictionary that contains information related to the notification in question. @return Whether or the notification is handled. YES means the notification is for Firebase Auth diff --git a/Firebase/Auth/Source/Public/FIRAuthDataResult.h b/Firebase/Auth/Source/Public/FIRAuthDataResult.h index ba16576..bc4fa4a 100644 --- a/Firebase/Auth/Source/Public/FIRAuthDataResult.h +++ b/Firebase/Auth/Source/Public/FIRAuthDataResult.h @@ -29,8 +29,8 @@ NS_SWIFT_NAME(AuthDataResult) @interface FIRAuthDataResult : NSObject /** @fn init - @brief This class should not be initialized manually. @c FIRAuthDataResult instance is - returned as part of @c FIRAuthDataResultCallback . + @brief This class should not be initialized manually. `FIRAuthDataResult` instance is + returned as part of `FIRAuthDataResultCallback`. */ - (instancetype)init NS_UNAVAILABLE; diff --git a/Firebase/Auth/Source/Public/FIRAuthErrors.h b/Firebase/Auth/Source/Public/FIRAuthErrors.h index fdfee19..b8e5fb6 100644 --- a/Firebase/Auth/Source/Public/FIRAuthErrors.h +++ b/Firebase/Auth/Source/Public/FIRAuthErrors.h @@ -18,21 +18,21 @@ /** @class FIRAuthErrors @remarks Error Codes common to all API Methods: -
    -
  • @c FIRAuthErrorCodeNetworkError
  • -
  • @c FIRAuthErrorCodeUserNotFound
  • -
  • @c FIRAuthErrorCodeUserTokenExpired
  • -
  • @c FIRAuthErrorCodeTooManyRequests
  • -
  • @c FIRAuthErrorCodeInvalidAPIKey
  • -
  • @c FIRAuthErrorCodeAppNotAuthorized
  • -
  • @c FIRAuthErrorCodeKeychainError
  • -
  • @c FIRAuthErrorCodeInternalError
  • -
- @remarks Common error codes for @c FIRUser operations: -
    -
  • @c FIRAuthErrorCodeInvalidUserToken
  • -
  • @c FIRAuthErrorCodeUserDisabled
  • -
+ + + `FIRAuthErrorCodeNetworkError` + + `FIRAuthErrorCodeUserNotFound` + + `FIRAuthErrorCodeUserTokenExpired` + + `FIRAuthErrorCodeTooManyRequests` + + `FIRAuthErrorCodeInvalidAPIKey` + + `FIRAuthErrorCodeAppNotAuthorized` + + `FIRAuthErrorCodeKeychainError` + + `FIRAuthErrorCodeInternalError` + + @remarks Common error codes for `FIRUser` operations: + + + `FIRAuthErrorCodeInvalidUserToken` + + `FIRAuthErrorCodeUserDisabled` + */ NS_SWIFT_NAME(AuthErrors) @interface FIRAuthErrors @@ -54,8 +54,8 @@ extern NSString *const FIRAuthUpdatedCredentialKey NS_SWIFT_NAME(AuthUpdatedCred extern NSString *const FIRAuthErrorNameKey NS_SWIFT_NAME(AuthErrorNameKey); /** - @brief Errors with the code @c FIRAuthErrorCodeAccountExistsWithDifferentCredential may contain - an @c NSError.userInfo dictinary object which contains this key. The value associated with + @brief Errors with the code `FIRAuthErrorCodeAccountExistsWithDifferentCredential` may contain + an `NSError.userInfo` dictinary object which contains this key. The value associated with this key is an NSString of the email address of the account that already exists. */ extern NSString *const FIRAuthErrorUserInfoEmailKey NS_SWIFT_NAME(AuthErrorUserInfoEmailKey); @@ -127,7 +127,7 @@ typedef NS_ENUM(NSInteger, FIRAuthErrorCode) { /** Indicates a network error occurred (such as a timeout, interrupted connection, or unreachable host). These types of errors are often recoverable with a retry. The - @c NSUnderlyingError field in the @c NSError.userInfo dictionary will contain the error + `NSUnderlyingError` field in the `NSError.userInfo` dictionary will contain the error encountered. */ FIRAuthErrorCodeNetworkError = 17020, @@ -192,7 +192,7 @@ typedef NS_ENUM(NSInteger, FIRAuthErrorCode) { */ FIRAuthErrorCodeMissingIosBundleID = 17036, - /** Indicates that the android package name is missing when the @c androidInstallApp flag is set + /** Indicates that the android package name is missing when the `androidInstallApp` flag is set to true. */ FIRAuthErrorCodeMissingAndroidPackageName = 17037, @@ -212,12 +212,12 @@ typedef NS_ENUM(NSInteger, FIRAuthErrorCode) { FIRAuthErrorCodeMissingContinueURI = 17040, /** Indicates that a phone number was not provided in a call to - @c verifyPhoneNumber:completion:. + `verifyPhoneNumber:completion:`. */ FIRAuthErrorCodeMissingPhoneNumber = 17041, /** Indicates that an invalid phone number was provided in a call to - @c verifyPhoneNumber:completion:. + `verifyPhoneNumber:completion:`. */ FIRAuthErrorCodeInvalidPhoneNumber = 17042, @@ -295,7 +295,7 @@ typedef NS_ENUM(NSInteger, FIRAuthErrorCode) { */ FIRAuthErrorCodeWebNetworkRequestFailed = 17061, - /** Indicates that an internal error occured within a SFSafariViewController or UIWebview. + /** Indicates that an internal error occurred within a SFSafariViewController or UIWebview. */ FIRAuthErrorCodeWebInternalError = 17062, diff --git a/Firebase/Auth/Source/Public/FIREmailAuthProvider.h b/Firebase/Auth/Source/Public/FIREmailAuthProvider.h index 030efda..0108d40 100644 --- a/Firebase/Auth/Source/Public/FIREmailAuthProvider.h +++ b/Firebase/Auth/Source/Public/FIREmailAuthProvider.h @@ -26,24 +26,24 @@ NS_ASSUME_NONNULL_BEGIN extern NSString *const FIREmailAuthProviderID NS_SWIFT_NAME(EmailAuthProviderID); /** - @brief please use @c FIREmailAuthProviderID instead. + @brief please use `FIREmailAuthProviderID` instead. */ extern NSString *const FIREmailPasswordAuthProviderID __attribute__((deprecated)); /** @class FIREmailAuthProvider - @brief A concrete implementation of @c FIRAuthProvider for Email & Password Sign In. + @brief A concrete implementation of `FIRAuthProvider` for Email & Password Sign In. */ NS_SWIFT_NAME(EmailAuthProvider) @interface FIREmailAuthProvider : NSObject /** @typedef FIREmailPasswordAuthProvider - @brief Please use @c FIREmailAuthProvider instead. + @brief Please use `FIREmailAuthProvider` instead. */ typedef FIREmailAuthProvider FIREmailPasswordAuthProvider __attribute__((deprecated)); /** @fn credentialWithEmail:password: - @brief Creates an @c FIRAuthCredential for an email & password sign in. + @brief Creates an `FIRAuthCredential` for an email & password sign in. @param email The user's email address. @param password The user's password. diff --git a/Firebase/Auth/Source/Public/FIRFacebookAuthProvider.h b/Firebase/Auth/Source/Public/FIRFacebookAuthProvider.h index dae90dc..f08740f 100644 --- a/Firebase/Auth/Source/Public/FIRFacebookAuthProvider.h +++ b/Firebase/Auth/Source/Public/FIRFacebookAuthProvider.h @@ -32,7 +32,7 @@ NS_SWIFT_NAME(FacebookAuthProvider) @interface FIRFacebookAuthProvider : NSObject /** @fn credentialWithAccessToken: - @brief Creates an @c FIRAuthCredential for a Facebook sign in. + @brief Creates an `FIRAuthCredential` for a Facebook sign in. @param accessToken The Access Token from Facebook. @return A FIRAuthCredential containing the Facebook credentials. diff --git a/Firebase/Auth/Source/Public/FIRGitHubAuthProvider.h b/Firebase/Auth/Source/Public/FIRGitHubAuthProvider.h index 0da3142..f0b5dbe 100644 --- a/Firebase/Auth/Source/Public/FIRGitHubAuthProvider.h +++ b/Firebase/Auth/Source/Public/FIRGitHubAuthProvider.h @@ -32,7 +32,7 @@ NS_SWIFT_NAME(GitHubAuthProvider) @interface FIRGitHubAuthProvider : NSObject /** @fn credentialWithToken: - @brief Creates an @c FIRAuthCredential for a GitHub sign in. + @brief Creates an `FIRAuthCredential` for a GitHub sign in. @param token The GitHub OAuth access token. @return A FIRAuthCredential containing the GitHub credential. diff --git a/Firebase/Auth/Source/Public/FIRGoogleAuthProvider.h b/Firebase/Auth/Source/Public/FIRGoogleAuthProvider.h index 1386c04..e80d87e 100644 --- a/Firebase/Auth/Source/Public/FIRGoogleAuthProvider.h +++ b/Firebase/Auth/Source/Public/FIRGoogleAuthProvider.h @@ -32,7 +32,7 @@ NS_SWIFT_NAME(GoogleAuthProvider) @interface FIRGoogleAuthProvider : NSObject /** @fn credentialWithIDToken:accessToken: - @brief Creates an @c FIRAuthCredential for a Google sign in. + @brief Creates an `FIRAuthCredential` for a Google sign in. @param IDToken The ID Token from Google. @param accessToken The Access Token from Google. diff --git a/Firebase/Auth/Source/Public/FIROAuthProvider.h b/Firebase/Auth/Source/Public/FIROAuthProvider.h index b20d9b6..cc628f8 100644 --- a/Firebase/Auth/Source/Public/FIROAuthProvider.h +++ b/Firebase/Auth/Source/Public/FIROAuthProvider.h @@ -21,13 +21,13 @@ NS_ASSUME_NONNULL_BEGIN /** @class FIROAuthProvider - @brief A concrete implementation of @c FIRAuthProvider for generic OAuth Providers. + @brief A concrete implementation of `FIRAuthProvider` for generic OAuth Providers. */ NS_SWIFT_NAME(OAuthProvider) @interface FIROAuthProvider : NSObject /** @fn credentialWithProviderID:IDToken:accessToken: - @brief Creates an @c FIRAuthCredential for that OAuth 2 provider identified by providerID, ID + @brief Creates an `FIRAuthCredential` for that OAuth 2 provider identified by providerID, ID token and access token. @param providerID The provider ID associated with the Auth credential being created. @@ -42,7 +42,7 @@ NS_SWIFT_NAME(OAuthProvider) /** @fn credentialWithProviderID:accessToken: - @brief Creates an @c FIRAuthCredential for that OAuth 2 provider identified by providerID using + @brief Creates an `FIRAuthCredential` for that OAuth 2 provider identified by providerID using an ID token. @param providerID The provider ID associated with the Auth credential being created. diff --git a/Firebase/Auth/Source/Public/FIRPhoneAuthProvider.h b/Firebase/Auth/Source/Public/FIRPhoneAuthProvider.h index 2d6d698..34db683 100644 --- a/Firebase/Auth/Source/Public/FIRPhoneAuthProvider.h +++ b/Firebase/Auth/Source/Public/FIRPhoneAuthProvider.h @@ -38,47 +38,44 @@ typedef void (^FIRVerificationResultCallback)(NSString *_Nullable verificationID NS_SWIFT_NAME(VerificationResultCallback); /** @class FIRPhoneAuthProvider - @brief A concrete implementation of @c FIRAuthProvider for phone auth providers. + @brief A concrete implementation of `FIRAuthProvider` for phone auth providers. */ NS_SWIFT_NAME(PhoneAuthProvider) @interface FIRPhoneAuthProvider : NSObject /** @fn provider - @brief Returns an instance of @c FIRPhoneAuthProvider for the default @c FIRAuth object. + @brief Returns an instance of `FIRPhoneAuthProvider` for the default `FIRAuth` object. */ + (instancetype)provider NS_SWIFT_NAME(provider()); /** @fn providerWithAuth: - @brief Returns an instance of @c FIRPhoneAuthProvider for the provided @c FIRAuth object. + @brief Returns an instance of `FIRPhoneAuthProvider` for the provided `FIRAuth` object. @param auth The auth object to associate with the phone auth provider instance. */ + (instancetype)providerWithAuth:(FIRAuth *)auth NS_SWIFT_NAME(provider(auth:)); /** @fn verifyPhoneNumber:completion: - @brief Please use @c verifyPhoneNumber:UIDelegate:completion: instead. + @brief Please use `verifyPhoneNumber:UIDelegate:completion:` instead. @param phoneNumber The phone number to be verified. @param completion The callback to be invoked when the verification flow is finished. @remarks Possible error codes: -
    -
  • @c FIRAuthErrorCodeAppNotVerified - Indicates that Firebase could not retrieve the - silent push notification and therefore could not verify your app.
  • -
  • @c FIRAuthErrorCodeInvalidAppCredential - Indicates that The APNs device token provided + + + `FIRAuthErrorCodeAppNotVerified` - Indicates that Firebase could not retrieve the + silent push notification and therefore could not verify your app. + + `FIRAuthErrorCodeInvalidAppCredential` - Indicates that The APNs device token provided is either incorrect or does not match the private certificate uploaded to the Firebase - Console.
  • -
  • @c FIRAuthErrorCodeQuotaExceeded - Indicates that the phone verification quota for this - project has been exceeded.
  • -
  • @c FIRAuthErrorCodeInvalidPhoneNumber - Indicates that the phone number provided is - invalid.
  • -
  • @c FIRAuthErrorCodeMissingPhoneNumber - Indicates that a phone number was not provided. -
  • -
  • @c FIRAuthErrorCodeMissingAppToken - Indicates that the APNs device token could not be + Console. + + `FIRAuthErrorCodeQuotaExceeded` - Indicates that the phone verification quota for this + project has been exceeded. + + `FIRAuthErrorCodeInvalidPhoneNumber` - Indicates that the phone number provided is + invalid. + + `FIRAuthErrorCodeMissingPhoneNumber` - Indicates that a phone number was not provided. + + `FIRAuthErrorCodeMissingAppToken` - Indicates that the APNs device token could not be obtained. The app may not have set up remote notification correctly, or may fail to forward the APNs device token to FIRAuth if app delegate swizzling is disabled. -
  • -
*/ - (void)verifyPhoneNumber:(NSString *)phoneNumber completion:(nullable FIRVerificationResultCallback)completion @@ -92,23 +89,21 @@ NS_SWIFT_NAME(PhoneAuthProvider) by this method until the completion block is executed. @param completion The callback to be invoked when the verification flow is finished. @remarks Possible error codes: -
    -
  • @c FIRAuthErrorCodeCaptchaCheckFailed - Indicates that the reCAPTCHA token obtained by - the Firebase Auth is invalid or has expired.
  • -
  • @c FIRAuthErrorCodeQuotaExceeded - Indicates that the phone verification quota for this - project has been exceeded.
  • -
  • @c FIRAuthErrorCodeInvalidPhoneNumber - Indicates that the phone number provided is - invalid.
  • -
  • @c FIRAuthErrorCodeMissingPhoneNumber - Indicates that a phone number was not provided. -
  • -
+ + + `FIRAuthErrorCodeCaptchaCheckFailed` - Indicates that the reCAPTCHA token obtained by + the Firebase Auth is invalid or has expired. + + `FIRAuthErrorCodeQuotaExceeded` - Indicates that the phone verification quota for this + project has been exceeded. + + `FIRAuthErrorCodeInvalidPhoneNumber` - Indicates that the phone number provided is + invalid. + + `FIRAuthErrorCodeMissingPhoneNumber` - Indicates that a phone number was not provided. */ - (void)verifyPhoneNumber:(NSString *)phoneNumber UIDelegate:(nullable id)UIDelegate completion:(nullable FIRVerificationResultCallback)completion; /** @fn credentialWithVerificationID:verificationCode: - @brief Creates an @c FIRAuthCredential for the phone number provider identified by the + @brief Creates an `FIRAuthCredential` for the phone number provider identified by the verification ID and verification code. @param verificationID The verification ID obtained from invoking @@ -121,8 +116,8 @@ NS_SWIFT_NAME(PhoneAuthProvider) verificationCode:(NSString *)verificationCode; /** @fn init - @brief Please use the @c provider or @c providerWithAuth: methods to obtain an instance of - @c FIRPhoneAuthProvider. + @brief Please use the `provider` or `providerWithAuth:` methods to obtain an instance of + `FIRPhoneAuthProvider`. */ - (instancetype)init NS_UNAVAILABLE; diff --git a/Firebase/Auth/Source/Public/FIRTwitterAuthProvider.h b/Firebase/Auth/Source/Public/FIRTwitterAuthProvider.h index 4200753..2ef32f7 100644 --- a/Firebase/Auth/Source/Public/FIRTwitterAuthProvider.h +++ b/Firebase/Auth/Source/Public/FIRTwitterAuthProvider.h @@ -32,7 +32,7 @@ NS_SWIFT_NAME(TwitterAuthProvider) @interface FIRTwitterAuthProvider : NSObject /** @fn credentialWithToken:secret: - @brief Creates an @c FIRAuthCredential for a Twitter sign in. + @brief Creates an `FIRAuthCredential` for a Twitter sign in. @param token The Twitter OAuth token. @param secret The Twitter OAuth secret. diff --git a/Firebase/Auth/Source/Public/FIRUser.h b/Firebase/Auth/Source/Public/FIRUser.h index 7e22329..1bba710 100644 --- a/Firebase/Auth/Source/Public/FIRUser.h +++ b/Firebase/Auth/Source/Public/FIRUser.h @@ -34,7 +34,7 @@ NS_ASSUME_NONNULL_BEGIN @param token Optionally; an access token if the request was successful. @param error Optionally; the error which occurred - or nil if the request was successful. - @remarks One of: @c token or @c error will always be non-nil. + @remarks One of: `token` or `error` will always be non-nil. */ typedef void (^FIRAuthTokenCallback)(NSString *_Nullable token, NSError *_Nullable error) NS_SWIFT_NAME(AuthTokenCallback); @@ -91,8 +91,8 @@ NS_SWIFT_NAME(User) /** @fn init @brief This class should not be instantiated. - @remarks To retrieve the current user, use @c FIRAuth.currentUser. To sign a user - in or out, use the methods on @c FIRAuth. + @remarks To retrieve the current user, use `FIRAuth.currentUser`. To sign a user + in or out, use the methods on `FIRAuth`. */ - (instancetype)init NS_UNAVAILABLE; @@ -107,29 +107,22 @@ NS_SWIFT_NAME(User) Invoked asynchronously on the main thread in the future. @remarks Possible error codes: -
    -
  • @c FIRAuthErrorCodeInvalidRecipientEmail - Indicates an invalid recipient email was + + + `FIRAuthErrorCodeInvalidRecipientEmail` - Indicates an invalid recipient email was sent in the request. -
  • -
  • @c FIRAuthErrorCodeInvalidSender - Indicates an invalid sender email is set in + + `FIRAuthErrorCodeInvalidSender` - Indicates an invalid sender email is set in the console for this action. -
  • -
  • @c FIRAuthErrorCodeInvalidMessagePayload - Indicates an invalid email template for + + `FIRAuthErrorCodeInvalidMessagePayload` - Indicates an invalid email template for sending update email. -
  • -
  • @c FIRAuthErrorCodeEmailAlreadyInUse - Indicates the email is already in use by another + + `FIRAuthErrorCodeEmailAlreadyInUse` - Indicates the email is already in use by another account. -
  • -
  • @c FIRAuthErrorCodeInvalidEmail - Indicates the email address is malformed. -
  • -
  • @c FIRAuthErrorCodeRequiresRecentLogin - Updating a user’s email is a security + + `FIRAuthErrorCodeInvalidEmail` - Indicates the email address is malformed. + + `FIRAuthErrorCodeRequiresRecentLogin` - Updating a user’s email is a security sensitive operation that requires a recent login from the user. This error indicates the user has not signed in recently enough. To resolve, reauthenticate the user by invoking reauthenticateWithCredential:completion: on FIRUser. -
  • -
- @remarks See @c FIRAuthErrors for a list of error codes that are common to all FIRUser methods. + @remarks See `FIRAuthErrors` for a list of error codes that are common to all FIRUser methods. */ - (void)updateEmail:(NSString *)email completion:(nullable FIRUserProfileChangeCallback)completion NS_SWIFT_NAME(updateEmail(to:completion:)); @@ -142,22 +135,18 @@ NS_SWIFT_NAME(User) Invoked asynchronously on the main thread in the future. @remarks Possible error codes: -
    -
  • @c FIRAuthErrorCodeOperationNotAllowed - Indicates the administrator disabled + + + `FIRAuthErrorCodeOperationNotAllowed` - Indicates the administrator disabled sign in with the specified identity provider. -
  • -
  • @c FIRAuthErrorCodeRequiresRecentLogin - Updating a user’s password is a security + + `FIRAuthErrorCodeRequiresRecentLogin` - Updating a user’s password is a security sensitive operation that requires a recent login from the user. This error indicates the user has not signed in recently enough. To resolve, reauthenticate the user by invoking reauthenticateWithCredential:completion: on FIRUser. -
  • -
  • @c FIRAuthErrorCodeWeakPassword - Indicates an attempt to set a password that is + + `FIRAuthErrorCodeWeakPassword` - Indicates an attempt to set a password that is considered too weak. The NSLocalizedFailureReasonErrorKey field in the NSError.userInfo dictionary object will contain more detailed explanation that can be shown to the user. -
  • -
- @remarks See @c FIRAuthErrors for a list of error codes that are common to all FIRUser methods. + @remarks See `FIRAuthErrors` for a list of error codes that are common to all FIRUser methods. */ - (void)updatePassword:(NSString *)password completion:(nullable FIRUserProfileChangeCallback)completion @@ -175,15 +164,13 @@ NS_SWIFT_NAME(User) Invoked asynchronously on the main thread in the future. @remarks Possible error codes: -
    -
  • @c FIRAuthErrorCodeRequiresRecentLogin - Updating a user’s phone number is a security + + + `FIRAuthErrorCodeRequiresRecentLogin` - Updating a user’s phone number is a security sensitive operation that requires a recent login from the user. This error indicates the user has not signed in recently enough. To resolve, reauthenticate the user by invoking reauthenticateWithCredential:completion: on FIRUser. -
  • -
- @remarks See @c FIRAuthErrors for a list of error codes that are common to all FIRUser methods. + @remarks See `FIRAuthErrors` for a list of error codes that are common to all FIRUser methods. */ - (void)updatePhoneNumberCredential:(FIRPhoneAuthCredential *)phoneNumberCredential completion:(nullable FIRUserProfileChangeCallback)completion; @@ -193,7 +180,7 @@ NS_SWIFT_NAME(User) @brief Creates an object which may be used to change the user's profile data. @remarks Set the properties of the returned object, then call - @c FIRUserProfileChangeRequest.commitChangesWithCallback: to perform the updates atomically. + `FIRUserProfileChangeRequest.commitChangesWithCallback:` to perform the updates atomically. @return An object which may be used to change the user's profile data atomically. */ @@ -205,16 +192,16 @@ NS_SWIFT_NAME(User) @param completion Optionally; the block invoked when the reload has finished. Invoked asynchronously on the main thread in the future. - @remarks May fail with a @c FIRAuthErrorCodeRequiresRecentLogin error code. In this case - you should call @c FIRUser.reauthenticateWithCredential:completion: before re-invoking - @c FIRUser.updateEmail:completion:. + @remarks May fail with a `FIRAuthErrorCodeRequiresRecentLogin` error code. In this case + you should call `FIRUser.reauthenticateWithCredential:completion:` before re-invoking + `FIRUser.updateEmail:completion:`. - @remarks See @c FIRAuthErrors for a list of error codes that are common to all API methods. + @remarks See `FIRAuthErrors` for a list of error codes that are common to all API methods. */ - (void)reloadWithCompletion:(nullable FIRUserProfileChangeCallback)completion; /** @fn reauthenticateWithCredential:completion: - @brief Convenience method for @c reauthenticateAndRetrieveDataWithCredential:completion: This + @brief Convenience method for `reauthenticateAndRetrieveDataWithCredential:completion:` This method doesn't return additional identity provider data. */ - (void)reauthenticateWithCredential:(FIRAuthCredential *)credential @@ -234,33 +221,27 @@ NS_SWIFT_NAME(User) user remains signed in. @remarks Possible error codes: -
    -
  • @c FIRAuthErrorCodeInvalidCredential - Indicates the supplied credential is invalid. + + + `FIRAuthErrorCodeInvalidCredential` - Indicates the supplied credential is invalid. This could happen if it has expired or it is malformed. -
  • -
  • @c FIRAuthErrorCodeOperationNotAllowed - Indicates that accounts with the + + `FIRAuthErrorCodeOperationNotAllowed` - Indicates that accounts with the identity provider represented by the credential are not enabled. Enable them in the Auth section of the Firebase console. -
  • -
  • @c FIRAuthErrorCodeEmailAlreadyInUse - Indicates the email asserted by the credential + + `FIRAuthErrorCodeEmailAlreadyInUse` - Indicates the email asserted by the credential (e.g. the email in a Facebook access token) is already in use by an existing account, that cannot be authenticated with this method. Call fetchProvidersForEmail for this user’s email and then prompt them to sign in with any of the sign-in providers returned. This error will only be thrown if the "One account per email address" setting is enabled in the Firebase console, under Auth settings. Please note that the error code raised in this specific situation may not be the same on Web and Android. -
  • -
  • @c FIRAuthErrorCodeUserDisabled - Indicates the user's account is disabled. -
  • -
  • @c FIRAuthErrorCodeWrongPassword - Indicates the user attempted reauthentication with + + `FIRAuthErrorCodeUserDisabled` - Indicates the user's account is disabled. + + `FIRAuthErrorCodeWrongPassword` - Indicates the user attempted reauthentication with an incorrect password, if credential is of the type EmailPasswordAuthCredential. -
  • -
  • @c FIRAuthErrorCodeUserMismatch - Indicates that an attempt was made to + + `FIRAuthErrorCodeUserMismatch` - Indicates that an attempt was made to reauthenticate with a user which is not the current user. -
  • -
  • @c FIRAuthErrorCodeInvalidEmail - Indicates the email address is malformed.
  • -
- @remarks See @c FIRAuthErrors for a list of error codes that are common to all API methods. + + `FIRAuthErrorCodeInvalidEmail` - Indicates the email address is malformed. + + @remarks See `FIRAuthErrors` for a list of error codes that are common to all API methods. */ - (void)reauthenticateAndRetrieveDataWithCredential:(FIRAuthCredential *) credential completion:(nullable FIRAuthDataResultCallback) completion; @@ -271,18 +252,18 @@ NS_SWIFT_NAME(User) @param completion Optionally; the block invoked when the token is available. Invoked asynchronously on the main thread in the future. - @remarks See @c FIRAuthErrors for a list of error codes that are common to all API methods. + @remarks See `FIRAuthErrors` for a list of error codes that are common to all API methods. */ - (void)getIDTokenWithCompletion:(nullable FIRAuthTokenCallback)completion NS_SWIFT_NAME(getIDToken(completion:)); /** @fn getTokenWithCompletion: - @brief Please use @c getIDTokenWithCompletion: instead. + @brief Please use `getIDTokenWithCompletion:` instead. @param completion Optionally; the block invoked when the token is available. Invoked asynchronously on the main thread in the future. - @remarks See @c FIRAuthErrors for a list of error codes that are common to all API methods. + @remarks See `FIRAuthErrors` for a list of error codes that are common to all API methods. */ - (void)getTokenWithCompletion:(nullable FIRAuthTokenCallback)completion NS_SWIFT_NAME(getToken(completion:)) __attribute__((deprecated)); @@ -296,9 +277,9 @@ NS_SWIFT_NAME(User) asynchronously on the main thread in the future. @remarks The authentication token will be refreshed (by making a network request) if it has - expired, or if @c forceRefresh is YES. + expired, or if `forceRefresh` is YES. - @remarks See @c FIRAuthErrors for a list of error codes that are common to all API methods. + @remarks See `FIRAuthErrors` for a list of error codes that are common to all API methods. */ - (void)getIDTokenForcingRefresh:(BOOL)forceRefresh completion:(nullable FIRAuthTokenCallback)completion; @@ -312,16 +293,16 @@ NS_SWIFT_NAME(User) asynchronously on the main thread in the future. @remarks The authentication token will be refreshed (by making a network request) if it has - expired, or if @c forceRefresh is YES. + expired, or if `forceRefresh` is YES. - @remarks See @c FIRAuthErrors for a list of error codes that are common to all API methods. + @remarks See `FIRAuthErrors` for a list of error codes that are common to all API methods. */ - (void)getTokenForcingRefresh:(BOOL)forceRefresh completion:(nullable FIRAuthTokenCallback)completion __attribute__((deprecated)); /** @fn linkWithCredential:completion: - @brief Convenience method for @c linkAndRetrieveDataWithCredential:completion: This method + @brief Convenience method for `linkAndRetrieveDataWithCredential:completion:` This method doesn't return additional identity provider data. */ - (void)linkWithCredential:(FIRAuthCredential *)credential @@ -336,24 +317,20 @@ NS_SWIFT_NAME(User) Invoked asynchronously on the main thread in the future. @remarks Possible error codes: -
    -
  • @c FIRAuthErrorCodeProviderAlreadyLinked - Indicates an attempt to link a provider of a + + + `FIRAuthErrorCodeProviderAlreadyLinked` - Indicates an attempt to link a provider of a type already linked to this account. -
  • -
  • @c FIRAuthErrorCodeCredentialAlreadyInUse - Indicates an attempt to link with a + + `FIRAuthErrorCodeCredentialAlreadyInUse` - Indicates an attempt to link with a credential that has already been linked with a different Firebase account. -
  • -
  • @c FIRAuthErrorCodeOperationNotAllowed - Indicates that accounts with the identity + + `FIRAuthErrorCodeOperationNotAllowed` - Indicates that accounts with the identity provider represented by the credential are not enabled. Enable them in the Auth section of the Firebase console. -
  • -
@remarks This method may also return error codes associated with updateEmail:completion: and updatePassword:completion: on FIRUser. - @remarks See @c FIRAuthErrors for a list of error codes that are common to all FIRUser methods. + @remarks See `FIRAuthErrors` for a list of error codes that are common to all FIRUser methods. */ - (void)linkAndRetrieveDataWithCredential:(FIRAuthCredential *) credential completion:(nullable FIRAuthDataResultCallback) completion; @@ -366,18 +343,15 @@ NS_SWIFT_NAME(User) Invoked asynchronously on the main thread in the future. @remarks Possible error codes: -
    -
  • @c FIRAuthErrorCodeNoSuchProvider - Indicates an attempt to unlink a provider + + + `FIRAuthErrorCodeNoSuchProvider` - Indicates an attempt to unlink a provider that is not linked to the account. -
  • -
  • @c FIRAuthErrorCodeRequiresRecentLogin - Updating email is a security sensitive + + `FIRAuthErrorCodeRequiresRecentLogin` - Updating email is a security sensitive operation that requires a recent login from the user. This error indicates the user has not signed in recently enough. To resolve, reauthenticate the user by invoking reauthenticateWithCredential:completion: on FIRUser. -
  • -
- @remarks See @c FIRAuthErrors for a list of error codes that are common to all FIRUser methods. + @remarks See `FIRAuthErrors` for a list of error codes that are common to all FIRUser methods. */ - (void)unlinkFromProvider:(NSString *)provider completion:(nullable FIRAuthResultCallback)completion; @@ -389,54 +363,42 @@ NS_SWIFT_NAME(User) is complete, or fails. Invoked asynchronously on the main thread in the future. @remarks Possible error codes: -
    -
  • @c FIRAuthErrorCodeInvalidRecipientEmail - Indicates an invalid recipient email was + + + `FIRAuthErrorCodeInvalidRecipientEmail` - Indicates an invalid recipient email was sent in the request. -
  • -
  • @c FIRAuthErrorCodeInvalidSender - Indicates an invalid sender email is set in + + `FIRAuthErrorCodeInvalidSender` - Indicates an invalid sender email is set in the console for this action. -
  • -
  • @c FIRAuthErrorCodeInvalidMessagePayload - Indicates an invalid email template for + + `FIRAuthErrorCodeInvalidMessagePayload` - Indicates an invalid email template for sending update email. -
  • -
  • @c FIRAuthErrorCodeUserNotFound - Indicates the user account was not found.
  • -
+ + `FIRAuthErrorCodeUserNotFound` - Indicates the user account was not found. - @remarks See @c FIRAuthErrors for a list of error codes that are common to all FIRUser methods. + @remarks See `FIRAuthErrors` for a list of error codes that are common to all FIRUser methods. */ - (void)sendEmailVerificationWithCompletion:(nullable FIRSendEmailVerificationCallback)completion; /** @fn sendEmailVerificationWithActionCodeSettings:completion: @brief Initiates email verification for the user. - @param actionCodeSettings An @c FIRActionCodeSettings object containing settings related to + @param actionCodeSettings An `FIRActionCodeSettings` object containing settings related to handling action codes. @remarks Possible error codes: -
    -
  • @c FIRAuthErrorCodeInvalidRecipientEmail - Indicates an invalid recipient email was + + + `FIRAuthErrorCodeInvalidRecipientEmail` - Indicates an invalid recipient email was sent in the request. -
  • -
  • @c FIRAuthErrorCodeInvalidSender - Indicates an invalid sender email is set in + + `FIRAuthErrorCodeInvalidSender` - Indicates an invalid sender email is set in the console for this action. -
  • -
  • @c FIRAuthErrorCodeInvalidMessagePayload - Indicates an invalid email template for + + `FIRAuthErrorCodeInvalidMessagePayload` - Indicates an invalid email template for sending update email. -
  • -
  • @c FIRAuthErrorCodeUserNotFound - Indicates the user account was not found.
  • -
  • @c FIRAuthErrorCodeMissingIosBundleID - Indicates that the iOS bundle ID is missing when + + `FIRAuthErrorCodeUserNotFound` - Indicates the user account was not found. + + `FIRAuthErrorCodeMissingIosBundleID` - Indicates that the iOS bundle ID is missing when a iOS App Store ID is provided. -
  • -
  • @c FIRAuthErrorCodeMissingAndroidPackageName - Indicates that the android package name - is missing when the @c androidInstallApp flag is set to true. -
  • -
  • @c FIRAuthErrorCodeUnauthorizedDomain - Indicates that the domain specified in the + + `FIRAuthErrorCodeMissingAndroidPackageName` - Indicates that the android package name + is missing when the `androidInstallApp` flag is set to true. + + `FIRAuthErrorCodeUnauthorizedDomain` - Indicates that the domain specified in the continue URL is not whitelisted in the Firebase console. -
  • -
  • @c FIRAuthErrorCodeInvalidContinueURI - Indicates that the domain specified in the + + `FIRAuthErrorCodeInvalidContinueURI` - Indicates that the domain specified in the continue URI is not valid. -
  • -
*/ - (void)sendEmailVerificationWithActionCodeSettings:(FIRActionCodeSettings *)actionCodeSettings completion:(nullable FIRSendEmailVerificationCallback) @@ -449,15 +411,13 @@ NS_SWIFT_NAME(User) complete, or fails. Invoked asynchronously on the main thread in the future. @remarks Possible error codes: -
    -
  • @c FIRAuthErrorCodeRequiresRecentLogin - Updating email is a security sensitive + + + `FIRAuthErrorCodeRequiresRecentLogin` - Updating email is a security sensitive operation that requires a recent login from the user. This error indicates the user has not signed in recently enough. To resolve, reauthenticate the user by invoking reauthenticateWithCredential:completion: on FIRUser. -
  • -
- @remarks See @c FIRAuthErrors for a list of error codes that are common to all FIRUser methods. + @remarks See `FIRAuthErrors` for a list of error codes that are common to all FIRUser methods. */ - (void)deleteWithCompletion:(nullable FIRUserProfileChangeCallback)completion; @@ -473,21 +433,21 @@ NS_SWIFT_NAME(UserProfileChangeRequest) @interface FIRUserProfileChangeRequest : NSObject /** @fn init - @brief Please use @c FIRUser.profileChangeRequest + @brief Please use `FIRUser.profileChangeRequest` */ - (instancetype)init NS_UNAVAILABLE; /** @property displayName @brief The user's display name. @remarks It is an error to set this property after calling - @c FIRUserProfileChangeRequest.commitChangesWithCallback: + `FIRUserProfileChangeRequest.commitChangesWithCallback:` */ @property(nonatomic, copy, nullable) NSString *displayName; /** @property photoURL @brief The user's photo URL. @remarks It is an error to set this property after calling - @c FIRUserProfileChangeRequest.commitChangesWithCallback: + `FIRUserProfileChangeRequest.commitChangesWithCallback:` */ @property(nonatomic, copy, nullable) NSURL *photoURL; -- cgit v1.2.3 From 32bdc38400258b24edb37990cc8cba057a3297de Mon Sep 17 00:00:00 2001 From: Gil Date: Wed, 6 Dec 2017 16:10:59 -0800 Subject: Rework the top-level cmake build to be a superproject (#538) All projects are now ExternalProjects This makes it much easier to build them all in a single pass. --- .gitignore | 3 +++ CMAKE.md | 30 ++++++++++++++++++++++++++---- CMakeLists.txt | 23 ++++++++++------------- Firestore/CMakeLists.txt | 20 +++++++++++++++++--- Firestore/core/CMakeLists.txt | 16 ++++++++++++++++ cmake/external/firestore.cmake | 40 ++++++++++++++++++++++++++++++++++++++++ cmake/external/googletest.cmake | 40 ++++++++++------------------------------ cmake/utils.cmake | 4 +--- 8 files changed, 123 insertions(+), 53 deletions(-) create mode 100644 Firestore/core/CMakeLists.txt create mode 100644 cmake/external/firestore.cmake diff --git a/.gitignore b/.gitignore index 9a2e82e..93e3974 100644 --- a/.gitignore +++ b/.gitignore @@ -54,3 +54,6 @@ Carthage Pods/ Podfile.lock *.xcworkspace + +# CMake +.downloads diff --git a/CMAKE.md b/CMAKE.md index 09ce143..0ec1a94 100644 --- a/CMAKE.md +++ b/CMAKE.md @@ -16,6 +16,7 @@ the Mac App Store. You can get other development tools via [homebrew](https://brew.sh). Adjust as needed for other package managers. + ``` brew install cmake ``` @@ -51,12 +52,33 @@ cd build cmake .. ``` -## Testing +You only need to do this once. + +## Initial Build + +The first build will download, compile all dependencies of the project, and run +an initial battery of tests. + +To perform the initial build, you can use CMake + +``` +cmake --build . +``` + +or use the underlying build system, e.g. + +``` +make -j all +``` + +## Working with a Project + +Once the initial build has completed, you can work with a specific subproject +to make changes and test just that project in isolation. -Once CMake has run once, you can just run `make` repeatedly and it will -regenerate Makefiles as needed. +For example, to work with just Firestore, -To build everything and run tests: ``` +cd build/Firestore make -j all test ``` diff --git a/CMakeLists.txt b/CMakeLists.txt index 53b454d..f9e7527 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,22 +12,19 @@ # See the License for the specific language governing permissions and # limitations under the License. +# Superbuild for Firebase + cmake_minimum_required(VERSION 2.8.11) project(firebase C CXX) -# We use C++11 -set(CMAKE_CXX_STANDARD 11) -set(CMAKE_CXX_STANDARD_REQUIRED ON) -set(CMAKE_CXX_EXTENSIONS OFF) - -# Fully qualified imports, project wide -include_directories("${PROJECT_SOURCE_DIR}") +list(INSERT CMAKE_MODULE_PATH 0 ${PROJECT_SOURCE_DIR}/cmake) -# CMake's test target does not build tests before running them. This adds a -# check target that -add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure) - -include(cmake/utils.cmake) +# External Projects install into this prefix and download into the source tree +# to avoid re-downloading repeatedly during development. +set(FIREBASE_INSTALL_DIR "${PROJECT_BINARY_DIR}/usr") +set(FIREBASE_DOWNLOAD_DIR "${PROJECT_SOURCE_DIR}/.downloads") enable_testing() -add_subdirectory(Firestore) + +include(external/googletest) +include(external/firestore) diff --git a/Firestore/CMakeLists.txt b/Firestore/CMakeLists.txt index 82e1903..6c2a32e 100644 --- a/Firestore/CMakeLists.txt +++ b/Firestore/CMakeLists.txt @@ -12,7 +12,21 @@ # See the License for the specific language governing permissions and # limitations under the License. -include(${PROJECT_SOURCE_DIR}/cmake/external/googletest.cmake) +cmake_minimum_required(VERSION 2.8.11) +project(firestore) -add_subdirectory(core/src/firebase/firestore/util) -add_subdirectory(core/test/firebase/firestore/util) +set(FIREBASE_SOURCE_DIR "${CMAKE_CURRENT_LIST_DIR}/..") +include("${FIREBASE_SOURCE_DIR}/cmake/utils.cmake") + +find_package(GTest REQUIRED) + +# We use C++11 +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) + +# Fully qualified imports, project wide +include_directories("${FIREBASE_SOURCE_DIR}") + +enable_testing() +add_subdirectory(core) diff --git a/Firestore/core/CMakeLists.txt b/Firestore/core/CMakeLists.txt new file mode 100644 index 0000000..c49b6db --- /dev/null +++ b/Firestore/core/CMakeLists.txt @@ -0,0 +1,16 @@ +# 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. + +add_subdirectory(src/firebase/firestore/util) +add_subdirectory(test/firebase/firestore/util) diff --git a/cmake/external/firestore.cmake b/cmake/external/firestore.cmake new file mode 100644 index 0000000..5316873 --- /dev/null +++ b/cmake/external/firestore.cmake @@ -0,0 +1,40 @@ +# 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. + +include(ExternalProject) + +set(source_dir ${PROJECT_SOURCE_DIR}/Firestore) +set(binary_dir ${PROJECT_BINARY_DIR}/Firestore) + +ExternalProject_Add( + Firestore + DEPENDS googletest + + # Lay the binary directory out as if this were a subproject. This makes it + # possible to build and test in it directly. + PREFIX ${binary_dir} + SOURCE_DIR ${source_dir} + BINARY_DIR ${binary_dir} + BUILD_ALWAYS ON + + # Even though this isn't installed, set up the INSTALL_DIR so that + # find_package can find dependencies built from source. + INSTALL_DIR ${FIREBASE_INSTALL_DIR} + INSTALL_COMMAND "" + TEST_BEFORE_INSTALL ON + + CMAKE_ARGS + -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE} + -DCMAKE_INSTALL_PREFIX:PATH= +) diff --git a/cmake/external/googletest.cmake b/cmake/external/googletest.cmake index 66b2689..a956e9f 100644 --- a/cmake/external/googletest.cmake +++ b/cmake/external/googletest.cmake @@ -13,42 +13,22 @@ # limitations under the License. include(ExternalProject) + ExternalProject_Add( - googletest_external - PREFIX googletest + googletest + URL "https://github.com/google/googletest/archive/release-1.8.0.tar.gz" URL_HASH "SHA256=58a6f4277ca2bc8565222b3bbd58a177609e9c488e8a72649359ba51450db7d8" - CMAKE_ARGS - -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE} - -DBUILD_GMOCK:BOOL=OFF - -DBUILD_GTEST:BOOL=ON + PREFIX ${PROJECT_BINARY_DIR}/third_party/googletest - # Cut down on scary log output - LOG_DOWNLOAD ON - LOG_CONFIGURE ON + DOWNLOAD_DIR ${FIREBASE_DOWNLOAD_DIR} + INSTALL_DIR ${FIREBASE_INSTALL_DIR} - INSTALL_COMMAND "" - UPDATE_COMMAND "" TEST_COMMAND "" -) - -ExternalProject_Get_Property(googletest_external source_dir binary_dir) -# CMake requires paths in include_directories to exist at configure time -file(MAKE_DIRECTORY ${source_dir}/googletest/include) - -add_library(gtest STATIC IMPORTED GLBOAL) -set_target_properties( - gtest PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES ${source_dir}/googletest/include - IMPORTED_LOCATION ${binary_dir}/googletest/${CMAKE_FIND_LIBRARY_PREFIXES}gtest.a -) -add_dependencies(gtest googletest_external) - -add_library(gtest_main STATIC IMPORTED GLOBAL) -set_target_properties( - gtest_main PROPERTIES - IMPORTED_LOCATION ${binary_dir}/googletest/${CMAKE_FIND_LIBRARY_PREFIXES}gtest_main.a + CMAKE_ARGS + -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE} + -DCMAKE_INSTALL_PREFIX:PATH= + -DBUILD_SHARED_LIBS:BOOL=OFF ) -add_dependencies(gtest_main googletest_external) diff --git a/cmake/utils.cmake b/cmake/utils.cmake index 40e2325..54044d6 100644 --- a/cmake/utils.cmake +++ b/cmake/utils.cmake @@ -23,7 +23,5 @@ function(cc_test name) add_executable(${name} ${ARGN}) add_test(${name} ${name}) - target_link_libraries(${name} gtest gtest_main) - - add_dependencies(check ${name}) + target_link_libraries(${name} GTest::GTest GTest::Main) endfunction() -- cgit v1.2.3 From 293c6e252eda4c1dbc3f7fbbc3956079ad979132 Mon Sep 17 00:00:00 2001 From: Paul Beusterien Date: Thu, 7 Dec 2017 06:19:59 -0800 Subject: Add FirebaseFirestore.h to fix Firebase module in source build (#539) --- Firestore/Source/Public/FirebaseFirestore.h | 33 +++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 Firestore/Source/Public/FirebaseFirestore.h diff --git a/Firestore/Source/Public/FirebaseFirestore.h b/Firestore/Source/Public/FirebaseFirestore.h new file mode 100644 index 0000000..ff110fd --- /dev/null +++ b/Firestore/Source/Public/FirebaseFirestore.h @@ -0,0 +1,33 @@ +/* + * 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 "FIRCollectionReference.h" +#import "FIRDocumentChange.h" +#import "FIRDocumentReference.h" +#import "FIRDocumentSnapshot.h" +#import "FIRFieldPath.h" +#import "FIRFieldValue.h" +#import "FIRFirestore.h" +#import "FIRFirestoreErrors.h" +#import "FIRFirestoreSettings.h" +#import "FIRGeoPoint.h" +#import "FIRListenerRegistration.h" +#import "FIRQuery.h" +#import "FIRQuerySnapshot.h" +#import "FIRSetOptions.h" +#import "FIRSnapshotMetadata.h" +#import "FIRTransaction.h" +#import "FIRWriteBatch.h" -- cgit v1.2.3 From 5da88e4b9b5ce9d1aee8611d03946e19bdfa5b65 Mon Sep 17 00:00:00 2001 From: zxu Date: Thu, 7 Dec 2017 15:36:15 -0500 Subject: Implement NSPredicate-based query (#531) * implement queryFilteredUsingPredicate in FIRQuery; * add unit test and integration test for queryFilteredUsingPredicate; * project change of adding the FIRQueryTests.m file; * refactoring queryFilteredUsingPredicate to split logic into two helpers; --- Firestore/CHANGELOG.md | 1 + .../Example/Firestore.xcodeproj/project.pbxproj | 4 + Firestore/Example/Tests/API/FIRQueryTests.m | 75 ++++++++++++++++++ .../Example/Tests/Integration/API/FIRQueryTests.m | 17 ++++ Firestore/Source/API/FIRQuery+Internal.h | 2 + Firestore/Source/API/FIRQuery.m | 92 ++++++++++++++++++++++ Firestore/Source/Public/FIRQuery.h | 13 +++ 7 files changed, 204 insertions(+) create mode 100644 Firestore/Example/Tests/API/FIRQueryTests.m diff --git a/Firestore/CHANGELOG.md b/Firestore/CHANGELOG.md index 0c5bcdc..e6ecf11 100644 --- a/Firestore/CHANGELOG.md +++ b/Firestore/CHANGELOG.md @@ -4,6 +4,7 @@ with persistence enabled. - [fixed] Addressed race condition during the teardown of idle streams (#490). +- [feature] Queries can now be created from an NSPredicate. # v0.9.3 - [changed] Improved performance loading documents matching a query. diff --git a/Firestore/Example/Firestore.xcodeproj/project.pbxproj b/Firestore/Example/Firestore.xcodeproj/project.pbxproj index 437b661..5657b95 100644 --- a/Firestore/Example/Firestore.xcodeproj/project.pbxproj +++ b/Firestore/Example/Firestore.xcodeproj/project.pbxproj @@ -61,6 +61,7 @@ 6ED54761B845349D43DB6B78 /* Pods_Firestore_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 75A6FE51C1A02DF38F62FAAD /* Pods_Firestore_Example.framework */; }; 71719F9F1E33DC2100824A3D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 71719F9D1E33DC2100824A3D /* LaunchScreen.storyboard */; }; 873B8AEB1B1F5CCA007FD442 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 873B8AEA1B1F5CCA007FD442 /* Main.storyboard */; }; + ABAEEF4F1FD5F8B100C966CB /* FIRQueryTests.m in Sources */ = {isa = PBXBuildFile; fileRef = ABAEEF4E1FD5F8B100C966CB /* FIRQueryTests.m */; }; AFE6114F0D4DAECBA7B7C089 /* Pods_Firestore_IntegrationTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B2FA635DF5D116A67A7441CD /* Pods_Firestore_IntegrationTests.framework */; }; C4E749275AD0FBDF9F4716A8 /* Pods_SwiftBuildTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 32AD40BF6B0E849B07FFD05E /* Pods_SwiftBuildTest.framework */; }; D5B2532E4676014F57A7EAB9 /* FSTStreamTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D5B25C0D4AADFCA3ADB883E4 /* FSTStreamTests.m */; }; @@ -230,6 +231,7 @@ 8E002F4AD5D9B6197C940847 /* Firestore.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = Firestore.podspec; path = ../Firestore.podspec; sourceTree = ""; }; 9D52E67EE96AA7E5D6F69748 /* Pods-Firestore_IntegrationTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Firestore_IntegrationTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Firestore_IntegrationTests/Pods-Firestore_IntegrationTests.debug.xcconfig"; sourceTree = ""; }; 9EF477AD4B2B643FD320867A /* Pods-Firestore_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Firestore_Example.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Firestore_Example/Pods-Firestore_Example.debug.xcconfig"; sourceTree = ""; }; + ABAEEF4E1FD5F8B100C966CB /* FIRQueryTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FIRQueryTests.m; sourceTree = ""; }; B2FA635DF5D116A67A7441CD /* Pods_Firestore_IntegrationTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Firestore_IntegrationTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; CE00BABB5A3AAB44A4C209E2 /* Pods-Firestore_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Firestore_Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Firestore_Tests/Pods-Firestore_Tests.debug.xcconfig"; sourceTree = ""; }; D3CC3DC5338DCAF43A211155 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; }; @@ -584,6 +586,7 @@ isa = PBXGroup; children = ( DE51B1841F0D48AC0013853F /* FIRGeoPointTests.m */, + ABAEEF4E1FD5F8B100C966CB /* FIRQueryTests.m */, ); path = API; sourceTree = ""; @@ -1161,6 +1164,7 @@ files = ( DE2EF0881F3D0B6E003D0CDC /* FSTTreeSortedDictionaryTests.m in Sources */, DE51B1FD1F0D492C0013853F /* FSTSpecTests.m in Sources */, + ABAEEF4F1FD5F8B100C966CB /* FIRQueryTests.m in Sources */, DE51B2001F0D493A0013853F /* FSTComparisonTests.m in Sources */, DE51B1CC1F0D48C00013853F /* FIRGeoPointTests.m in Sources */, DE51B1E11F0D490D0013853F /* FSTMemoryRemoteDocumentCacheTests.m in Sources */, diff --git a/Firestore/Example/Tests/API/FIRQueryTests.m b/Firestore/Example/Tests/API/FIRQueryTests.m new file mode 100644 index 0000000..bd0d860 --- /dev/null +++ b/Firestore/Example/Tests/API/FIRQueryTests.m @@ -0,0 +1,75 @@ +/* + * 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 FirebaseFirestore; + +#import + +#import "Firestore/Source/API/FIRFirestore+Internal.h" +#import "Firestore/Source/API/FIRQuery+Internal.h" +#import "Firestore/Source/Core/FSTQuery.h" +#import "Firestore/Source/Model/FSTPath.h" + +#import "Firestore/Example/Tests/Util/FSTHelpers.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface FIRQueryTests : XCTestCase +@end + +@implementation FIRQueryTests + +- (void)testFilteringWithPredicate { + // Everything is dummy for unit test here. Filtering does not require any app + // specific setting as far as we do not fetch data. + FIRFirestore *firestore = [[FIRFirestore alloc] initWithProjectID:@"abc" + database:@"abc" + persistenceKey:@"db123" + credentialsProvider:nil + workerDispatchQueue:nil + firebaseApp:nil]; + FSTResourcePath *path = [FSTResourcePath pathWithString:@"foo"]; + FIRQuery *query = [FIRQuery referenceWithQuery:[FSTQuery queryWithPath:path] + firestore:firestore]; + FIRQuery *query1 = [query queryWhereField:@"f" isLessThanOrEqualTo:@1]; + FIRQuery *query2 = [query queryFilteredUsingPredicate: + [NSPredicate predicateWithFormat:@"f<=1"]]; + FIRQuery *query3 = [[query queryWhereField:@"f1" isLessThan:@2] + queryWhereField:@"f2" isEqualTo:@3]; + FIRQuery *query4 = [query queryFilteredUsingPredicate: + [NSPredicate predicateWithFormat:@"f1<2 && f2==3"]]; + FIRQuery *query5 = [[[[[query queryWhereField:@"f1" isLessThan:@2] + queryWhereField:@"f2" isEqualTo:@3] + queryWhereField:@"f1" isLessThanOrEqualTo:@"four"] + queryWhereField:@"f1" isGreaterThanOrEqualTo:@"five"] + queryWhereField:@"f1" isGreaterThan:@6]; + FIRQuery *query6 = [query queryFilteredUsingPredicate: + [NSPredicate predicateWithFormat: + @"f1<2 && f2==3 && f1<='four' && f1>='five' && f1>6"]]; + FIRQuery *query7 = [query queryFilteredUsingPredicate: + [NSPredicate predicateWithFormat: + @"2>f1 && 3==f2 && 'four'>=f1 && 'five'<=f1 && 6 Date: Wed, 6 Dec 2017 09:22:18 -0800 Subject: Remove use of absl::synchronization_internal::ThreadPool --- Firestore/third_party/abseil-cpp/absl/base/config_test.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Firestore/third_party/abseil-cpp/absl/base/config_test.cc b/Firestore/third_party/abseil-cpp/absl/base/config_test.cc index c839712..83d45b7 100644 --- a/Firestore/third_party/abseil-cpp/absl/base/config_test.cc +++ b/Firestore/third_party/abseil-cpp/absl/base/config_test.cc @@ -17,7 +17,7 @@ #include #include "gtest/gtest.h" -#include "absl/synchronization/internal/thread_pool.h" +// #include "absl/synchronization/internal/thread_pool.h" namespace { @@ -41,6 +41,7 @@ TEST(ConfigTest, Endianness) { #endif } +#if 0 #if defined(ABSL_HAVE_THREAD_LOCAL) TEST(ConfigTest, ThreadLocal) { static thread_local int mine_mine_mine = 16; @@ -56,5 +57,6 @@ TEST(ConfigTest, ThreadLocal) { EXPECT_EQ(16, mine_mine_mine); } #endif +#endif // 0 } // namespace -- cgit v1.2.3 From 1641a0d791719c8e0e1fe206e067b4842ca657d2 Mon Sep 17 00:00:00 2001 From: Marek Gilbert Date: Wed, 6 Dec 2017 09:23:03 -0800 Subject: Consume googletest in the standard CMake way --- Firestore/third_party/abseil-cpp/CMakeLists.txt | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/Firestore/third_party/abseil-cpp/CMakeLists.txt b/Firestore/third_party/abseil-cpp/CMakeLists.txt index e87f4a8..0da6c42 100644 --- a/Firestore/third_party/abseil-cpp/CMakeLists.txt +++ b/Firestore/third_party/abseil-cpp/CMakeLists.txt @@ -53,15 +53,17 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_WARNING_VLA} ${CMAKE_CXX_FLAGS} ") ## pthread find_package(Threads REQUIRED) +find_package(GTest REQUIRED) + # commented: used only for standalone test #add_subdirectory(cctz) #add_subdirectory(googletest) ## check targets -check_target(cctz) -check_target(gtest) -check_target(gtest_main) -check_target(gmock) +#check_target(cctz) +#check_target(gtest) +#check_target(gtest_main) +#check_target(gmock) # -fexceptions set(ABSL_EXCEPTIONS_FLAG "${CMAKE_CXX_EXCEPTIONS}") @@ -70,9 +72,9 @@ set(ABSL_EXCEPTIONS_FLAG "${CMAKE_CXX_EXCEPTIONS}") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FIX_MSVC} ${CMAKE_CXX_FLAGS}") list(APPEND ABSL_TEST_COMMON_LIBRARIES - gtest_main - gtest - gmock + GTest::Main + GTest::GTest + #GMock::GMock ${CMAKE_THREAD_LIBS_INIT} ) -- cgit v1.2.3 From ed26e832f60535229177cd0a0bdebd703e8c6dfb Mon Sep 17 00:00:00 2001 From: Marek Gilbert Date: Fri, 24 Nov 2017 20:00:55 -0800 Subject: Explicitly handle Firestore/third_party/Immutable This allows Firestore/third_party to include a mix of Objective-C and C++ code. --- FirebaseFirestore.podspec | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/FirebaseFirestore.podspec b/FirebaseFirestore.podspec index 35e5f5d..ed7346c 100644 --- a/FirebaseFirestore.podspec +++ b/FirebaseFirestore.podspec @@ -33,15 +33,15 @@ Google Cloud Firestore is a NoSQL document database built for automatic scaling, 'Firestore/Port/**/*', 'Firestore/Protos/objc/**/*.[hm]', 'Firestore/core/src/**/*.{h,cc}', - 'Firestore/third_party/**/*.[mh]' + 'Firestore/third_party/Immutable/*.[mh]' ] s.requires_arc = [ 'Firestore/Source/**/*', - 'Firestore/third_party/**/*.[mh]' + 'Firestore/third_party/Immutable/*.[mh]' ] s.exclude_files = [ 'Firestore/Port/*test.cc', - 'Firestore/third_party/**/Tests/**' + 'Firestore/third_party/Immutable/Tests/**' ] s.public_header_files = 'Firestore/Source/Public/*.h' -- cgit v1.2.3 From 36cd94a04fa15a5b85e7156bd070f157306522b9 Mon Sep 17 00:00:00 2001 From: Marek Gilbert Date: Wed, 6 Dec 2017 09:23:55 -0800 Subject: Cut down absl CMakeLists to only include the things we use --- .../third_party/abseil-cpp/absl/CMakeLists.txt | 18 +- .../abseil-cpp/absl/base/CMakeLists.txt | 454 ++++++++++----------- .../abseil-cpp/absl/strings/CMakeLists.txt | 335 ++++++++------- 3 files changed, 399 insertions(+), 408 deletions(-) diff --git a/Firestore/third_party/abseil-cpp/absl/CMakeLists.txt b/Firestore/third_party/abseil-cpp/absl/CMakeLists.txt index 689f64e..c909ba0 100644 --- a/Firestore/third_party/abseil-cpp/absl/CMakeLists.txt +++ b/Firestore/third_party/abseil-cpp/absl/CMakeLists.txt @@ -17,14 +17,14 @@ add_subdirectory(base) -add_subdirectory(algorithm) -add_subdirectory(container) -add_subdirectory(debugging) -add_subdirectory(memory) +#add_subdirectory(algorithm) +#add_subdirectory(container) +#add_subdirectory(debugging) +#add_subdirectory(memory) add_subdirectory(meta) -add_subdirectory(numeric) +#add_subdirectory(numeric) add_subdirectory(strings) -add_subdirectory(synchronization) -add_subdirectory(time) -add_subdirectory(types) -add_subdirectory(utility) +#add_subdirectory(synchronization) +#add_subdirectory(time) +#add_subdirectory(types) +#add_subdirectory(utility) diff --git a/Firestore/third_party/abseil-cpp/absl/base/CMakeLists.txt b/Firestore/third_party/abseil-cpp/absl/base/CMakeLists.txt index 3e94d51..1adc249 100644 --- a/Firestore/third_party/abseil-cpp/absl/base/CMakeLists.txt +++ b/Firestore/third_party/abseil-cpp/absl/base/CMakeLists.txt @@ -16,57 +16,57 @@ list(APPEND BASE_PUBLIC_HEADERS "attributes.h" - "call_once.h" - "casts.h" +# "call_once.h" +# "casts.h" "config.h" "dynamic_annotations.h" "macros.h" "optimization.h" "policy_checks.h" "port.h" - "thread_annotations.h" +# "thread_annotations.h" ) list(APPEND BASE_INTERNAL_HEADERS "internal/atomic_hook.h" - "internal/cycleclock.h" - "internal/endian.h" - "internal/exception_testing.h" - "internal/identity.h" - "internal/invoke.h" +# "internal/cycleclock.h" +# "internal/endian.h" +# "internal/exception_testing.h" +# "internal/identity.h" +# "internal/invoke.h" "internal/log_severity.h" - "internal/low_level_alloc.h" - "internal/low_level_scheduling.h" - "internal/malloc_extension_c.h" - "internal/malloc_extension.h" - "internal/malloc_hook_c.h" - "internal/malloc_hook.h" - "internal/malloc_hook_invoke.h" - "internal/per_thread_tls.h" +# "internal/low_level_alloc.h" +# "internal/low_level_scheduling.h" +# "internal/malloc_extension_c.h" +# "internal/malloc_extension.h" +# "internal/malloc_hook_c.h" +# "internal/malloc_hook.h" +# "internal/malloc_hook_invoke.h" +# "internal/per_thread_tls.h" "internal/raw_logging.h" - "internal/scheduling_mode.h" - "internal/spinlock.h" - "internal/spinlock_wait.h" - "internal/sysinfo.h" - "internal/thread_identity.h" +# "internal/scheduling_mode.h" +# "internal/spinlock.h" +# "internal/spinlock_wait.h" +# "internal/sysinfo.h" +# "internal/thread_identity.h" "internal/throw_delegate.h" - "internal/tsan_mutex_interface.h" - "internal/unaligned_access.h" - "internal/unscaledcycleclock.h" +# "internal/tsan_mutex_interface.h" +# "internal/unaligned_access.h" +# "internal/unscaledcycleclock.h" ) # absl_base main library list(APPEND BASE_SRC - "internal/cycleclock.cc" +# "internal/cycleclock.cc" "internal/raw_logging.cc" - "internal/spinlock.cc" - "internal/sysinfo.cc" - "internal/thread_identity.cc" - "internal/unscaledcycleclock.cc" - "internal/low_level_alloc.cc" - "internal/malloc_hook.cc" +# "internal/spinlock.cc" +# "internal/sysinfo.cc" +# "internal/thread_identity.cc" +# "internal/unscaledcycleclock.cc" +# "internal/low_level_alloc.cc" +# "internal/malloc_hook.cc" ${BASE_PUBLIC_HEADERS} ${BASE_INTERNAL_HEADERS} ) @@ -78,25 +78,25 @@ absl_library( ${BASE_SRC} PUBLIC_LIBRARIES absl_dynamic_annotations - absl_spinlock_wait +# absl_spinlock_wait EXPORT_NAME base ) -# malloc extension library -set(MALLOC_EXTENSION_SRC "internal/malloc_extension.cc") -set(MALLOC_EXTENSION_PUBLIC_LIBRARIES absl::base) - -absl_library( - TARGET - absl_malloc_extension - SOURCES - ${MALLOC_EXTENSION_SRC} - PUBLIC_LIBRARIES - ${MALLOC_EXTENSION_PUBLIC_LIBRARIES} - EXPORT_NAME - malloc_extension -) +## malloc extension library +#set(MALLOC_EXTENSION_SRC "internal/malloc_extension.cc") +#set(MALLOC_EXTENSION_PUBLIC_LIBRARIES absl::base) +# +#absl_library( +# TARGET +# absl_malloc_extension +# SOURCES +# ${MALLOC_EXTENSION_SRC} +# PUBLIC_LIBRARIES +# ${MALLOC_EXTENSION_PUBLIC_LIBRARIES} +# EXPORT_NAME +# malloc_extension +#) # throw delegate library set(THROW_DELEGATE_SRC "internal/throw_delegate.cc") @@ -126,134 +126,134 @@ absl_library( ) -# spinlock_wait library -set(SPINLOCK_WAIT_SRC "internal/spinlock_wait.cc") - -absl_library( - TARGET - absl_spinlock_wait - SOURCES - ${SPINLOCK_WAIT_SRC} -) - - -# malloc_internal library -list(APPEND MALLOC_INTERNAL_SRC - "internal/low_level_alloc.cc" - "internal/malloc_hook.cc" - "internal/malloc_hook_mmap_linux.inc" -) - -absl_library( - TARGET - absl_malloc_internal - SOURCES - ${MALLOC_INTERNAL_SRC} - PUBLIC_LIBRARIES - absl_dynamic_annotations -) - - - +## spinlock_wait library +#set(SPINLOCK_WAIT_SRC "internal/spinlock_wait.cc") # -## TESTS +#absl_library( +# TARGET +# absl_spinlock_wait +# SOURCES +# ${SPINLOCK_WAIT_SRC} +#) # - -# call once test -set(CALL_ONCE_TEST_SRC "call_once_test.cc") -set(CALL_ONCE_TEST_PUBLIC_LIBRARIES absl::base absl::synchronization) - -absl_test( - TARGET - call_once_test - SOURCES - ${CALL_ONCE_TEST_SRC} - PUBLIC_LIBRARIES - ${CALL_ONCE_TEST_PUBLIC_LIBRARIES} -) - - -# test bit_cast_test -set(BIT_CAST_TEST_SRC "bit_cast_test.cc") - -absl_test( - TARGET - bit_cast_test - SOURCES - ${BIT_CAST_TEST_SRC} -) - - -# test absl_throw_delegate_test -set(THROW_DELEGATE_TEST_SRC "throw_delegate_test.cc") -set(THROW_DELEGATE_TEST_PUBLIC_LIBRARIES absl::base absl_throw_delegate) - -absl_test( - TARGET - throw_delegate_test - SOURCES - ${THROW_DELEGATE_TEST_SRC} - PUBLIC_LIBRARIES - ${THROW_DELEGATE_TEST_PUBLIC_LIBRARIES} -) - - -# test invoke_test -set(INVOKE_TEST_SRC "invoke_test.cc") -set(INVOKE_TEST_PUBLIC_LIBRARIES absl::strings) - -absl_test( - TARGET - invoke_test - SOURCES - ${INVOKE_TEST_SRC} - PUBLIC_LIBRARIES - ${INVOKE_TEST_PUBLIC_LIBRARIES} -) - - -# test spinlock_test_common -set(SPINLOCK_TEST_COMMON_SRC "spinlock_test_common.cc") -set(SPINLOCK_TEST_COMMON_PUBLIC_LIBRARIES absl::base absl::synchronization) - -absl_test( - TARGET - spinlock_test_common - SOURCES - ${SPINLOCK_TEST_COMMON_SRC} - PUBLIC_LIBRARIES - ${SPINLOCK_TEST_COMMON_PUBLIC_LIBRARIES} -) - - -# test spinlock_test -set(SPINLOCK_TEST_SRC "spinlock_test_common.cc") -set(SPINLOCK_TEST_PUBLIC_LIBRARIES absl::base absl::synchronization) - -absl_test( - TARGET - spinlock_test - SOURCES - ${SPINLOCK_TEST_SRC} - PUBLIC_LIBRARIES - ${SPINLOCK_TEST_PUBLIC_LIBRARIES} -) - - -# test endian_test -set(ENDIAN_TEST_SRC "internal/endian_test.cc") - -absl_test( - TARGET - endian_test - SOURCES - ${ENDIAN_TEST_SRC} -) +# +## malloc_internal library +#list(APPEND MALLOC_INTERNAL_SRC +# "internal/low_level_alloc.cc" +# "internal/malloc_hook.cc" +# "internal/malloc_hook_mmap_linux.inc" +#) +# +#absl_library( +# TARGET +# absl_malloc_internal +# SOURCES +# ${MALLOC_INTERNAL_SRC} +# PUBLIC_LIBRARIES +# absl_dynamic_annotations +#) +# +# +# +## +### TESTS +## +# +## call once test +#set(CALL_ONCE_TEST_SRC "call_once_test.cc") +#set(CALL_ONCE_TEST_PUBLIC_LIBRARIES absl::base absl::synchronization) +# +#absl_test( +# TARGET +# call_once_test +# SOURCES +# ${CALL_ONCE_TEST_SRC} +# PUBLIC_LIBRARIES +# ${CALL_ONCE_TEST_PUBLIC_LIBRARIES} +#) +# +# +## test bit_cast_test +#set(BIT_CAST_TEST_SRC "bit_cast_test.cc") +# +#absl_test( +# TARGET +# bit_cast_test +# SOURCES +# ${BIT_CAST_TEST_SRC} +#) +# +# +## test absl_throw_delegate_test +#set(THROW_DELEGATE_TEST_SRC "throw_delegate_test.cc") +#set(THROW_DELEGATE_TEST_PUBLIC_LIBRARIES absl::base absl_throw_delegate) +# +#absl_test( +# TARGET +# throw_delegate_test +# SOURCES +# ${THROW_DELEGATE_TEST_SRC} +# PUBLIC_LIBRARIES +# ${THROW_DELEGATE_TEST_PUBLIC_LIBRARIES} +#) +# +# +## test invoke_test +#set(INVOKE_TEST_SRC "invoke_test.cc") +#set(INVOKE_TEST_PUBLIC_LIBRARIES absl::strings) +# +#absl_test( +# TARGET +# invoke_test +# SOURCES +# ${INVOKE_TEST_SRC} +# PUBLIC_LIBRARIES +# ${INVOKE_TEST_PUBLIC_LIBRARIES} +#) +# +# +## test spinlock_test_common +#set(SPINLOCK_TEST_COMMON_SRC "spinlock_test_common.cc") +#set(SPINLOCK_TEST_COMMON_PUBLIC_LIBRARIES absl::base absl::synchronization) +# +#absl_test( +# TARGET +# spinlock_test_common +# SOURCES +# ${SPINLOCK_TEST_COMMON_SRC} +# PUBLIC_LIBRARIES +# ${SPINLOCK_TEST_COMMON_PUBLIC_LIBRARIES} +#) +# +# +## test spinlock_test +#set(SPINLOCK_TEST_SRC "spinlock_test_common.cc") +#set(SPINLOCK_TEST_PUBLIC_LIBRARIES absl::base absl::synchronization) +# +#absl_test( +# TARGET +# spinlock_test +# SOURCES +# ${SPINLOCK_TEST_SRC} +# PUBLIC_LIBRARIES +# ${SPINLOCK_TEST_PUBLIC_LIBRARIES} +#) +# +# +## test endian_test +#set(ENDIAN_TEST_SRC "internal/endian_test.cc") +# +#absl_test( +# TARGET +# endian_test +# SOURCES +# ${ENDIAN_TEST_SRC} +#) # test config_test set(CONFIG_TEST_SRC "config_test.cc") -set(CONFIG_TEST_PUBLIC_LIBRARIES absl::base absl::synchronization) +set(CONFIG_TEST_PUBLIC_LIBRARIES absl::base) absl_test( TARGET config_test @@ -278,64 +278,60 @@ absl_test( ) -# test sysinfo_test -set(SYSINFO_TEST_SRC "internal/sysinfo_test.cc") -set(SYSINFO_TEST_PUBLIC_LIBRARIES absl::base absl::synchronization) - -absl_test( - TARGET - sysinfo_test - SOURCES - ${SYSINFO_TEST_SRC} - PUBLIC_LIBRARIES - ${SYSINFO_TEST_PUBLIC_LIBRARIES} -) - - -# test low_level_alloc_test -set(LOW_LEVEL_ALLOC_TEST_SRC "internal/low_level_alloc_test.cc") -set(LOW_LEVEL_ALLOC_TEST_PUBLIC_LIBRARIES absl::base) - -absl_test( - TARGET - low_level_alloc_test - SOURCES - ${LOW_LEVEL_ALLOC_TEST_SRC} - PUBLIC_LIBRARIES - ${LOW_LEVEL_ALLOC_TEST_PUBLIC_LIBRARIES} -) - - -# test thread_identity_test -set(THREAD_IDENTITY_TEST_SRC "internal/thread_identity_test.cc") -set(THREAD_IDENTITY_TEST_PUBLIC_LIBRARIES absl::base absl::synchronization) - -absl_test( - TARGET - thread_identity_test - SOURCES - ${THREAD_IDENTITY_TEST_SRC} - PUBLIC_LIBRARIES - ${THREAD_IDENTITY_TEST_PUBLIC_LIBRARIES} -) - - -# test absl_malloc_extension_system_malloc_test -set(MALLOC_EXTENSION_SYSTEM_MALLOC_TEST_SRC "internal/malloc_extension_test.cc") -set(MALLOC_EXTENSION_SYSTEM_MALLOC_TEST_PUBLIC_LIBRARIES absl::base absl_malloc_extension) -set(MALLOC_EXTENSION_SYSTEM_MALLOC_TEST_PRIVATE_COMPILE_FLAGS "-DABSL_MALLOC_EXTENSION_TEST_ALLOW_MISSING_EXTENSION=1") - -absl_test( - TARGET - absl_malloc_extension_system_malloc_test - SOURCES - ${MALLOC_EXTENSION_SYSTEM_MALLOC_TEST_SRC} - PUBLIC_LIBRARIES - ${MALLOC_EXTENSION_SYSTEM_MALLOC_TEST_PUBLIC_LIBRARIES} - PRIVATE_COMPILE_FLAGS - ${MALLOC_EXTENSION_SYSTEM_MALLOC_TEST_PRIVATE_COMPILE_FLAGS} -) - - - - +## test sysinfo_test +#set(SYSINFO_TEST_SRC "internal/sysinfo_test.cc") +#set(SYSINFO_TEST_PUBLIC_LIBRARIES absl::base absl::synchronization) +# +#absl_test( +# TARGET +# sysinfo_test +# SOURCES +# ${SYSINFO_TEST_SRC} +# PUBLIC_LIBRARIES +# ${SYSINFO_TEST_PUBLIC_LIBRARIES} +#) +# +# +## test low_level_alloc_test +#set(LOW_LEVEL_ALLOC_TEST_SRC "internal/low_level_alloc_test.cc") +#set(LOW_LEVEL_ALLOC_TEST_PUBLIC_LIBRARIES absl::base) +# +#absl_test( +# TARGET +# low_level_alloc_test +# SOURCES +# ${LOW_LEVEL_ALLOC_TEST_SRC} +# PUBLIC_LIBRARIES +# ${LOW_LEVEL_ALLOC_TEST_PUBLIC_LIBRARIES} +#) +# +# +## test thread_identity_test +#set(THREAD_IDENTITY_TEST_SRC "internal/thread_identity_test.cc") +#set(THREAD_IDENTITY_TEST_PUBLIC_LIBRARIES absl::base absl::synchronization) +# +#absl_test( +# TARGET +# thread_identity_test +# SOURCES +# ${THREAD_IDENTITY_TEST_SRC} +# PUBLIC_LIBRARIES +# ${THREAD_IDENTITY_TEST_PUBLIC_LIBRARIES} +#) +# +# +## test absl_malloc_extension_system_malloc_test +#set(MALLOC_EXTENSION_SYSTEM_MALLOC_TEST_SRC "internal/malloc_extension_test.cc") +#set(MALLOC_EXTENSION_SYSTEM_MALLOC_TEST_PUBLIC_LIBRARIES absl::base absl_malloc_extension) +#set(MALLOC_EXTENSION_SYSTEM_MALLOC_TEST_PRIVATE_COMPILE_FLAGS "-DABSL_MALLOC_EXTENSION_TEST_ALLOW_MISSING_EXTENSION=1") +# +#absl_test( +# TARGET +# absl_malloc_extension_system_malloc_test +# SOURCES +# ${MALLOC_EXTENSION_SYSTEM_MALLOC_TEST_SRC} +# PUBLIC_LIBRARIES +# ${MALLOC_EXTENSION_SYSTEM_MALLOC_TEST_PUBLIC_LIBRARIES} +# PRIVATE_COMPILE_FLAGS +# ${MALLOC_EXTENSION_SYSTEM_MALLOC_TEST_PRIVATE_COMPILE_FLAGS} +#) diff --git a/Firestore/third_party/abseil-cpp/absl/strings/CMakeLists.txt b/Firestore/third_party/abseil-cpp/absl/strings/CMakeLists.txt index dcd4974..2babc9f 100644 --- a/Firestore/third_party/abseil-cpp/absl/strings/CMakeLists.txt +++ b/Firestore/third_party/abseil-cpp/absl/strings/CMakeLists.txt @@ -17,27 +17,27 @@ list(APPEND STRINGS_PUBLIC_HEADERS "ascii.h" - "escaping.h" +# "escaping.h" "match.h" - "numbers.h" - "str_cat.h" +# "numbers.h" +# "str_cat.h" "string_view.h" - "strip.h" - "str_join.h" - "str_replace.h" - "str_split.h" - "substitute.h" +# "strip.h" +# "str_join.h" +# "str_replace.h" +# "str_split.h" +# "substitute.h" ) list(APPEND STRINGS_INTERNAL_HEADERS - "internal/char_map.h" +# "internal/char_map.h" "internal/memutil.h" - "internal/ostringstream.h" +# "internal/ostringstream.h" "internal/resize_uninitialized.h" - "internal/str_join_internal.h" - "internal/str_split_internal.h" - "internal/utf8.h" +# "internal/str_join_internal.h" +# "internal/str_split_internal.h" +# "internal/utf8.h" ) @@ -45,17 +45,16 @@ list(APPEND STRINGS_INTERNAL_HEADERS # add string library list(APPEND STRINGS_SRC "ascii.cc" - "escaping.cc" +# "escaping.cc" "internal/memutil.cc" - "internal/memutil.h" - "internal/utf8.cc" +# "internal/utf8.cc" "match.cc" - "numbers.cc" - "str_cat.cc" - "str_replace.cc" - "str_split.cc" +# "numbers.cc" +# "str_cat.cc" +# "str_replace.cc" +# "str_split.cc" "string_view.cc" - "substitute.cc" +# "substitute.cc" ${STRINGS_PUBLIC_HEADERS} ${STRINGS_INTERNAL_HEADERS} ) @@ -91,18 +90,18 @@ absl_test( ) -# test escaping_test -set(ESCAPING_TEST_SRC "escaping_test.cc") -set(ESCAPING_TEST_PUBLIC_LIBRARIES absl::strings absl::base) - -absl_test( - TARGET - escaping_test - SOURCES - ${ESCAPING_TEST_SRC} - PUBLIC_LIBRARIES - ${ESCAPING_TEST_PUBLIC_LIBRARIES} -) +## test escaping_test +#set(ESCAPING_TEST_SRC "escaping_test.cc") +#set(ESCAPING_TEST_PUBLIC_LIBRARIES absl::strings absl::base) +# +#absl_test( +# TARGET +# escaping_test +# SOURCES +# ${ESCAPING_TEST_SRC} +# PUBLIC_LIBRARIES +# ${ESCAPING_TEST_PUBLIC_LIBRARIES} +#) # test ascii_test @@ -133,20 +132,20 @@ absl_test( ) -# test utf8_test -set(UTF8_TEST_SRC "internal/utf8_test.cc") -set(UTF8_TEST_PUBLIC_LIBRARIES absl::strings absl::base) - -absl_test( - TARGET - utf8_test - SOURCES - ${UTF8_TEST_SRC} - PUBLIC_LIBRARIES - ${UTF8_TEST_PUBLIC_LIBRARIES} -) - - +## test utf8_test +#set(UTF8_TEST_SRC "internal/utf8_test.cc") +#set(UTF8_TEST_PUBLIC_LIBRARIES absl::strings absl::base) +# +#absl_test( +# TARGET +# utf8_test +# SOURCES +# ${UTF8_TEST_SRC} +# PUBLIC_LIBRARIES +# ${UTF8_TEST_PUBLIC_LIBRARIES} +#) +# +# # test string_view_test set(STRING_VIEW_TEST_SRC "string_view_test.cc") set(STRING_VIEW_TEST_PUBLIC_LIBRARIES absl::strings absl_throw_delegate absl::base) @@ -161,57 +160,57 @@ absl_test( ) -# test substitute_test -set(SUBSTITUTE_TEST_SRC "substitute_test.cc") -set(SUBSTITUTE_TEST_PUBLIC_LIBRARIES absl::strings absl::base) - -absl_test( - TARGET - substitute_test - SOURCES - ${SUBSTITUTE_TEST_SRC} - PUBLIC_LIBRARIES - ${SUBSTITUTE_TEST_PUBLIC_LIBRARIES} -) - - -# test str_replace_test -set(STR_REPLACE_TEST_SRC "str_replace_test.cc") -set(STR_REPLACE_TEST_PUBLIC_LIBRARIES absl::strings absl::base absl_throw_delegate) - -absl_test( - TARGET - str_replace_test - SOURCES - ${STR_REPLACE_TEST_SRC} - PUBLIC_LIBRARIES - ${STR_REPLACE_TEST_PUBLIC_LIBRARIES} -) - - -# test str_split_test -set(STR_SPLIT_TEST_SRC "str_split_test.cc") -set(STR_SPLIT_TEST_PUBLIC_LIBRARIES absl::strings absl::base absl_throw_delegate) - -absl_test( - TARGET - str_split_test - SOURCES - ${STR_SPLIT_TEST_SRC} - PUBLIC_LIBRARIES - ${STR_SPLIT_TEST_PUBLIC_LIBRARIES} -) - - -# test ostringstream_test -set(OSTRINGSTREAM_TEST_SRC "internal/ostringstream_test.cc") - -absl_test( - TARGET - ostringstream_test - SOURCES - ${OSTRINGSTREAM_TEST_SRC} -) +## test substitute_test +#set(SUBSTITUTE_TEST_SRC "substitute_test.cc") +#set(SUBSTITUTE_TEST_PUBLIC_LIBRARIES absl::strings absl::base) +# +#absl_test( +# TARGET +# substitute_test +# SOURCES +# ${SUBSTITUTE_TEST_SRC} +# PUBLIC_LIBRARIES +# ${SUBSTITUTE_TEST_PUBLIC_LIBRARIES} +#) +# +# +## test str_replace_test +#set(STR_REPLACE_TEST_SRC "str_replace_test.cc") +#set(STR_REPLACE_TEST_PUBLIC_LIBRARIES absl::strings absl::base absl_throw_delegate) +# +#absl_test( +# TARGET +# str_replace_test +# SOURCES +# ${STR_REPLACE_TEST_SRC} +# PUBLIC_LIBRARIES +# ${STR_REPLACE_TEST_PUBLIC_LIBRARIES} +#) +# +# +## test str_split_test +#set(STR_SPLIT_TEST_SRC "str_split_test.cc") +#set(STR_SPLIT_TEST_PUBLIC_LIBRARIES absl::strings absl::base absl_throw_delegate) +# +#absl_test( +# TARGET +# str_split_test +# SOURCES +# ${STR_SPLIT_TEST_SRC} +# PUBLIC_LIBRARIES +# ${STR_SPLIT_TEST_PUBLIC_LIBRARIES} +#) +# +# +## test ostringstream_test +#set(OSTRINGSTREAM_TEST_SRC "internal/ostringstream_test.cc") +# +#absl_test( +# TARGET +# ostringstream_test +# SOURCES +# ${OSTRINGSTREAM_TEST_SRC} +#) # test resize_uninitialized_test @@ -225,75 +224,71 @@ absl_test( ) -# test str_join_test -set(STR_JOIN_TEST_SRC "str_join_test.cc") -set(STR_JOIN_TEST_PUBLIC_LIBRARIES absl::strings) - -absl_test( - TARGET - str_join_test - SOURCES - ${STR_JOIN_TEST_SRC} - PUBLIC_LIBRARIES - ${STR_JOIN_TEST_PUBLIC_LIBRARIES} -) - - -# test str_cat_test -set(STR_CAT_TEST_SRC "str_cat_test.cc") -set(STR_CAT_TEST_PUBLIC_LIBRARIES absl::strings) - -absl_test( - TARGET - str_cat_test - SOURCES - ${STR_CAT_TEST_SRC} - PUBLIC_LIBRARIES - ${STR_CAT_TEST_PUBLIC_LIBRARIES} -) - - -# test numbers_test -set(NUMBERS_TEST_SRC "numbers_test.cc") -set(NUMBERS_TEST_PUBLIC_LIBRARIES absl::strings) - -absl_test( - TARGET - numbers_test - SOURCES - ${NUMBERS_TEST_SRC} - PUBLIC_LIBRARIES - ${NUMBERS_TEST_PUBLIC_LIBRARIES} -) - - -# test strip_test -set(STRIP_TEST_SRC "strip_test.cc") -set(STRIP_TEST_PUBLIC_LIBRARIES absl::strings) - -absl_test( - TARGET - strip_test - SOURCES - ${STRIP_TEST_SRC} - PUBLIC_LIBRARIES - ${STRIP_TEST_PUBLIC_LIBRARIES} -) - - -# test char_map_test -set(CHAR_MAP_TEST_SRC "internal/char_map_test.cc") -set(CHAR_MAP_TEST_PUBLIC_LIBRARIES absl::strings) - -absl_test( - TARGET - char_map_test - SOURCES - ${CHAR_MAP_TEST_SRC} - PUBLIC_LIBRARIES - ${CHAR_MAP_TEST_PUBLIC_LIBRARIES} -) - - - - +## test str_join_test +#set(STR_JOIN_TEST_SRC "str_join_test.cc") +#set(STR_JOIN_TEST_PUBLIC_LIBRARIES absl::strings) +# +#absl_test( +# TARGET +# str_join_test +# SOURCES +# ${STR_JOIN_TEST_SRC} +# PUBLIC_LIBRARIES +# ${STR_JOIN_TEST_PUBLIC_LIBRARIES} +#) +# +# +## test str_cat_test +#set(STR_CAT_TEST_SRC "str_cat_test.cc") +#set(STR_CAT_TEST_PUBLIC_LIBRARIES absl::strings) +# +#absl_test( +# TARGET +# str_cat_test +# SOURCES +# ${STR_CAT_TEST_SRC} +# PUBLIC_LIBRARIES +# ${STR_CAT_TEST_PUBLIC_LIBRARIES} +#) +# +# +## test numbers_test +#set(NUMBERS_TEST_SRC "numbers_test.cc") +#set(NUMBERS_TEST_PUBLIC_LIBRARIES absl::strings) +# +#absl_test( +# TARGET +# numbers_test +# SOURCES +# ${NUMBERS_TEST_SRC} +# PUBLIC_LIBRARIES +# ${NUMBERS_TEST_PUBLIC_LIBRARIES} +#) +# +# +## test strip_test +#set(STRIP_TEST_SRC "strip_test.cc") +#set(STRIP_TEST_PUBLIC_LIBRARIES absl::strings) +# +#absl_test( +# TARGET +# strip_test +# SOURCES +# ${STRIP_TEST_SRC} +# PUBLIC_LIBRARIES +# ${STRIP_TEST_PUBLIC_LIBRARIES} +#) +# +# +## test char_map_test +#set(CHAR_MAP_TEST_SRC "internal/char_map_test.cc") +#set(CHAR_MAP_TEST_PUBLIC_LIBRARIES absl::strings) +# +#absl_test( +# TARGET +# char_map_test +# SOURCES +# ${CHAR_MAP_TEST_SRC} +# PUBLIC_LIBRARIES +# ${CHAR_MAP_TEST_PUBLIC_LIBRARIES} +#) -- cgit v1.2.3 From 58ff30b73fee4b87228506a8ca9ecb0e2602474e Mon Sep 17 00:00:00 2001 From: Marek Gilbert Date: Wed, 6 Dec 2017 09:10:24 -0800 Subject: Import a subset of abseil sources --- .../abseil-cpp/CMake/AbseilHelpers.cmake | 157 +++ Firestore/third_party/abseil-cpp/CMakeLists.txt | 79 ++ .../third_party/abseil-cpp/absl/CMakeLists.txt | 30 + .../abseil-cpp/absl/base/CMakeLists.txt | 341 ++++++ .../third_party/abseil-cpp/absl/base/attributes.h | 535 ++++++++++ .../third_party/abseil-cpp/absl/base/config.h | 399 +++++++ .../abseil-cpp/absl/base/config_test.cc | 60 ++ .../abseil-cpp/absl/base/dynamic_annotations.cc | 129 +++ .../abseil-cpp/absl/base/dynamic_annotations.h | 409 ++++++++ .../abseil-cpp/absl/base/internal/atomic_hook.h | 150 +++ .../abseil-cpp/absl/base/internal/log_severity.h | 52 + .../abseil-cpp/absl/base/internal/raw_logging.cc | 222 ++++ .../abseil-cpp/absl/base/internal/raw_logging.h | 130 +++ .../absl/base/internal/throw_delegate.cc | 106 ++ .../abseil-cpp/absl/base/internal/throw_delegate.h | 71 ++ .../third_party/abseil-cpp/absl/base/macros.h | 202 ++++ .../abseil-cpp/absl/base/optimization.h | 165 +++ .../abseil-cpp/absl/base/policy_checks.h | 99 ++ Firestore/third_party/abseil-cpp/absl/base/port.h | 26 + .../abseil-cpp/absl/base/raw_logging_test.cc | 50 + .../abseil-cpp/absl/meta/CMakeLists.txt | 49 + .../third_party/abseil-cpp/absl/meta/type_traits.h | 327 ++++++ .../abseil-cpp/absl/meta/type_traits_test.cc | 640 ++++++++++++ .../abseil-cpp/absl/strings/CMakeLists.txt | 299 ++++++ .../third_party/abseil-cpp/absl/strings/ascii.cc | 198 ++++ .../third_party/abseil-cpp/absl/strings/ascii.h | 239 +++++ .../abseil-cpp/absl/strings/ascii_test.cc | 354 +++++++ .../abseil-cpp/absl/strings/internal/memutil.cc | 110 ++ .../abseil-cpp/absl/strings/internal/memutil.h | 146 +++ .../absl/strings/internal/memutil_test.cc | 179 ++++ .../absl/strings/internal/resize_uninitialized.h | 69 ++ .../strings/internal/resize_uninitialized_test.cc | 68 ++ .../third_party/abseil-cpp/absl/strings/match.cc | 40 + .../third_party/abseil-cpp/absl/strings/match.h | 84 ++ .../abseil-cpp/absl/strings/match_test.cc | 99 ++ .../abseil-cpp/absl/strings/string_view.cc | 247 +++++ .../abseil-cpp/absl/strings/string_view.h | 570 ++++++++++ .../abseil-cpp/absl/strings/string_view_test.cc | 1101 ++++++++++++++++++++ 38 files changed, 8231 insertions(+) create mode 100644 Firestore/third_party/abseil-cpp/CMake/AbseilHelpers.cmake create mode 100644 Firestore/third_party/abseil-cpp/CMakeLists.txt create mode 100644 Firestore/third_party/abseil-cpp/absl/CMakeLists.txt create mode 100644 Firestore/third_party/abseil-cpp/absl/base/CMakeLists.txt create mode 100644 Firestore/third_party/abseil-cpp/absl/base/attributes.h create mode 100644 Firestore/third_party/abseil-cpp/absl/base/config.h create mode 100644 Firestore/third_party/abseil-cpp/absl/base/config_test.cc create mode 100644 Firestore/third_party/abseil-cpp/absl/base/dynamic_annotations.cc create mode 100644 Firestore/third_party/abseil-cpp/absl/base/dynamic_annotations.h create mode 100644 Firestore/third_party/abseil-cpp/absl/base/internal/atomic_hook.h create mode 100644 Firestore/third_party/abseil-cpp/absl/base/internal/log_severity.h create mode 100644 Firestore/third_party/abseil-cpp/absl/base/internal/raw_logging.cc create mode 100644 Firestore/third_party/abseil-cpp/absl/base/internal/raw_logging.h create mode 100644 Firestore/third_party/abseil-cpp/absl/base/internal/throw_delegate.cc create mode 100644 Firestore/third_party/abseil-cpp/absl/base/internal/throw_delegate.h create mode 100644 Firestore/third_party/abseil-cpp/absl/base/macros.h create mode 100644 Firestore/third_party/abseil-cpp/absl/base/optimization.h create mode 100644 Firestore/third_party/abseil-cpp/absl/base/policy_checks.h create mode 100644 Firestore/third_party/abseil-cpp/absl/base/port.h create mode 100644 Firestore/third_party/abseil-cpp/absl/base/raw_logging_test.cc create mode 100644 Firestore/third_party/abseil-cpp/absl/meta/CMakeLists.txt create mode 100644 Firestore/third_party/abseil-cpp/absl/meta/type_traits.h create mode 100644 Firestore/third_party/abseil-cpp/absl/meta/type_traits_test.cc create mode 100644 Firestore/third_party/abseil-cpp/absl/strings/CMakeLists.txt create mode 100644 Firestore/third_party/abseil-cpp/absl/strings/ascii.cc create mode 100644 Firestore/third_party/abseil-cpp/absl/strings/ascii.h create mode 100644 Firestore/third_party/abseil-cpp/absl/strings/ascii_test.cc create mode 100644 Firestore/third_party/abseil-cpp/absl/strings/internal/memutil.cc create mode 100644 Firestore/third_party/abseil-cpp/absl/strings/internal/memutil.h create mode 100644 Firestore/third_party/abseil-cpp/absl/strings/internal/memutil_test.cc create mode 100644 Firestore/third_party/abseil-cpp/absl/strings/internal/resize_uninitialized.h create mode 100644 Firestore/third_party/abseil-cpp/absl/strings/internal/resize_uninitialized_test.cc create mode 100644 Firestore/third_party/abseil-cpp/absl/strings/match.cc create mode 100644 Firestore/third_party/abseil-cpp/absl/strings/match.h create mode 100644 Firestore/third_party/abseil-cpp/absl/strings/match_test.cc create mode 100644 Firestore/third_party/abseil-cpp/absl/strings/string_view.cc create mode 100644 Firestore/third_party/abseil-cpp/absl/strings/string_view.h create mode 100644 Firestore/third_party/abseil-cpp/absl/strings/string_view_test.cc diff --git a/Firestore/third_party/abseil-cpp/CMake/AbseilHelpers.cmake b/Firestore/third_party/abseil-cpp/CMake/AbseilHelpers.cmake new file mode 100644 index 0000000..b114b29 --- /dev/null +++ b/Firestore/third_party/abseil-cpp/CMake/AbseilHelpers.cmake @@ -0,0 +1,157 @@ +# +# Copyright 2017 The Abseil Authors. +# +# 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. +# + +include(CMakeParseArguments) + + +# +# create a library in the absl namespace +# +# parameters +# SOURCES : sources files for the library +# PUBLIC_LIBRARIES: targets and flags for linking phase +# PRIVATE_COMPILE_FLAGS: compile flags for the library. Will not be exported. +# EXPORT_NAME: export name for the absl:: target export +# TARGET: target name +# +# create a target associated to +# libraries are installed under CMAKE_INSTALL_FULL_LIBDIR by default +# +function(absl_library) + cmake_parse_arguments(ABSL_LIB + "DISABLE_INSTALL" # keep that in case we want to support installation one day + "TARGET;EXPORT_NAME" + "SOURCES;PUBLIC_LIBRARIES;PRIVATE_COMPILE_FLAGS;PUBLIC_INCLUDE_DIRS;PRIVATE_INCLUDE_DIRS" + ${ARGN} + ) + + set(_NAME ${ABSL_LIB_TARGET}) + string(TOUPPER ${_NAME} _UPPER_NAME) + + add_library(${_NAME} STATIC ${ABSL_LIB_SOURCES}) + + target_compile_options(${_NAME} PRIVATE ${ABSL_COMPILE_CXXFLAGS} ${ABSL_LIB_PRIVATE_COMPILE_FLAGS}) + target_link_libraries(${_NAME} PUBLIC ${ABSL_LIB_PUBLIC_LIBRARIES}) + target_include_directories(${_NAME} + PUBLIC ${ABSL_COMMON_INCLUDE_DIRS} ${ABSL_LIB_PUBLIC_INCLUDE_DIRS} + PRIVATE ${ABSL_LIB_PRIVATE_INCLUDE_DIRS} + ) + + if(ABSL_LIB_EXPORT_NAME) + add_library(absl::${ABSL_LIB_EXPORT_NAME} ALIAS ${_NAME}) + endif() +endfunction() + + + +# +# header only virtual target creation +# +function(absl_header_library) + cmake_parse_arguments(ABSL_HO_LIB + "DISABLE_INSTALL" + "EXPORT_NAME;TARGET" + "PUBLIC_LIBRARIES;PRIVATE_COMPILE_FLAGS;PUBLIC_INCLUDE_DIRS;PRIVATE_INCLUDE_DIRS" + ${ARGN} + ) + + set(_NAME ${ABSL_HO_LIB_TARGET}) + + set(__dummy_header_only_lib_file "${CMAKE_CURRENT_BINARY_DIR}/${_NAME}_header_only_dummy.cc") + + if(NOT EXISTS ${__dummy_header_only_lib_file}) + file(WRITE ${__dummy_header_only_lib_file} + "/* generated file for header-only cmake target */ + + namespace absl { + + // single meaningless symbol + void ${_NAME}__header_fakesym() {} + } // namespace absl + " + ) + endif() + + + add_library(${_NAME} ${__dummy_header_only_lib_file}) + target_link_libraries(${_NAME} PUBLIC ${ABSL_HO_LIB_PUBLIC_LIBRARIES}) + target_include_directories(${_NAME} + PUBLIC ${ABSL_COMMON_INCLUDE_DIRS} ${ABSL_HO_LIB_PUBLIC_INCLUDE_DIRS} + PRIVATE ${ABSL_HO_LIB_PRIVATE_INCLUDE_DIRS} + ) + + if(ABSL_HO_LIB_EXPORT_NAME) + add_library(absl::${ABSL_HO_LIB_EXPORT_NAME} ALIAS ${_NAME}) + endif() + +endfunction() + + +# +# create an abseil unit_test and add it to the executed test list +# +# parameters +# TARGET: target name prefix +# SOURCES: sources files for the tests +# PUBLIC_LIBRARIES: targets and flags for linking phase. +# PRIVATE_COMPILE_FLAGS: compile flags for the test. Will not be exported. +# +# create a target associated to _bin +# +# all tests will be register for execution with add_test() +# +# test compilation and execution is disable when BUILD_TESTING=OFF +# +function(absl_test) + + cmake_parse_arguments(ABSL_TEST + "" + "TARGET" + "SOURCES;PUBLIC_LIBRARIES;PRIVATE_COMPILE_FLAGS;PUBLIC_INCLUDE_DIRS" + ${ARGN} + ) + + + if(BUILD_TESTING) + + set(_NAME ${ABSL_TEST_TARGET}) + string(TOUPPER ${_NAME} _UPPER_NAME) + + add_executable(${_NAME}_bin ${ABSL_TEST_SOURCES}) + + target_compile_options(${_NAME}_bin PRIVATE ${ABSL_COMPILE_CXXFLAGS} ${ABSL_TEST_PRIVATE_COMPILE_FLAGS}) + target_link_libraries(${_NAME}_bin PUBLIC ${ABSL_TEST_PUBLIC_LIBRARIES} ${ABSL_TEST_COMMON_LIBRARIES}) + target_include_directories(${_NAME}_bin + PUBLIC ${ABSL_COMMON_INCLUDE_DIRS} ${ABSL_TEST_PUBLIC_INCLUDE_DIRS} + PRIVATE ${GMOCK_INCLUDE_DIRS} ${GTEST_INCLUDE_DIRS} + ) + + add_test(${_NAME}_test ${_NAME}_bin) + endif(BUILD_TESTING) + +endfunction() + + + + +function(check_target my_target) + + if(NOT TARGET ${my_target}) + message(FATAL_ERROR " ABSL: compiling absl requires a ${my_target} CMake target in your project, + see CMake/README.md for more details") + endif(NOT TARGET ${my_target}) + +endfunction() diff --git a/Firestore/third_party/abseil-cpp/CMakeLists.txt b/Firestore/third_party/abseil-cpp/CMakeLists.txt new file mode 100644 index 0000000..e87f4a8 --- /dev/null +++ b/Firestore/third_party/abseil-cpp/CMakeLists.txt @@ -0,0 +1,79 @@ +# +# Copyright 2017 The Abseil Authors. +# +# 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. +# +cmake_minimum_required(VERSION 2.8.12) +project(absl) + +# enable ctest +include(CTest) + +list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/CMake) + +include(GNUInstallDirs) +include(AbseilHelpers) + + +# config options +set(ABSL_STD_CXX_FLAG "-std=c++11" CACHE STRING "c++ std flag (default: c++11)") + + + +## +## Using absl targets +## +## all public absl targets are +## exported with the absl:: prefix +## +## e.g absl::base absl::synchronization absl::strings .... +## +## DO NOT rely on the internal targets outside of the prefix + + +# include current path +list(APPEND ABSL_COMMON_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}) + +# -std=X +set(CMAKE_CXX_FLAGS "${ABSL_STD_CXX_FLAG} ${CMAKE_CXX_FLAGS}") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_WARNING_VLA} ${CMAKE_CXX_FLAGS} ") + + +# find dependencies +## pthread +find_package(Threads REQUIRED) + +# commented: used only for standalone test +#add_subdirectory(cctz) +#add_subdirectory(googletest) + +## check targets +check_target(cctz) +check_target(gtest) +check_target(gtest_main) +check_target(gmock) + +# -fexceptions +set(ABSL_EXCEPTIONS_FLAG "${CMAKE_CXX_EXCEPTIONS}") + +# fix stuff +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FIX_MSVC} ${CMAKE_CXX_FLAGS}") + +list(APPEND ABSL_TEST_COMMON_LIBRARIES + gtest_main + gtest + gmock + ${CMAKE_THREAD_LIBS_INIT} +) + +add_subdirectory(absl) diff --git a/Firestore/third_party/abseil-cpp/absl/CMakeLists.txt b/Firestore/third_party/abseil-cpp/absl/CMakeLists.txt new file mode 100644 index 0000000..689f64e --- /dev/null +++ b/Firestore/third_party/abseil-cpp/absl/CMakeLists.txt @@ -0,0 +1,30 @@ +# +# Copyright 2017 The Abseil Authors. +# +# 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. +# + + + +add_subdirectory(base) +add_subdirectory(algorithm) +add_subdirectory(container) +add_subdirectory(debugging) +add_subdirectory(memory) +add_subdirectory(meta) +add_subdirectory(numeric) +add_subdirectory(strings) +add_subdirectory(synchronization) +add_subdirectory(time) +add_subdirectory(types) +add_subdirectory(utility) diff --git a/Firestore/third_party/abseil-cpp/absl/base/CMakeLists.txt b/Firestore/third_party/abseil-cpp/absl/base/CMakeLists.txt new file mode 100644 index 0000000..3e94d51 --- /dev/null +++ b/Firestore/third_party/abseil-cpp/absl/base/CMakeLists.txt @@ -0,0 +1,341 @@ +# +# Copyright 2017 The Abseil Authors. +# +# 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. +# + +list(APPEND BASE_PUBLIC_HEADERS + "attributes.h" + "call_once.h" + "casts.h" + "config.h" + "dynamic_annotations.h" + "macros.h" + "optimization.h" + "policy_checks.h" + "port.h" + "thread_annotations.h" +) + + +list(APPEND BASE_INTERNAL_HEADERS + "internal/atomic_hook.h" + "internal/cycleclock.h" + "internal/endian.h" + "internal/exception_testing.h" + "internal/identity.h" + "internal/invoke.h" + "internal/log_severity.h" + "internal/low_level_alloc.h" + "internal/low_level_scheduling.h" + "internal/malloc_extension_c.h" + "internal/malloc_extension.h" + "internal/malloc_hook_c.h" + "internal/malloc_hook.h" + "internal/malloc_hook_invoke.h" + "internal/per_thread_tls.h" + "internal/raw_logging.h" + "internal/scheduling_mode.h" + "internal/spinlock.h" + "internal/spinlock_wait.h" + "internal/sysinfo.h" + "internal/thread_identity.h" + "internal/throw_delegate.h" + "internal/tsan_mutex_interface.h" + "internal/unaligned_access.h" + "internal/unscaledcycleclock.h" +) + + +# absl_base main library +list(APPEND BASE_SRC + "internal/cycleclock.cc" + "internal/raw_logging.cc" + "internal/spinlock.cc" + "internal/sysinfo.cc" + "internal/thread_identity.cc" + "internal/unscaledcycleclock.cc" + "internal/low_level_alloc.cc" + "internal/malloc_hook.cc" + ${BASE_PUBLIC_HEADERS} + ${BASE_INTERNAL_HEADERS} +) + +absl_library( + TARGET + absl_base + SOURCES + ${BASE_SRC} + PUBLIC_LIBRARIES + absl_dynamic_annotations + absl_spinlock_wait + EXPORT_NAME + base +) + +# malloc extension library +set(MALLOC_EXTENSION_SRC "internal/malloc_extension.cc") +set(MALLOC_EXTENSION_PUBLIC_LIBRARIES absl::base) + +absl_library( + TARGET + absl_malloc_extension + SOURCES + ${MALLOC_EXTENSION_SRC} + PUBLIC_LIBRARIES + ${MALLOC_EXTENSION_PUBLIC_LIBRARIES} + EXPORT_NAME + malloc_extension +) + +# throw delegate library +set(THROW_DELEGATE_SRC "internal/throw_delegate.cc") + +absl_library( + TARGET + absl_throw_delegate + SOURCES + ${THROW_DELEGATE_SRC} + PUBLIC_LIBRARIES + ${THROW_DELEGATE_PUBLIC_LIBRARIES} + PRIVATE_COMPILE_FLAGS + ${ABSL_EXCEPTIONS_FLAG} + EXPORT_NAME + throw_delegate +) + + +# dynamic_annotations library +set(DYNAMIC_ANNOTATIONS_SRC "dynamic_annotations.cc") + +absl_library( + TARGET + absl_dynamic_annotations + SOURCES + ${DYNAMIC_ANNOTATIONS_SRC} +) + + +# spinlock_wait library +set(SPINLOCK_WAIT_SRC "internal/spinlock_wait.cc") + +absl_library( + TARGET + absl_spinlock_wait + SOURCES + ${SPINLOCK_WAIT_SRC} +) + + +# malloc_internal library +list(APPEND MALLOC_INTERNAL_SRC + "internal/low_level_alloc.cc" + "internal/malloc_hook.cc" + "internal/malloc_hook_mmap_linux.inc" +) + +absl_library( + TARGET + absl_malloc_internal + SOURCES + ${MALLOC_INTERNAL_SRC} + PUBLIC_LIBRARIES + absl_dynamic_annotations +) + + + +# +## TESTS +# + +# call once test +set(CALL_ONCE_TEST_SRC "call_once_test.cc") +set(CALL_ONCE_TEST_PUBLIC_LIBRARIES absl::base absl::synchronization) + +absl_test( + TARGET + call_once_test + SOURCES + ${CALL_ONCE_TEST_SRC} + PUBLIC_LIBRARIES + ${CALL_ONCE_TEST_PUBLIC_LIBRARIES} +) + + +# test bit_cast_test +set(BIT_CAST_TEST_SRC "bit_cast_test.cc") + +absl_test( + TARGET + bit_cast_test + SOURCES + ${BIT_CAST_TEST_SRC} +) + + +# test absl_throw_delegate_test +set(THROW_DELEGATE_TEST_SRC "throw_delegate_test.cc") +set(THROW_DELEGATE_TEST_PUBLIC_LIBRARIES absl::base absl_throw_delegate) + +absl_test( + TARGET + throw_delegate_test + SOURCES + ${THROW_DELEGATE_TEST_SRC} + PUBLIC_LIBRARIES + ${THROW_DELEGATE_TEST_PUBLIC_LIBRARIES} +) + + +# test invoke_test +set(INVOKE_TEST_SRC "invoke_test.cc") +set(INVOKE_TEST_PUBLIC_LIBRARIES absl::strings) + +absl_test( + TARGET + invoke_test + SOURCES + ${INVOKE_TEST_SRC} + PUBLIC_LIBRARIES + ${INVOKE_TEST_PUBLIC_LIBRARIES} +) + + +# test spinlock_test_common +set(SPINLOCK_TEST_COMMON_SRC "spinlock_test_common.cc") +set(SPINLOCK_TEST_COMMON_PUBLIC_LIBRARIES absl::base absl::synchronization) + +absl_test( + TARGET + spinlock_test_common + SOURCES + ${SPINLOCK_TEST_COMMON_SRC} + PUBLIC_LIBRARIES + ${SPINLOCK_TEST_COMMON_PUBLIC_LIBRARIES} +) + + +# test spinlock_test +set(SPINLOCK_TEST_SRC "spinlock_test_common.cc") +set(SPINLOCK_TEST_PUBLIC_LIBRARIES absl::base absl::synchronization) + +absl_test( + TARGET + spinlock_test + SOURCES + ${SPINLOCK_TEST_SRC} + PUBLIC_LIBRARIES + ${SPINLOCK_TEST_PUBLIC_LIBRARIES} +) + + +# test endian_test +set(ENDIAN_TEST_SRC "internal/endian_test.cc") + +absl_test( + TARGET + endian_test + SOURCES + ${ENDIAN_TEST_SRC} +) + + +# test config_test +set(CONFIG_TEST_SRC "config_test.cc") +set(CONFIG_TEST_PUBLIC_LIBRARIES absl::base absl::synchronization) +absl_test( + TARGET + config_test + SOURCES + ${CONFIG_TEST_SRC} + PUBLIC_LIBRARIES + ${CONFIG_TEST_PUBLIC_LIBRARIES} +) + + +# test raw_logging_test +set(RAW_LOGGING_TEST_SRC "raw_logging_test.cc") +set(RAW_LOGGING_TEST_PUBLIC_LIBRARIES absl::base) + +absl_test( + TARGET + raw_logging_test + SOURCES + ${RAW_LOGGING_TEST_SRC} + PUBLIC_LIBRARIES + ${RAW_LOGGING_TEST_PUBLIC_LIBRARIES} +) + + +# test sysinfo_test +set(SYSINFO_TEST_SRC "internal/sysinfo_test.cc") +set(SYSINFO_TEST_PUBLIC_LIBRARIES absl::base absl::synchronization) + +absl_test( + TARGET + sysinfo_test + SOURCES + ${SYSINFO_TEST_SRC} + PUBLIC_LIBRARIES + ${SYSINFO_TEST_PUBLIC_LIBRARIES} +) + + +# test low_level_alloc_test +set(LOW_LEVEL_ALLOC_TEST_SRC "internal/low_level_alloc_test.cc") +set(LOW_LEVEL_ALLOC_TEST_PUBLIC_LIBRARIES absl::base) + +absl_test( + TARGET + low_level_alloc_test + SOURCES + ${LOW_LEVEL_ALLOC_TEST_SRC} + PUBLIC_LIBRARIES + ${LOW_LEVEL_ALLOC_TEST_PUBLIC_LIBRARIES} +) + + +# test thread_identity_test +set(THREAD_IDENTITY_TEST_SRC "internal/thread_identity_test.cc") +set(THREAD_IDENTITY_TEST_PUBLIC_LIBRARIES absl::base absl::synchronization) + +absl_test( + TARGET + thread_identity_test + SOURCES + ${THREAD_IDENTITY_TEST_SRC} + PUBLIC_LIBRARIES + ${THREAD_IDENTITY_TEST_PUBLIC_LIBRARIES} +) + + +# test absl_malloc_extension_system_malloc_test +set(MALLOC_EXTENSION_SYSTEM_MALLOC_TEST_SRC "internal/malloc_extension_test.cc") +set(MALLOC_EXTENSION_SYSTEM_MALLOC_TEST_PUBLIC_LIBRARIES absl::base absl_malloc_extension) +set(MALLOC_EXTENSION_SYSTEM_MALLOC_TEST_PRIVATE_COMPILE_FLAGS "-DABSL_MALLOC_EXTENSION_TEST_ALLOW_MISSING_EXTENSION=1") + +absl_test( + TARGET + absl_malloc_extension_system_malloc_test + SOURCES + ${MALLOC_EXTENSION_SYSTEM_MALLOC_TEST_SRC} + PUBLIC_LIBRARIES + ${MALLOC_EXTENSION_SYSTEM_MALLOC_TEST_PUBLIC_LIBRARIES} + PRIVATE_COMPILE_FLAGS + ${MALLOC_EXTENSION_SYSTEM_MALLOC_TEST_PRIVATE_COMPILE_FLAGS} +) + + + + diff --git a/Firestore/third_party/abseil-cpp/absl/base/attributes.h b/Firestore/third_party/abseil-cpp/absl/base/attributes.h new file mode 100644 index 0000000..6f3cfe4 --- /dev/null +++ b/Firestore/third_party/abseil-cpp/absl/base/attributes.h @@ -0,0 +1,535 @@ +// Copyright 2017 The Abseil Authors. +// +// 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. +// +// This header file defines macros for declaring attributes for functions, +// types, and variables. +// +// These macros are used within Abseil and allow the compiler to optimize, where +// applicable, certain function calls. +// +// This file is used for both C and C++! +// +// Most macros here are exposing GCC or Clang features, and are stubbed out for +// other compilers. +// +// GCC attributes documentation: +// https://gcc.gnu.org/onlinedocs/gcc-4.7.0/gcc/Function-Attributes.html +// https://gcc.gnu.org/onlinedocs/gcc-4.7.0/gcc/Variable-Attributes.html +// https://gcc.gnu.org/onlinedocs/gcc-4.7.0/gcc/Type-Attributes.html +// +// Most attributes in this file are already supported by GCC 4.7. However, some +// of them are not supported in older version of Clang. Thus, we check +// `__has_attribute()` first. If the check fails, we check if we are on GCC and +// assume the attribute exists on GCC (which is verified on GCC 4.7). +// +// ----------------------------------------------------------------------------- +// Sanitizer Attributes +// ----------------------------------------------------------------------------- +// +// Sanitizer-related attributes are not "defined" in this file (and indeed +// are not defined as such in any file). To utilize the following +// sanitizer-related attributes within your builds, define the following macros +// within your build using a `-D` flag, along with the given value for +// `-fsanitize`: +// +// * `ADDRESS_SANITIZER` + `-fsanitize=address` (Clang, GCC 4.8) +// * `MEMORY_SANITIZER` + `-fsanitize=memory` (Clang-only) +// * `THREAD_SANITIZER + `-fsanitize=thread` (Clang, GCC 4.8+) +// * `UNDEFINED_BEHAVIOR_SANITIZER` + `-fsanitize=undefined` (Clang, GCC 4.9+) +// * `CONTROL_FLOW_INTEGRITY` + -fsanitize=cfi (Clang-only) +// +// Example: +// +// // Enable branches in the Abseil code that are tagged for ASan: +// $ bazel -D ADDRESS_SANITIZER -fsanitize=address *target* +// +// Since these macro names are only supported by GCC and Clang, we only check +// for `__GNUC__` (GCC or Clang) and the above macros. +#ifndef ABSL_BASE_ATTRIBUTES_H_ +#define ABSL_BASE_ATTRIBUTES_H_ + +// ABSL_HAVE_ATTRIBUTE +// +// A function-like feature checking macro that is a wrapper around +// `__has_attribute`, which is defined by GCC 5+ and Clang and evaluates to a +// nonzero constant integer if the attribute is supported or 0 if not. +// +// It evaluates to zero if `__has_attribute` is not defined by the compiler. +// +// GCC: https://gcc.gnu.org/gcc-5/changes.html +// Clang: https://clang.llvm.org/docs/LanguageExtensions.html +#ifdef __has_attribute +#define ABSL_HAVE_ATTRIBUTE(x) __has_attribute(x) +#else +#define ABSL_HAVE_ATTRIBUTE(x) 0 +#endif + +// ABSL_HAVE_CPP_ATTRIBUTE +// +// A function-like feature checking macro that accepts C++11 style attributes. +// It's a wrapper around `__has_cpp_attribute`, defined by ISO C++ SD-6 +// (http://en.cppreference.com/w/cpp/experimental/feature_test). If we don't +// find `__has_cpp_attribute`, will evaluate to 0. +#if defined(__cplusplus) && defined(__has_cpp_attribute) +// NOTE: requiring __cplusplus above should not be necessary, but +// works around https://bugs.llvm.org/show_bug.cgi?id=23435. +#define ABSL_HAVE_CPP_ATTRIBUTE(x) __has_cpp_attribute(x) +#else +#define ABSL_HAVE_CPP_ATTRIBUTE(x) 0 +#endif + +// ----------------------------------------------------------------------------- +// Function Attributes +// ----------------------------------------------------------------------------- +// +// GCC: https://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html +// Clang: https://clang.llvm.org/docs/AttributeReference.html + +// ABSL_PRINTF_ATTRIBUTE +// ABSL_SCANF_ATTRIBUTE +// +// Tells the compiler to perform `printf` format std::string checking if the +// compiler supports it; see the 'format' attribute in +// . +// +// Note: As the GCC manual states, "[s]ince non-static C++ methods +// have an implicit 'this' argument, the arguments of such methods +// should be counted from two, not one." +#if ABSL_HAVE_ATTRIBUTE(format) || (defined(__GNUC__) && !defined(__clang__)) +#define ABSL_PRINTF_ATTRIBUTE(string_index, first_to_check) \ + __attribute__((__format__(__printf__, string_index, first_to_check))) +#define ABSL_SCANF_ATTRIBUTE(string_index, first_to_check) \ + __attribute__((__format__(__scanf__, string_index, first_to_check))) +#else +#define ABSL_PRINTF_ATTRIBUTE(string_index, first_to_check) +#define ABSL_SCANF_ATTRIBUTE(string_index, first_to_check) +#endif + +// ABSL_ATTRIBUTE_ALWAYS_INLINE +// ABSL_ATTRIBUTE_NOINLINE +// +// Forces functions to either inline or not inline. Introduced in gcc 3.1. +#if ABSL_HAVE_ATTRIBUTE(always_inline) || \ + (defined(__GNUC__) && !defined(__clang__)) +#define ABSL_ATTRIBUTE_ALWAYS_INLINE __attribute__((always_inline)) +#define ABSL_HAVE_ATTRIBUTE_ALWAYS_INLINE 1 +#else +#define ABSL_ATTRIBUTE_ALWAYS_INLINE +#endif + +#if ABSL_HAVE_ATTRIBUTE(noinline) || (defined(__GNUC__) && !defined(__clang__)) +#define ABSL_ATTRIBUTE_NOINLINE __attribute__((noinline)) +#define ABSL_HAVE_ATTRIBUTE_NOINLINE 1 +#else +#define ABSL_ATTRIBUTE_NOINLINE +#endif + +// ABSL_ATTRIBUTE_NO_TAIL_CALL +// +// Prevents the compiler from optimizing away stack frames for functions which +// end in a call to another function. +#if ABSL_HAVE_ATTRIBUTE(disable_tail_calls) +#define ABSL_HAVE_ATTRIBUTE_NO_TAIL_CALL 1 +#define ABSL_ATTRIBUTE_NO_TAIL_CALL __attribute__((disable_tail_calls)) +#elif defined(__GNUC__) && !defined(__clang__) +#define ABSL_HAVE_ATTRIBUTE_NO_TAIL_CALL 1 +#define ABSL_ATTRIBUTE_NO_TAIL_CALL \ + __attribute__((optimize("no-optimize-sibling-calls"))) +#else +#define ABSL_ATTRIBUTE_NO_TAIL_CALL +#define ABSL_HAVE_ATTRIBUTE_NO_TAIL_CALL 0 +#endif + +// ABSL_ATTRIBUTE_WEAK +// +// Tags a function as weak for the purposes of compilation and linking. +#if ABSL_HAVE_ATTRIBUTE(weak) || (defined(__GNUC__) && !defined(__clang__)) +#undef ABSL_ATTRIBUTE_WEAK +#define ABSL_ATTRIBUTE_WEAK __attribute__((weak)) +#define ABSL_HAVE_ATTRIBUTE_WEAK 1 +#else +#define ABSL_ATTRIBUTE_WEAK +#define ABSL_HAVE_ATTRIBUTE_WEAK 0 +#endif + +// ABSL_ATTRIBUTE_NONNULL +// +// Tells the compiler either (a) that a particular function parameter +// should be a non-null pointer, or (b) that all pointer arguments should +// be non-null. +// +// Note: As the GCC manual states, "[s]ince non-static C++ methods +// have an implicit 'this' argument, the arguments of such methods +// should be counted from two, not one." +// +// Args are indexed starting at 1. +// +// For non-static class member functions, the implicit `this` argument +// is arg 1, and the first explicit argument is arg 2. For static class member +// functions, there is no implicit `this`, and the first explicit argument is +// arg 1. +// +// Example: +// +// /* arg_a cannot be null, but arg_b can */ +// void Function(void* arg_a, void* arg_b) ABSL_ATTRIBUTE_NONNULL(1); +// +// class C { +// /* arg_a cannot be null, but arg_b can */ +// void Method(void* arg_a, void* arg_b) ABSL_ATTRIBUTE_NONNULL(2); +// +// /* arg_a cannot be null, but arg_b can */ +// static void StaticMethod(void* arg_a, void* arg_b) +// ABSL_ATTRIBUTE_NONNULL(1); +// }; +// +// If no arguments are provided, then all pointer arguments should be non-null. +// +// /* No pointer arguments may be null. */ +// void Function(void* arg_a, void* arg_b, int arg_c) ABSL_ATTRIBUTE_NONNULL(); +// +// NOTE: The GCC nonnull attribute actually accepts a list of arguments, but +// ABSL_ATTRIBUTE_NONNULL does not. +#if ABSL_HAVE_ATTRIBUTE(nonnull) || (defined(__GNUC__) && !defined(__clang__)) +#define ABSL_ATTRIBUTE_NONNULL(arg_index) __attribute__((nonnull(arg_index))) +#else +#define ABSL_ATTRIBUTE_NONNULL(...) +#endif + +// ABSL_ATTRIBUTE_NORETURN +// +// Tells the compiler that a given function never returns. +#if ABSL_HAVE_ATTRIBUTE(noreturn) || (defined(__GNUC__) && !defined(__clang__)) +#define ABSL_ATTRIBUTE_NORETURN __attribute__((noreturn)) +#elif defined(_MSC_VER) +#define ABSL_ATTRIBUTE_NORETURN __declspec(noreturn) +#else +#define ABSL_ATTRIBUTE_NORETURN +#endif + +// ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS +// +// Tells the AddressSanitizer (or other memory testing tools) to ignore a given +// function. Useful for cases when a function reads random locations on stack, +// calls _exit from a cloned subprocess, deliberately accesses buffer +// out of bounds or does other scary things with memory. +// NOTE: GCC supports AddressSanitizer(asan) since 4.8. +// https://gcc.gnu.org/gcc-4.8/changes.html +#if defined(__GNUC__) && defined(ADDRESS_SANITIZER) +#define ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS __attribute__((no_sanitize_address)) +#else +#define ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS +#endif + +// ABSL_ATTRIBUTE_NO_SANITIZE_MEMORY +// +// Tells the MemorySanitizer to relax the handling of a given function. All +// "Use of uninitialized value" warnings from such functions will be suppressed, +// and all values loaded from memory will be considered fully initialized. +// This attribute is similar to the ADDRESS_SANITIZER attribute above, but deals +// with initialized-ness rather than addressability issues. +// NOTE: MemorySanitizer(msan) is supported by Clang but not GCC. +#if defined(__GNUC__) && defined(MEMORY_SANITIZER) +#define ABSL_ATTRIBUTE_NO_SANITIZE_MEMORY __attribute__((no_sanitize_memory)) +#else +#define ABSL_ATTRIBUTE_NO_SANITIZE_MEMORY +#endif + +// ABSL_ATTRIBUTE_NO_SANITIZE_THREAD +// +// Tells the ThreadSanitizer to not instrument a given function. +// NOTE: GCC supports ThreadSanitizer(tsan) since 4.8. +// https://gcc.gnu.org/gcc-4.8/changes.html +#if defined(__GNUC__) && defined(THREAD_SANITIZER) +#define ABSL_ATTRIBUTE_NO_SANITIZE_THREAD __attribute__((no_sanitize_thread)) +#else +#define ABSL_ATTRIBUTE_NO_SANITIZE_THREAD +#endif + +// ABSL_ATTRIBUTE_NO_SANITIZE_UNDEFINED +// +// Tells the UndefinedSanitizer to ignore a given function. Useful for cases +// where certain behavior (eg. division by zero) is being used intentionally. +// NOTE: GCC supports UndefinedBehaviorSanitizer(ubsan) since 4.9. +// https://gcc.gnu.org/gcc-4.9/changes.html +#if defined(__GNUC__) && \ + (defined(UNDEFINED_BEHAVIOR_SANITIZER) || defined(ADDRESS_SANITIZER)) +#define ABSL_ATTRIBUTE_NO_SANITIZE_UNDEFINED \ + __attribute__((no_sanitize("undefined"))) +#else +#define ABSL_ATTRIBUTE_NO_SANITIZE_UNDEFINED +#endif + +// ABSL_ATTRIBUTE_NO_SANITIZE_CFI +// +// Tells the ControlFlowIntegrity sanitizer to not instrument a given function. +// See https://clang.llvm.org/docs/ControlFlowIntegrity.html for details. +#if defined(__GNUC__) && defined(CONTROL_FLOW_INTEGRITY) +#define ABSL_ATTRIBUTE_NO_SANITIZE_CFI __attribute__((no_sanitize("cfi"))) +#else +#define ABSL_ATTRIBUTE_NO_SANITIZE_CFI +#endif + +// ABSL_HAVE_ATTRIBUTE_SECTION +// +// Indicates whether labeled sections are supported. Labeled sections are not +// supported on Darwin/iOS. +#ifdef ABSL_HAVE_ATTRIBUTE_SECTION +#error ABSL_HAVE_ATTRIBUTE_SECTION cannot be directly set +#elif (ABSL_HAVE_ATTRIBUTE(section) || \ + (defined(__GNUC__) && !defined(__clang__))) && \ + !defined(__APPLE__) +#define ABSL_HAVE_ATTRIBUTE_SECTION 1 + +// ABSL_ATTRIBUTE_SECTION +// +// Tells the compiler/linker to put a given function into a section and define +// `__start_ ## name` and `__stop_ ## name` symbols to bracket the section. +// This functionality is supported by GNU linker. Any function annotated with +// `ABSL_ATTRIBUTE_SECTION` must not be inlined, or it will be placed into +// whatever section its caller is placed into. +// +#ifndef ABSL_ATTRIBUTE_SECTION +#define ABSL_ATTRIBUTE_SECTION(name) \ + __attribute__((section(#name))) __attribute__((noinline)) +#endif + +// ABSL_ATTRIBUTE_SECTION_VARIABLE +// +// Tells the compiler/linker to put a given variable into a section and define +// `__start_ ## name` and `__stop_ ## name` symbols to bracket the section. +// This functionality is supported by GNU linker. +#ifndef ABSL_ATTRIBUTE_SECTION_VARIABLE +#define ABSL_ATTRIBUTE_SECTION_VARIABLE(name) __attribute__((section(#name))) +#endif + +// ABSL_DECLARE_ATTRIBUTE_SECTION_VARS +// +// A weak section declaration to be used as a global declaration +// for ABSL_ATTRIBUTE_SECTION_START|STOP(name) to compile and link +// even without functions with ABSL_ATTRIBUTE_SECTION(name). +// ABSL_DEFINE_ATTRIBUTE_SECTION should be in the exactly one file; it's +// a no-op on ELF but not on Mach-O. +// +#ifndef ABSL_DECLARE_ATTRIBUTE_SECTION_VARS +#define ABSL_DECLARE_ATTRIBUTE_SECTION_VARS(name) \ + extern char __start_##name[] ABSL_ATTRIBUTE_WEAK; \ + extern char __stop_##name[] ABSL_ATTRIBUTE_WEAK +#endif +#ifndef ABSL_DEFINE_ATTRIBUTE_SECTION_VARS +#define ABSL_INIT_ATTRIBUTE_SECTION_VARS(name) +#define ABSL_DEFINE_ATTRIBUTE_SECTION_VARS(name) +#endif + +// ABSL_ATTRIBUTE_SECTION_START +// +// Returns `void*` pointers to start/end of a section of code with +// functions having ABSL_ATTRIBUTE_SECTION(name). +// Returns 0 if no such functions exist. +// One must ABSL_DECLARE_ATTRIBUTE_SECTION_VARS(name) for this to compile and +// link. +// +#define ABSL_ATTRIBUTE_SECTION_START(name) \ + (reinterpret_cast(__start_##name)) +#define ABSL_ATTRIBUTE_SECTION_STOP(name) \ + (reinterpret_cast(__stop_##name)) +#else // !ABSL_HAVE_ATTRIBUTE_SECTION + +#define ABSL_HAVE_ATTRIBUTE_SECTION 0 + +// provide dummy definitions +#define ABSL_ATTRIBUTE_SECTION(name) +#define ABSL_ATTRIBUTE_SECTION_VARIABLE(name) +#define ABSL_INIT_ATTRIBUTE_SECTION_VARS(name) +#define ABSL_DEFINE_ATTRIBUTE_SECTION_VARS(name) +#define ABSL_DECLARE_ATTRIBUTE_SECTION_VARS(name) +#define ABSL_ATTRIBUTE_SECTION_START(name) (reinterpret_cast(0)) +#define ABSL_ATTRIBUTE_SECTION_STOP(name) (reinterpret_cast(0)) +#endif // ABSL_ATTRIBUTE_SECTION + +// ABSL_ATTRIBUTE_STACK_ALIGN_FOR_OLD_LIBC +// +// Support for aligning the stack on 32-bit x86. +#if ABSL_HAVE_ATTRIBUTE(force_align_arg_pointer) || \ + (defined(__GNUC__) && !defined(__clang__)) +#if defined(__i386__) +#define ABSL_ATTRIBUTE_STACK_ALIGN_FOR_OLD_LIBC \ + __attribute__((force_align_arg_pointer)) +#define ABSL_REQUIRE_STACK_ALIGN_TRAMPOLINE (0) +#elif defined(__x86_64__) +#define ABSL_REQUIRE_STACK_ALIGN_TRAMPOLINE (1) +#define ABSL_ATTRIBUTE_STACK_ALIGN_FOR_OLD_LIBC +#else // !__i386__ && !__x86_64 +#define ABSL_REQUIRE_STACK_ALIGN_TRAMPOLINE (0) +#define ABSL_ATTRIBUTE_STACK_ALIGN_FOR_OLD_LIBC +#endif // __i386__ +#else +#define ABSL_ATTRIBUTE_STACK_ALIGN_FOR_OLD_LIBC +#define ABSL_REQUIRE_STACK_ALIGN_TRAMPOLINE (0) +#endif + +// ABSL_MUST_USE_RESULT +// +// Tells the compiler to warn about unused return values for functions declared +// with this macro. The macro must appear as the very first part of a function +// declaration or definition: +// +// Example: +// +// ABSL_MUST_USE_RESULT Sprocket* AllocateSprocket(); +// +// This placement has the broadest compatibility with GCC, Clang, and MSVC, with +// both defs and decls, and with GCC-style attributes, MSVC declspec, C++11 +// and C++17 attributes. +// +// ABSL_MUST_USE_RESULT allows using cast-to-void to suppress the unused result +// warning. For that, warn_unused_result is used only for clang but not for gcc. +// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66425 +// +// Note: past advice was to place the macro after the argument list. +#if ABSL_HAVE_ATTRIBUTE(nodiscard) +#define ABSL_MUST_USE_RESULT [[nodiscard]] +#elif defined(__clang__) && ABSL_HAVE_ATTRIBUTE(warn_unused_result) +#define ABSL_MUST_USE_RESULT __attribute__((warn_unused_result)) +#else +#define ABSL_MUST_USE_RESULT +#endif + +// ABSL_ATTRIBUTE_HOT, ABSL_ATTRIBUTE_COLD +// +// Tells GCC that a function is hot or cold. GCC can use this information to +// improve static analysis, i.e. a conditional branch to a cold function +// is likely to be not-taken. +// This annotation is used for function declarations. +// +// Example: +// +// int foo() ABSL_ATTRIBUTE_HOT; +#if ABSL_HAVE_ATTRIBUTE(hot) || (defined(__GNUC__) && !defined(__clang__)) +#define ABSL_ATTRIBUTE_HOT __attribute__((hot)) +#else +#define ABSL_ATTRIBUTE_HOT +#endif + +#if ABSL_HAVE_ATTRIBUTE(cold) || (defined(__GNUC__) && !defined(__clang__)) +#define ABSL_ATTRIBUTE_COLD __attribute__((cold)) +#else +#define ABSL_ATTRIBUTE_COLD +#endif + +// ABSL_XRAY_ALWAYS_INSTRUMENT, ABSL_XRAY_NEVER_INSTRUMENT, ABSL_XRAY_LOG_ARGS +// +// We define the ABSL_XRAY_ALWAYS_INSTRUMENT and ABSL_XRAY_NEVER_INSTRUMENT +// macro used as an attribute to mark functions that must always or never be +// instrumented by XRay. Currently, this is only supported in Clang/LLVM. +// +// For reference on the LLVM XRay instrumentation, see +// http://llvm.org/docs/XRay.html. +// +// A function with the XRAY_ALWAYS_INSTRUMENT macro attribute in its declaration +// will always get the XRay instrumentation sleds. These sleds may introduce +// some binary size and runtime overhead and must be used sparingly. +// +// These attributes only take effect when the following conditions are met: +// +// * The file/target is built in at least C++11 mode, with a Clang compiler +// that supports XRay attributes. +// * The file/target is built with the -fxray-instrument flag set for the +// Clang/LLVM compiler. +// * The function is defined in the translation unit (the compiler honors the +// attribute in either the definition or the declaration, and must match). +// +// There are cases when, even when building with XRay instrumentation, users +// might want to control specifically which functions are instrumented for a +// particular build using special-case lists provided to the compiler. These +// special case lists are provided to Clang via the +// -fxray-always-instrument=... and -fxray-never-instrument=... flags. The +// attributes in source take precedence over these special-case lists. +// +// To disable the XRay attributes at build-time, users may define +// ABSL_NO_XRAY_ATTRIBUTES. Do NOT define ABSL_NO_XRAY_ATTRIBUTES on specific +// packages/targets, as this may lead to conflicting definitions of functions at +// link-time. +// +#if ABSL_HAVE_CPP_ATTRIBUTE(clang::xray_always_instrument) && \ + !defined(ABSL_NO_XRAY_ATTRIBUTES) +#define ABSL_XRAY_ALWAYS_INSTRUMENT [[clang::xray_always_instrument]] +#define ABSL_XRAY_NEVER_INSTRUMENT [[clang::xray_never_instrument]] +#if ABSL_HAVE_CPP_ATTRIBUTE(clang::xray_log_args) +#define ABSL_XRAY_LOG_ARGS(N) \ + [[clang::xray_always_instrument, clang::xray_log_args(N)]] +#else +#define ABSL_XRAY_LOG_ARGS(N) [[clang::xray_always_instrument]] +#endif +#else +#define ABSL_XRAY_ALWAYS_INSTRUMENT +#define ABSL_XRAY_NEVER_INSTRUMENT +#define ABSL_XRAY_LOG_ARGS(N) +#endif + +// ----------------------------------------------------------------------------- +// Variable Attributes +// ----------------------------------------------------------------------------- + +// ABSL_ATTRIBUTE_UNUSED +// +// Prevents the compiler from complaining about or optimizing away variables +// that appear unused. +#if ABSL_HAVE_ATTRIBUTE(unused) || (defined(__GNUC__) && !defined(__clang__)) +#undef ABSL_ATTRIBUTE_UNUSED +#define ABSL_ATTRIBUTE_UNUSED __attribute__((__unused__)) +#else +#define ABSL_ATTRIBUTE_UNUSED +#endif + +// ABSL_ATTRIBUTE_INITIAL_EXEC +// +// Tells the compiler to use "initial-exec" mode for a thread-local variable. +// See http://people.redhat.com/drepper/tls.pdf for the gory details. +#if ABSL_HAVE_ATTRIBUTE(tls_model) || (defined(__GNUC__) && !defined(__clang__)) +#define ABSL_ATTRIBUTE_INITIAL_EXEC __attribute__((tls_model("initial-exec"))) +#else +#define ABSL_ATTRIBUTE_INITIAL_EXEC +#endif + +// ABSL_ATTRIBUTE_PACKED +// +// Prevents the compiler from padding a structure to natural alignment +#if ABSL_HAVE_ATTRIBUTE(packed) || (defined(__GNUC__) && !defined(__clang__)) +#define ABSL_ATTRIBUTE_PACKED __attribute__((__packed__)) +#else +#define ABSL_ATTRIBUTE_PACKED +#endif + +// ABSL_CONST_INIT +// +// A variable declaration annotated with the `ABSL_CONST_INIT` attribute will +// not compile (on supported platforms) unless the variable has a constant +// initializer. This is useful for variables with static and thread storage +// duration, because it guarantees that they will not suffer from the so-called +// "static init order fiasco". +// +// Example: +// +// ABSL_CONST_INIT static MyType my_var = MakeMyType(...); +// +// Note that this attribute is redundant if the variable is declared constexpr. +#if ABSL_HAVE_CPP_ATTRIBUTE(clang::require_constant_initialization) +// NOLINTNEXTLINE(whitespace/braces) +#define ABSL_CONST_INIT [[clang::require_constant_initialization]] +#else +#define ABSL_CONST_INIT +#endif // ABSL_HAVE_CPP_ATTRIBUTE(clang::require_constant_initialization) + +#endif // ABSL_BASE_ATTRIBUTES_H_ diff --git a/Firestore/third_party/abseil-cpp/absl/base/config.h b/Firestore/third_party/abseil-cpp/absl/base/config.h new file mode 100644 index 0000000..8a44c06 --- /dev/null +++ b/Firestore/third_party/abseil-cpp/absl/base/config.h @@ -0,0 +1,399 @@ +// +// Copyright 2017 The Abseil Authors. +// +// 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. +// +// ----------------------------------------------------------------------------- +// File: config.h +// ----------------------------------------------------------------------------- +// +// This header file defines a set of macros for checking the presence of +// important compiler and platform features. Such macros can be used to +// produce portable code by parameterizing compilation based on the presence or +// lack of a given feature. +// +// We define a "feature" as some interface we wish to program to: for example, +// a library function or system call. A value of `1` indicates support for +// that feature; any other value indicates the feature support is undefined. +// +// Example: +// +// Suppose a programmer wants to write a program that uses the 'mmap()' system +// call. The Abseil macro for that feature (`ABSL_HAVE_MMAP`) allows you to +// selectively include the `mmap.h` header and bracket code using that feature +// in the macro: +// +// #include "absl/base/config.h" +// +// #ifdef ABSL_HAVE_MMAP +// #include "sys/mman.h" +// #endif //ABSL_HAVE_MMAP +// +// ... +// #ifdef ABSL_HAVE_MMAP +// void *ptr = mmap(...); +// ... +// #endif // ABSL_HAVE_MMAP + +#ifndef ABSL_BASE_CONFIG_H_ +#define ABSL_BASE_CONFIG_H_ + +// Included for the __GLIBC__ macro (or similar macros on other systems). +#include + +#ifdef __cplusplus +// Included for __GLIBCXX__, _LIBCPP_VERSION +#include +#endif // __cplusplus + +#if defined(__APPLE__) +// Included for TARGET_OS_IPHONE, __IPHONE_OS_VERSION_MIN_REQUIRED, +// __IPHONE_8_0. +#include +#include +#endif + +#include "absl/base/policy_checks.h" + +// ----------------------------------------------------------------------------- +// Compiler Feature Checks +// ----------------------------------------------------------------------------- + +// ABSL_HAVE_BUILTIN() +// +// Checks whether the compiler supports a Clang Feature Checking Macro, and if +// so, checks whether it supports the provided builtin function "x" where x +// is one of the functions noted in +// https://clang.llvm.org/docs/LanguageExtensions.html +// +// Note: Use this macro to avoid an extra level of #ifdef __has_builtin check. +// http://releases.llvm.org/3.3/tools/clang/docs/LanguageExtensions.html +#ifdef __has_builtin +#define ABSL_HAVE_BUILTIN(x) __has_builtin(x) +#else +#define ABSL_HAVE_BUILTIN(x) 0 +#endif + +// ABSL_HAVE_TLS is defined to 1 when __thread should be supported. +// We assume __thread is supported on Linux when compiled with Clang or compiled +// against libstdc++ with _GLIBCXX_HAVE_TLS defined. +#ifdef ABSL_HAVE_TLS +#error ABSL_HAVE_TLS cannot be directly set +#elif defined(__linux__) && (defined(__clang__) || defined(_GLIBCXX_HAVE_TLS)) +#define ABSL_HAVE_TLS 1 +#endif + +// ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE +// +// Checks whether `std::is_trivially_destructible` is supported. +// +// Notes: All supported compilers using libc++ support this feature, as does +// gcc >= 4.8.1 using libstdc++, and Visual Studio. +#ifdef ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE +#error ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE cannot be directly set +#elif defined(_LIBCPP_VERSION) || \ + (!defined(__clang__) && defined(__GNUC__) && defined(__GLIBCXX__) && \ + (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))) || \ + defined(_MSC_VER) +#define ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE 1 +#endif + +// ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE +// +// Checks whether `std::is_trivially_default_constructible` and +// `std::is_trivially_copy_constructible` are supported. + +// ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE +// +// Checks whether `std::is_trivially_copy_assignable` is supported. + +// Notes: Clang with libc++ supports these features, as does gcc >= 5.1 with +// either libc++ or libstdc++, and Visual Studio. +#if defined(ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE) +#error ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE cannot be directly set +#elif defined(ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE) +#error ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE cannot directly set +#elif (defined(__clang__) && defined(_LIBCPP_VERSION)) || \ + (!defined(__clang__) && defined(__GNUC__) && \ + (__GNUC__ > 5 || (__GNUC__ == 5 && __GNUC_MINOR__ >= 1)) && \ + (defined(_LIBCPP_VERSION) || defined(__GLIBCXX__))) || \ + defined(_MSC_VER) +#define ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE 1 +#define ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE 1 +#endif + +// ABSL_HAVE_THREAD_LOCAL +// +// Checks whether C++11's `thread_local` storage duration specifier is +// supported. +#ifdef ABSL_HAVE_THREAD_LOCAL +#error ABSL_HAVE_THREAD_LOCAL cannot be directly set +#elif !defined(__apple_build_version__) || \ + ((__apple_build_version__ >= 8000042) && \ + !(TARGET_OS_IPHONE && __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_9_0)) +// Notes: Xcode's clang did not support `thread_local` until version +// 8, and even then not for all iOS < 9.0. +#define ABSL_HAVE_THREAD_LOCAL 1 +#endif + +// There are platforms for which TLS should not be used even though the compiler +// makes it seem like it's supported (Android NDK < r12b for example). +// This is primarily because of linker problems and toolchain misconfiguration: +// Abseil does not intend to support this indefinitely. Currently, the newest +// toolchain that we intend to support that requires this behavior is the +// r11 NDK - allowing for a 5 year support window on that means this option +// is likely to be removed around June of 2021. +// TLS isn't supported until NDK r12b per +// https://developer.android.com/ndk/downloads/revision_history.html +// Since NDK r16, `__NDK_MAJOR__` and `__NDK_MINOR__` are defined in +// . For NDK < r16, users should define these macros, +// e.g. `-D__NDK_MAJOR__=11 -D__NKD_MINOR__=0` for NDK r11. +#if defined(__ANDROID__) && defined(__clang__) +#if __has_include() +#include +#endif // __has_include() +#if defined(__ANDROID__) && defined(__clang__) && defined(__NDK_MAJOR__) && \ + defined(__NDK_MINOR__) && \ + ((__NDK_MAJOR__ < 12) || ((__NDK_MAJOR__ == 12) && (__NDK_MINOR__ < 1))) +#undef ABSL_HAVE_TLS +#undef ABSL_HAVE_THREAD_LOCAL +#endif +#endif // defined(__ANDROID__) && defined(__clang__) + +// ABSL_HAVE_INTRINSIC_INT128 +// +// Checks whether the __int128 compiler extension for a 128-bit integral type is +// supported. +// +// Notes: __SIZEOF_INT128__ is defined by Clang and GCC when __int128 is +// supported, except on ppc64 and aarch64 where __int128 exists but has exhibits +// a sporadic compiler crashing bug. Nvidia's nvcc also defines __GNUC__ and +// __SIZEOF_INT128__ but not all versions actually support __int128. +#ifdef ABSL_HAVE_INTRINSIC_INT128 +#error ABSL_HAVE_INTRINSIC_INT128 cannot be directly set +#elif (defined(__clang__) && defined(__SIZEOF_INT128__) && \ + !defined(__aarch64__)) || \ + (defined(__CUDACC__) && defined(__SIZEOF_INT128__) && \ + __CUDACC_VER_MAJOR__ >= 9) || \ + (!defined(__clang__) && !defined(__CUDACC__) && defined(__GNUC__) && \ + defined(__SIZEOF_INT128__)) +#define ABSL_HAVE_INTRINSIC_INT128 1 +// __CUDACC_VER__ is a full version number before CUDA 9, and is defined to a +// std::string explaining that it has been removed starting with CUDA 9. We can't +// compare both variants in a single boolean expression because there is no +// short-circuiting in the preprocessor. +#elif defined(__CUDACC__) && defined(__SIZEOF_INT128__) && \ + __CUDACC_VER__ >= 7000 +#define ABSL_HAVE_INTRINSIC_INT128 1 +#endif + +// ABSL_HAVE_EXCEPTIONS +// +// Checks whether the compiler both supports and enables exceptions. Many +// compilers support a "no exceptions" mode that disables exceptions. +// +// Generally, when ABSL_HAVE_EXCEPTIONS is not defined: +// +// * Code using `throw` and `try` may not compile. +// * The `noexcept` specifier will still compile and behave as normal. +// * The `noexcept` operator may still return `false`. +// +// For further details, consult the compiler's documentation. +#ifdef ABSL_HAVE_EXCEPTIONS +#error ABSL_HAVE_EXCEPTIONS cannot be directly set. + +#elif defined(__clang__) +// TODO(calabrese) +// Switch to using __cpp_exceptions when we no longer support versions < 3.6. +// For details on this check, see: +// http://releases.llvm.org/3.6.0/tools/clang/docs/ReleaseNotes.html#the-exceptions-macro +#if defined(__EXCEPTIONS) && __has_feature(cxx_exceptions) +#define ABSL_HAVE_EXCEPTIONS 1 +#endif // defined(__EXCEPTIONS) && __has_feature(cxx_exceptions) + +// Handle remaining special cases and default to exceptions being supported. +#elif !(defined(__GNUC__) && (__GNUC__ < 5) && !defined(__EXCEPTIONS)) && \ + !(defined(__GNUC__) && (__GNUC__ >= 5) && !defined(__cpp_exceptions)) && \ + !(defined(_MSC_VER) && !defined(_CPPUNWIND)) +#define ABSL_HAVE_EXCEPTIONS 1 +#endif + +// ----------------------------------------------------------------------------- +// Platform Feature Checks +// ----------------------------------------------------------------------------- + +// Currently supported operating systems and associated preprocessor +// symbols: +// +// Linux and Linux-derived __linux__ +// Android __ANDROID__ (implies __linux__) +// Linux (non-Android) __linux__ && !__ANDROID__ +// Darwin (Mac OS X and iOS) __APPLE__ +// Akaros (http://akaros.org) __ros__ +// Windows _WIN32 +// NaCL __native_client__ +// AsmJS __asmjs__ +// Fuschia __Fuchsia__ +// +// Note that since Android defines both __ANDROID__ and __linux__, one +// may probe for either Linux or Android by simply testing for __linux__. + +// ABSL_HAVE_MMAP +// +// Checks whether the platform has an mmap(2) implementation as defined in +// POSIX.1-2001. +#ifdef ABSL_HAVE_MMAP +#error ABSL_HAVE_MMAP cannot be directly set +#elif defined(__linux__) || defined(__APPLE__) || defined(__ros__) || \ + defined(__native_client__) || defined(__asmjs__) || defined(__Fuchsia__) +#define ABSL_HAVE_MMAP 1 +#endif + +// ABSL_HAVE_PTHREAD_GETSCHEDPARAM +// +// Checks whether the platform implements the pthread_(get|set)schedparam(3) +// functions as defined in POSIX.1-2001. +#ifdef ABSL_HAVE_PTHREAD_GETSCHEDPARAM +#error ABSL_HAVE_PTHREAD_GETSCHEDPARAM cannot be directly set +#elif defined(__linux__) || defined(__APPLE__) || defined(__ros__) +#define ABSL_HAVE_PTHREAD_GETSCHEDPARAM 1 +#endif + +// ABSL_HAVE_SCHED_YIELD +// +// Checks whether the platform implements sched_yield(2) as defined in +// POSIX.1-2001. +#ifdef ABSL_HAVE_SCHED_YIELD +#error ABSL_HAVE_SCHED_YIELD cannot be directly set +#elif defined(__linux__) || defined(__ros__) || defined(__native_client__) +#define ABSL_HAVE_SCHED_YIELD 1 +#endif + +// ABSL_HAVE_SEMAPHORE_H +// +// Checks whether the platform supports the header and sem_open(3) +// family of functions as standardized in POSIX.1-2001. +// +// Note: While Apple provides for both iOS and macOS, it is +// explicity deprecated and will cause build failures if enabled for those +// platforms. We side-step the issue by not defining it here for Apple +// platforms. +#ifdef ABSL_HAVE_SEMAPHORE_H +#error ABSL_HAVE_SEMAPHORE_H cannot be directly set +#elif defined(__linux__) || defined(__ros__) +#define ABSL_HAVE_SEMAPHORE_H 1 +#endif + +// ABSL_HAVE_ALARM +// +// Checks whether the platform supports the header and alarm(2) +// function as standardized in POSIX.1-2001. +#ifdef ABSL_HAVE_ALARM +#error ABSL_HAVE_ALARM cannot be directly set +#elif defined(__GOOGLE_GRTE_VERSION__) +// feature tests for Google's GRTE +#define ABSL_HAVE_ALARM 1 +#elif defined(__GLIBC__) +// feature test for glibc +#define ABSL_HAVE_ALARM 1 +#elif defined(_MSC_VER) +// feature tests for Microsoft's library +#elif defined(__native_client__) +#else +// other standard libraries +#define ABSL_HAVE_ALARM 1 +#endif + +// ABSL_IS_LITTLE_ENDIAN +// ABSL_IS_BIG_ENDIAN +// +// Checks the endianness of the platform. +// +// Notes: uses the built in endian macros provided by GCC (since 4.6) and +// Clang (since 3.2); see +// https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html. +// Otherwise, if _WIN32, assume little endian. Otherwise, bail with an error. +#if defined(ABSL_IS_BIG_ENDIAN) +#error "ABSL_IS_BIG_ENDIAN cannot be directly set." +#endif +#if defined(ABSL_IS_LITTLE_ENDIAN) +#error "ABSL_IS_LITTLE_ENDIAN cannot be directly set." +#endif + +#if (defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && \ + __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) +#define ABSL_IS_LITTLE_ENDIAN 1 +#elif defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && \ + __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +#define ABSL_IS_BIG_ENDIAN 1 +#elif defined(_WIN32) +#define ABSL_IS_LITTLE_ENDIAN 1 +#else +#error "absl endian detection needs to be set up for your compiler" +#endif + +// ABSL_HAVE_STD_ANY +// +// Checks whether C++17 std::any is available by checking whether exists. +#ifdef ABSL_HAVE_STD_ANY +#error "ABSL_HAVE_STD_ANY cannot be directly set." +#endif + +#ifdef __has_include +#if __has_include() && __cplusplus >= 201703L +#define ABSL_HAVE_STD_ANY 1 +#endif +#endif + +// ABSL_HAVE_STD_OPTIONAL +// +// Checks whether C++17 std::optional is available. +#ifdef ABSL_HAVE_STD_OPTIONAL +#error "ABSL_HAVE_STD_OPTIONAL cannot be directly set." +#endif + +#ifdef __has_include +#if __has_include() && __cplusplus >= 201703L +#define ABSL_HAVE_STD_OPTIONAL 1 +#endif +#endif + +// ABSL_HAVE_STD_STRING_VIEW +// +// Checks whether C++17 std::string_view is available. +#ifdef ABSL_HAVE_STD_STRING_VIEW +#error "ABSL_HAVE_STD_STRING_VIEW cannot be directly set." +#endif + +#ifdef __has_include +#if __has_include() && __cplusplus >= 201703L +#define ABSL_HAVE_STD_STRING_VIEW 1 +#endif +#endif + +// For MSVC, `__has_include` is supported in VS 2017 15.3, which is later than +// the support for , , . So we use _MSC_VER to check +// whether we have VS 2017 RTM (when , , is +// implemented) or higher. +// Also, `__cplusplus` is not correctly set by MSVC, so we use `_MSVC_LANG` to +// check the language version. +// TODO(zhangxy): fix tests before enabling aliasing for `std::any`, +// `std::string_view`. +#if defined(_MSC_VER) && _MSC_VER >= 1910 && \ + ((defined(_MSVC_LANG) && _MSVC_LANG > 201402) || __cplusplus > 201402) +// #define ABSL_HAVE_STD_ANY 1 +#define ABSL_HAVE_STD_OPTIONAL 1 +// #define ABSL_HAVE_STD_STRING_VIEW 1 +#endif + +#endif // ABSL_BASE_CONFIG_H_ diff --git a/Firestore/third_party/abseil-cpp/absl/base/config_test.cc b/Firestore/third_party/abseil-cpp/absl/base/config_test.cc new file mode 100644 index 0000000..c839712 --- /dev/null +++ b/Firestore/third_party/abseil-cpp/absl/base/config_test.cc @@ -0,0 +1,60 @@ +// Copyright 2017 The Abseil Authors. +// +// 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. + +#include "absl/base/config.h" + +#include + +#include "gtest/gtest.h" +#include "absl/synchronization/internal/thread_pool.h" + +namespace { + +TEST(ConfigTest, Endianness) { + union { + uint32_t value; + uint8_t data[sizeof(uint32_t)]; + } number; + number.data[0] = 0x00; + number.data[1] = 0x01; + number.data[2] = 0x02; + number.data[3] = 0x03; +#if defined(ABSL_IS_LITTLE_ENDIAN) && defined(ABSL_IS_BIG_ENDIAN) +#error Both ABSL_IS_LITTLE_ENDIAN and ABSL_IS_BIG_ENDIAN are defined +#elif defined(ABSL_IS_LITTLE_ENDIAN) + EXPECT_EQ(UINT32_C(0x03020100), number.value); +#elif defined(ABSL_IS_BIG_ENDIAN) + EXPECT_EQ(UINT32_C(0x00010203), number.value); +#else +#error Unknown endianness +#endif +} + +#if defined(ABSL_HAVE_THREAD_LOCAL) +TEST(ConfigTest, ThreadLocal) { + static thread_local int mine_mine_mine = 16; + EXPECT_EQ(16, mine_mine_mine); + { + absl::synchronization_internal::ThreadPool pool(1); + pool.Schedule([&] { + EXPECT_EQ(16, mine_mine_mine); + mine_mine_mine = 32; + EXPECT_EQ(32, mine_mine_mine); + }); + } + EXPECT_EQ(16, mine_mine_mine); +} +#endif + +} // namespace diff --git a/Firestore/third_party/abseil-cpp/absl/base/dynamic_annotations.cc b/Firestore/third_party/abseil-cpp/absl/base/dynamic_annotations.cc new file mode 100644 index 0000000..08c27e5 --- /dev/null +++ b/Firestore/third_party/abseil-cpp/absl/base/dynamic_annotations.cc @@ -0,0 +1,129 @@ +// Copyright 2017 The Abseil Authors. +// +// 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. + +#include +#include + +#include "absl/base/dynamic_annotations.h" + +#ifndef __has_feature +#define __has_feature(x) 0 +#endif + +/* Compiler-based ThreadSanitizer defines + DYNAMIC_ANNOTATIONS_EXTERNAL_IMPL = 1 + and provides its own definitions of the functions. */ + +#ifndef DYNAMIC_ANNOTATIONS_EXTERNAL_IMPL +# define DYNAMIC_ANNOTATIONS_EXTERNAL_IMPL 0 +#endif + +/* Each function is empty and called (via a macro) only in debug mode. + The arguments are captured by dynamic tools at runtime. */ + +#if DYNAMIC_ANNOTATIONS_EXTERNAL_IMPL == 0 && !defined(__native_client__) + +#if __has_feature(memory_sanitizer) +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +void AnnotateRWLockCreate(const char *, int, + const volatile void *){} +void AnnotateRWLockDestroy(const char *, int, + const volatile void *){} +void AnnotateRWLockAcquired(const char *, int, + const volatile void *, long){} +void AnnotateRWLockReleased(const char *, int, + const volatile void *, long){} +void AnnotateBenignRace(const char *, int, + const volatile void *, + const char *){} +void AnnotateBenignRaceSized(const char *, int, + const volatile void *, + size_t, + const char *) {} +void AnnotateThreadName(const char *, int, + const char *){} +void AnnotateIgnoreReadsBegin(const char *, int){} +void AnnotateIgnoreReadsEnd(const char *, int){} +void AnnotateIgnoreWritesBegin(const char *, int){} +void AnnotateIgnoreWritesEnd(const char *, int){} +void AnnotateEnableRaceDetection(const char *, int, int){} +void AnnotateMemoryIsInitialized(const char *, int, + const volatile void *mem, size_t size) { +#if __has_feature(memory_sanitizer) + __msan_unpoison(mem, size); +#else + (void)mem; + (void)size; +#endif +} + +void AnnotateMemoryIsUninitialized(const char *, int, + const volatile void *mem, size_t size) { +#if __has_feature(memory_sanitizer) + __msan_allocated_memory(mem, size); +#else + (void)mem; + (void)size; +#endif +} + +static int GetRunningOnValgrind(void) { +#ifdef RUNNING_ON_VALGRIND + if (RUNNING_ON_VALGRIND) return 1; +#endif + char *running_on_valgrind_str = getenv("RUNNING_ON_VALGRIND"); + if (running_on_valgrind_str) { + return strcmp(running_on_valgrind_str, "0") != 0; + } + return 0; +} + +/* See the comments in dynamic_annotations.h */ +int RunningOnValgrind(void) { + static volatile int running_on_valgrind = -1; + int local_running_on_valgrind = running_on_valgrind; + /* C doesn't have thread-safe initialization of statics, and we + don't want to depend on pthread_once here, so hack it. */ + ANNOTATE_BENIGN_RACE(&running_on_valgrind, "safe hack"); + if (local_running_on_valgrind == -1) + running_on_valgrind = local_running_on_valgrind = GetRunningOnValgrind(); + return local_running_on_valgrind; +} + +/* See the comments in dynamic_annotations.h */ +double ValgrindSlowdown(void) { + /* Same initialization hack as in RunningOnValgrind(). */ + static volatile double slowdown = 0.0; + double local_slowdown = slowdown; + ANNOTATE_BENIGN_RACE(&slowdown, "safe hack"); + if (RunningOnValgrind() == 0) { + return 1.0; + } + if (local_slowdown == 0.0) { + char *env = getenv("VALGRIND_SLOWDOWN"); + slowdown = local_slowdown = env ? atof(env) : 50.0; + } + return local_slowdown; +} + +#ifdef __cplusplus +} // extern "C" +#endif +#endif /* DYNAMIC_ANNOTATIONS_EXTERNAL_IMPL == 0 */ diff --git a/Firestore/third_party/abseil-cpp/absl/base/dynamic_annotations.h b/Firestore/third_party/abseil-cpp/absl/base/dynamic_annotations.h new file mode 100644 index 0000000..3b6d6ef --- /dev/null +++ b/Firestore/third_party/abseil-cpp/absl/base/dynamic_annotations.h @@ -0,0 +1,409 @@ +/* + * Copyright 2017 The Abseil Authors. + * + * 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. + */ +/* This file defines dynamic annotations for use with dynamic analysis + tool such as valgrind, PIN, etc. + + Dynamic annotation is a source code annotation that affects + the generated code (that is, the annotation is not a comment). + Each such annotation is attached to a particular + instruction and/or to a particular object (address) in the program. + + The annotations that should be used by users are macros in all upper-case + (e.g., ANNOTATE_THREAD_NAME). + + Actual implementation of these macros may differ depending on the + dynamic analysis tool being used. + + This file supports the following configurations: + - Dynamic Annotations enabled (with static thread-safety warnings disabled). + In this case, macros expand to functions implemented by Thread Sanitizer, + when building with TSan. When not provided an external implementation, + dynamic_annotations.cc provides no-op implementations. + + - Static Clang thread-safety warnings enabled. + When building with a Clang compiler that supports thread-safety warnings, + a subset of annotations can be statically-checked at compile-time. We + expand these macros to static-inline functions that can be analyzed for + thread-safety, but afterwards elided when building the final binary. + + - All annotations are disabled. + If neither Dynamic Annotations nor Clang thread-safety warnings are + enabled, then all annotation-macros expand to empty. */ + +#ifndef ABSL_BASE_DYNAMIC_ANNOTATIONS_H_ +#define ABSL_BASE_DYNAMIC_ANNOTATIONS_H_ + +#ifndef DYNAMIC_ANNOTATIONS_ENABLED +# define DYNAMIC_ANNOTATIONS_ENABLED 0 +#endif + +#if defined(__native_client__) + #include "nacl/dynamic_annotations.h" + + // Stub out the macros missing from the NaCl version. + #ifndef ANNOTATE_CONTIGUOUS_CONTAINER + #define ANNOTATE_CONTIGUOUS_CONTAINER(beg, end, old_mid, new_mid) + #endif + #ifndef ANNOTATE_RWLOCK_CREATE_STATIC + #define ANNOTATE_RWLOCK_CREATE_STATIC(lock) + #endif + #ifndef ADDRESS_SANITIZER_REDZONE + #define ADDRESS_SANITIZER_REDZONE(name) + #endif + #ifndef ANNOTATE_MEMORY_IS_UNINITIALIZED + #define ANNOTATE_MEMORY_IS_UNINITIALIZED(address, size) + #endif + +#else /* !__native_client__ */ + +#if DYNAMIC_ANNOTATIONS_ENABLED != 0 + + /* ------------------------------------------------------------- + Annotations that suppress errors. It is usually better to express the + program's synchronization using the other annotations, but these can + be used when all else fails. */ + + /* Report that we may have a benign race at "pointer", with size + "sizeof(*(pointer))". "pointer" must be a non-void* pointer. Insert at the + point where "pointer" has been allocated, preferably close to the point + where the race happens. See also ANNOTATE_BENIGN_RACE_STATIC. */ + #define ANNOTATE_BENIGN_RACE(pointer, description) \ + AnnotateBenignRaceSized(__FILE__, __LINE__, pointer, \ + sizeof(*(pointer)), description) + + /* Same as ANNOTATE_BENIGN_RACE(address, description), but applies to + the memory range [address, address+size). */ + #define ANNOTATE_BENIGN_RACE_SIZED(address, size, description) \ + AnnotateBenignRaceSized(__FILE__, __LINE__, address, size, description) + + /* Enable (enable!=0) or disable (enable==0) race detection for all threads. + This annotation could be useful if you want to skip expensive race analysis + during some period of program execution, e.g. during initialization. */ + #define ANNOTATE_ENABLE_RACE_DETECTION(enable) \ + AnnotateEnableRaceDetection(__FILE__, __LINE__, enable) + + /* ------------------------------------------------------------- + Annotations useful for debugging. */ + + /* Report the current thread name to a race detector. */ + #define ANNOTATE_THREAD_NAME(name) \ + AnnotateThreadName(__FILE__, __LINE__, name) + + /* ------------------------------------------------------------- + Annotations useful when implementing locks. They are not + normally needed by modules that merely use locks. + The "lock" argument is a pointer to the lock object. */ + + /* Report that a lock has been created at address "lock". */ + #define ANNOTATE_RWLOCK_CREATE(lock) \ + AnnotateRWLockCreate(__FILE__, __LINE__, lock) + + /* Report that a linker initialized lock has been created at address "lock". + */ +#ifdef THREAD_SANITIZER + #define ANNOTATE_RWLOCK_CREATE_STATIC(lock) \ + AnnotateRWLockCreateStatic(__FILE__, __LINE__, lock) +#else + #define ANNOTATE_RWLOCK_CREATE_STATIC(lock) ANNOTATE_RWLOCK_CREATE(lock) +#endif + + /* Report that the lock at address "lock" is about to be destroyed. */ + #define ANNOTATE_RWLOCK_DESTROY(lock) \ + AnnotateRWLockDestroy(__FILE__, __LINE__, lock) + + /* Report that the lock at address "lock" has been acquired. + is_w=1 for writer lock, is_w=0 for reader lock. */ + #define ANNOTATE_RWLOCK_ACQUIRED(lock, is_w) \ + AnnotateRWLockAcquired(__FILE__, __LINE__, lock, is_w) + + /* Report that the lock at address "lock" is about to be released. */ + #define ANNOTATE_RWLOCK_RELEASED(lock, is_w) \ + AnnotateRWLockReleased(__FILE__, __LINE__, lock, is_w) + +#else /* DYNAMIC_ANNOTATIONS_ENABLED == 0 */ + + #define ANNOTATE_RWLOCK_CREATE(lock) /* empty */ + #define ANNOTATE_RWLOCK_CREATE_STATIC(lock) /* empty */ + #define ANNOTATE_RWLOCK_DESTROY(lock) /* empty */ + #define ANNOTATE_RWLOCK_ACQUIRED(lock, is_w) /* empty */ + #define ANNOTATE_RWLOCK_RELEASED(lock, is_w) /* empty */ + #define ANNOTATE_BENIGN_RACE(address, description) /* empty */ + #define ANNOTATE_BENIGN_RACE_SIZED(address, size, description) /* empty */ + #define ANNOTATE_THREAD_NAME(name) /* empty */ + #define ANNOTATE_ENABLE_RACE_DETECTION(enable) /* empty */ + +#endif /* DYNAMIC_ANNOTATIONS_ENABLED */ + +/* These annotations are also made available to LLVM's Memory Sanitizer */ +#if DYNAMIC_ANNOTATIONS_ENABLED == 1 || defined(MEMORY_SANITIZER) + #define ANNOTATE_MEMORY_IS_INITIALIZED(address, size) \ + AnnotateMemoryIsInitialized(__FILE__, __LINE__, address, size) + + #define ANNOTATE_MEMORY_IS_UNINITIALIZED(address, size) \ + AnnotateMemoryIsUninitialized(__FILE__, __LINE__, address, size) +#else + #define ANNOTATE_MEMORY_IS_INITIALIZED(address, size) /* empty */ + #define ANNOTATE_MEMORY_IS_UNINITIALIZED(address, size) /* empty */ +#endif /* DYNAMIC_ANNOTATIONS_ENABLED || MEMORY_SANITIZER */ +/* TODO(delesley) -- Replace __CLANG_SUPPORT_DYN_ANNOTATION__ with the + appropriate feature ID. */ +#if defined(__clang__) && (!defined(SWIG)) \ + && defined(__CLANG_SUPPORT_DYN_ANNOTATION__) + + #if DYNAMIC_ANNOTATIONS_ENABLED == 0 + #define ANNOTALYSIS_ENABLED + #endif + + /* When running in opt-mode, GCC will issue a warning, if these attributes are + compiled. Only include them when compiling using Clang. */ + #define ATTRIBUTE_IGNORE_READS_BEGIN \ + __attribute((exclusive_lock_function("*"))) + #define ATTRIBUTE_IGNORE_READS_END \ + __attribute((unlock_function("*"))) +#else + #define ATTRIBUTE_IGNORE_READS_BEGIN /* empty */ + #define ATTRIBUTE_IGNORE_READS_END /* empty */ +#endif /* defined(__clang__) && ... */ + +#if (DYNAMIC_ANNOTATIONS_ENABLED != 0) || defined(ANNOTALYSIS_ENABLED) + #define ANNOTATIONS_ENABLED +#endif + +#if (DYNAMIC_ANNOTATIONS_ENABLED != 0) + + /* Request the analysis tool to ignore all reads in the current thread + until ANNOTATE_IGNORE_READS_END is called. + Useful to ignore intentional racey reads, while still checking + other reads and all writes. + See also ANNOTATE_UNPROTECTED_READ. */ + #define ANNOTATE_IGNORE_READS_BEGIN() \ + AnnotateIgnoreReadsBegin(__FILE__, __LINE__) + + /* Stop ignoring reads. */ + #define ANNOTATE_IGNORE_READS_END() \ + AnnotateIgnoreReadsEnd(__FILE__, __LINE__) + + /* Similar to ANNOTATE_IGNORE_READS_BEGIN, but ignore writes instead. */ + #define ANNOTATE_IGNORE_WRITES_BEGIN() \ + AnnotateIgnoreWritesBegin(__FILE__, __LINE__) + + /* Stop ignoring writes. */ + #define ANNOTATE_IGNORE_WRITES_END() \ + AnnotateIgnoreWritesEnd(__FILE__, __LINE__) + +/* Clang provides limited support for static thread-safety analysis + through a feature called Annotalysis. We configure macro-definitions + according to whether Annotalysis support is available. */ +#elif defined(ANNOTALYSIS_ENABLED) + + #define ANNOTATE_IGNORE_READS_BEGIN() \ + StaticAnnotateIgnoreReadsBegin(__FILE__, __LINE__) + + #define ANNOTATE_IGNORE_READS_END() \ + StaticAnnotateIgnoreReadsEnd(__FILE__, __LINE__) + + #define ANNOTATE_IGNORE_WRITES_BEGIN() \ + StaticAnnotateIgnoreWritesBegin(__FILE__, __LINE__) + + #define ANNOTATE_IGNORE_WRITES_END() \ + StaticAnnotateIgnoreWritesEnd(__FILE__, __LINE__) + +#else + #define ANNOTATE_IGNORE_READS_BEGIN() /* empty */ + #define ANNOTATE_IGNORE_READS_END() /* empty */ + #define ANNOTATE_IGNORE_WRITES_BEGIN() /* empty */ + #define ANNOTATE_IGNORE_WRITES_END() /* empty */ +#endif + +/* Implement the ANNOTATE_IGNORE_READS_AND_WRITES_* annotations using the more + primitive annotations defined above. */ +#if defined(ANNOTATIONS_ENABLED) + + /* Start ignoring all memory accesses (both reads and writes). */ + #define ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() \ + do { \ + ANNOTATE_IGNORE_READS_BEGIN(); \ + ANNOTATE_IGNORE_WRITES_BEGIN(); \ + }while (0) + + /* Stop ignoring both reads and writes. */ + #define ANNOTATE_IGNORE_READS_AND_WRITES_END() \ + do { \ + ANNOTATE_IGNORE_WRITES_END(); \ + ANNOTATE_IGNORE_READS_END(); \ + }while (0) + +#else + #define ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() /* empty */ + #define ANNOTATE_IGNORE_READS_AND_WRITES_END() /* empty */ +#endif + +/* Use the macros above rather than using these functions directly. */ +#include +#ifdef __cplusplus +extern "C" { +#endif +void AnnotateRWLockCreate(const char *file, int line, + const volatile void *lock); +void AnnotateRWLockCreateStatic(const char *file, int line, + const volatile void *lock); +void AnnotateRWLockDestroy(const char *file, int line, + const volatile void *lock); +void AnnotateRWLockAcquired(const char *file, int line, + const volatile void *lock, long is_w); /* NOLINT */ +void AnnotateRWLockReleased(const char *file, int line, + const volatile void *lock, long is_w); /* NOLINT */ +void AnnotateBenignRace(const char *file, int line, + const volatile void *address, + const char *description); +void AnnotateBenignRaceSized(const char *file, int line, + const volatile void *address, + size_t size, + const char *description); +void AnnotateThreadName(const char *file, int line, + const char *name); +void AnnotateEnableRaceDetection(const char *file, int line, int enable); +void AnnotateMemoryIsInitialized(const char *file, int line, + const volatile void *mem, size_t size); +void AnnotateMemoryIsUninitialized(const char *file, int line, + const volatile void *mem, size_t size); + +/* Annotations expand to these functions, when Dynamic Annotations are enabled. + These functions are either implemented as no-op calls, if no Sanitizer is + attached, or provided with externally-linked implementations by a library + like ThreadSanitizer. */ +void AnnotateIgnoreReadsBegin(const char *file, int line) + ATTRIBUTE_IGNORE_READS_BEGIN; +void AnnotateIgnoreReadsEnd(const char *file, int line) + ATTRIBUTE_IGNORE_READS_END; +void AnnotateIgnoreWritesBegin(const char *file, int line); +void AnnotateIgnoreWritesEnd(const char *file, int line); + +#if defined(ANNOTALYSIS_ENABLED) +/* When Annotalysis is enabled without Dynamic Annotations, the use of + static-inline functions allows the annotations to be read at compile-time, + while still letting the compiler elide the functions from the final build. + + TODO(delesley) -- The exclusive lock here ignores writes as well, but + allows IGNORE_READS_AND_WRITES to work properly. */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-function" +static inline void StaticAnnotateIgnoreReadsBegin(const char *file, int line) + ATTRIBUTE_IGNORE_READS_BEGIN { (void)file; (void)line; } +static inline void StaticAnnotateIgnoreReadsEnd(const char *file, int line) + ATTRIBUTE_IGNORE_READS_END { (void)file; (void)line; } +static inline void StaticAnnotateIgnoreWritesBegin( + const char *file, int line) { (void)file; (void)line; } +static inline void StaticAnnotateIgnoreWritesEnd( + const char *file, int line) { (void)file; (void)line; } +#pragma GCC diagnostic pop +#endif + +/* Return non-zero value if running under valgrind. + + If "valgrind.h" is included into dynamic_annotations.cc, + the regular valgrind mechanism will be used. + See http://valgrind.org/docs/manual/manual-core-adv.html about + RUNNING_ON_VALGRIND and other valgrind "client requests". + The file "valgrind.h" may be obtained by doing + svn co svn://svn.valgrind.org/valgrind/trunk/include + + If for some reason you can't use "valgrind.h" or want to fake valgrind, + there are two ways to make this function return non-zero: + - Use environment variable: export RUNNING_ON_VALGRIND=1 + - Make your tool intercept the function RunningOnValgrind() and + change its return value. + */ +int RunningOnValgrind(void); + +/* ValgrindSlowdown returns: + * 1.0, if (RunningOnValgrind() == 0) + * 50.0, if (RunningOnValgrind() != 0 && getenv("VALGRIND_SLOWDOWN") == NULL) + * atof(getenv("VALGRIND_SLOWDOWN")) otherwise + This function can be used to scale timeout values: + EXAMPLE: + for (;;) { + DoExpensiveBackgroundTask(); + SleepForSeconds(5 * ValgrindSlowdown()); + } + */ +double ValgrindSlowdown(void); + +#ifdef __cplusplus +} +#endif + +/* ANNOTATE_UNPROTECTED_READ is the preferred way to annotate racey reads. + + Instead of doing + ANNOTATE_IGNORE_READS_BEGIN(); + ... = x; + ANNOTATE_IGNORE_READS_END(); + one can use + ... = ANNOTATE_UNPROTECTED_READ(x); */ +#if defined(__cplusplus) && defined(ANNOTATIONS_ENABLED) +template +inline T ANNOTATE_UNPROTECTED_READ(const volatile T &x) { /* NOLINT */ + ANNOTATE_IGNORE_READS_BEGIN(); + T res = x; + ANNOTATE_IGNORE_READS_END(); + return res; + } +#else + #define ANNOTATE_UNPROTECTED_READ(x) (x) +#endif + +#if DYNAMIC_ANNOTATIONS_ENABLED != 0 && defined(__cplusplus) + /* Apply ANNOTATE_BENIGN_RACE_SIZED to a static variable. */ + #define ANNOTATE_BENIGN_RACE_STATIC(static_var, description) \ + namespace { \ + class static_var ## _annotator { \ + public: \ + static_var ## _annotator() { \ + ANNOTATE_BENIGN_RACE_SIZED(&static_var, \ + sizeof(static_var), \ + # static_var ": " description); \ + } \ + }; \ + static static_var ## _annotator the ## static_var ## _annotator;\ + } // namespace +#else /* DYNAMIC_ANNOTATIONS_ENABLED == 0 */ + #define ANNOTATE_BENIGN_RACE_STATIC(static_var, description) /* empty */ +#endif /* DYNAMIC_ANNOTATIONS_ENABLED */ + +#ifdef ADDRESS_SANITIZER +/* Describe the current state of a contiguous container such as e.g. + * std::vector or std::string. For more details see + * sanitizer/common_interface_defs.h, which is provided by the compiler. */ +#include +#define ANNOTATE_CONTIGUOUS_CONTAINER(beg, end, old_mid, new_mid) \ + __sanitizer_annotate_contiguous_container(beg, end, old_mid, new_mid) +#define ADDRESS_SANITIZER_REDZONE(name) \ + struct { char x[8] __attribute__ ((aligned (8))); } name +#else +#define ANNOTATE_CONTIGUOUS_CONTAINER(beg, end, old_mid, new_mid) +#define ADDRESS_SANITIZER_REDZONE(name) +#endif // ADDRESS_SANITIZER + +/* Undefine the macros intended only in this file. */ +#undef ANNOTALYSIS_ENABLED +#undef ANNOTATIONS_ENABLED +#undef ATTRIBUTE_IGNORE_READS_BEGIN +#undef ATTRIBUTE_IGNORE_READS_END + +#endif /* !__native_client__ */ + +#endif /* ABSL_BASE_DYNAMIC_ANNOTATIONS_H_ */ diff --git a/Firestore/third_party/abseil-cpp/absl/base/internal/atomic_hook.h b/Firestore/third_party/abseil-cpp/absl/base/internal/atomic_hook.h new file mode 100644 index 0000000..47d4013 --- /dev/null +++ b/Firestore/third_party/abseil-cpp/absl/base/internal/atomic_hook.h @@ -0,0 +1,150 @@ +// Copyright 2017 The Abseil Authors. +// +// 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. +// + +#ifndef ABSL_BASE_INTERNAL_ATOMIC_HOOK_H_ +#define ABSL_BASE_INTERNAL_ATOMIC_HOOK_H_ + +#include +#include +#include +#include + +namespace absl { +namespace base_internal { + +template +class AtomicHook; + +// AtomicHook is a helper class, templatized on a raw function pointer type, for +// implementing Abseil customization hooks. It is a callable object that +// dispatches to the registered hook, or performs a no-op (and returns a default +// constructed object) if no hook has been registered. +// +// Reads and writes guarantee memory_order_acquire/memory_order_release +// semantics. +template +class AtomicHook { + public: + using FnPtr = ReturnType (*)(Args...); + + constexpr AtomicHook() : hook_(kInitialValue) {} + + // Stores the provided function pointer as the value for this hook. + // + // This is intended to be called once. Multiple calls are legal only if the + // same function pointer is provided for each call. The store is implemented + // as a memory_order_release operation, and read accesses are implemented as + // memory_order_acquire. + void Store(FnPtr fn) { + bool success = DoStore(fn); + static_cast(success); + assert(success); + } + + // Invokes the registered callback. If no callback has yet been registered, a + // default-constructed object of the appropriate type is returned instead. + template + ReturnType operator()(CallArgs&&... args) const { + return DoLoad()(std::forward(args)...); + } + + // Returns the registered callback, or nullptr if none has been registered. + // Useful if client code needs to conditionalize behavior based on whether a + // callback was registered. + // + // Note that atomic_hook.Load()() and atomic_hook() have different semantics: + // operator()() will perform a no-op if no callback was registered, while + // Load()() will dereference a null function pointer. Prefer operator()() to + // Load()() unless you must conditionalize behavior on whether a hook was + // registered. + FnPtr Load() const { + FnPtr ptr = DoLoad(); + return (ptr == DummyFunction) ? nullptr : ptr; + } + + private: + static ReturnType DummyFunction(Args...) { + return ReturnType(); + } + + // Current versions of MSVC (as of September 2017) have a broken + // implementation of std::atomic: Its constructor attempts to do the + // equivalent of a reinterpret_cast in a constexpr context, which is not + // allowed. + // + // This causes an issue when building with LLVM under Windows. To avoid this, + // we use a less-efficient, intptr_t-based implementation on Windows. + +#ifdef _MSC_FULL_VER +#define ABSL_HAVE_WORKING_ATOMIC_POINTER 0 +#else +#define ABSL_HAVE_WORKING_ATOMIC_POINTER 1 +#endif + +#if ABSL_HAVE_WORKING_ATOMIC_POINTER + static constexpr FnPtr kInitialValue = &DummyFunction; + + // Return the stored value, or DummyFunction if no value has been stored. + FnPtr DoLoad() const { return hook_.load(std::memory_order_acquire); } + + // Store the given value. Returns false if a different value was already + // stored to this object. + bool DoStore(FnPtr fn) { + assert(fn); + FnPtr expected = DummyFunction; + hook_.compare_exchange_strong(expected, fn, std::memory_order_acq_rel, + std::memory_order_acquire); + const bool store_succeeded = (expected == DummyFunction); + const bool same_value_already_stored = (expected == fn); + return store_succeeded || same_value_already_stored; + } + + std::atomic hook_; +#else // !ABSL_HAVE_WORKING_ATOMIC_POINTER + // Use a sentinel value unlikely to be the address of an actual function. + static constexpr intptr_t kInitialValue = 0; + + static_assert(sizeof(intptr_t) >= sizeof(FnPtr), + "intptr_t can't contain a function pointer"); + + FnPtr DoLoad() const { + const intptr_t value = hook_.load(std::memory_order_acquire); + if (value == 0) { + return DummyFunction; + } + return reinterpret_cast(value); + } + + bool DoStore(FnPtr fn) { + assert(fn); + const auto value = reinterpret_cast(fn); + intptr_t expected = 0; + hook_.compare_exchange_strong(expected, value, std::memory_order_acq_rel, + std::memory_order_acquire); + const bool store_succeeded = (expected == 0); + const bool same_value_already_stored = (expected == value); + return store_succeeded || same_value_already_stored; + } + + std::atomic hook_; +#endif +}; + +#undef ABSL_HAVE_WORKING_ATOMIC_POINTER + +} // namespace base_internal +} // namespace absl + +#endif // ABSL_BASE_INTERNAL_ATOMIC_HOOK_H_ diff --git a/Firestore/third_party/abseil-cpp/absl/base/internal/log_severity.h b/Firestore/third_party/abseil-cpp/absl/base/internal/log_severity.h new file mode 100644 index 0000000..deaf6a5 --- /dev/null +++ b/Firestore/third_party/abseil-cpp/absl/base/internal/log_severity.h @@ -0,0 +1,52 @@ +// Copyright 2017 The Abseil Authors. +// +// 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. +// + +#ifndef ABSL_BASE_INTERNAL_LOG_SEVERITY_H_ +#define ABSL_BASE_INTERNAL_LOG_SEVERITY_H_ + +#include "absl/base/attributes.h" + +namespace absl { + +enum class LogSeverity : int { + kInfo = 0, + kWarning = 1, + kError = 2, + kFatal = 3, +}; + +constexpr const char* LogSeverityName(absl::LogSeverity s) { + return s == absl::LogSeverity::kInfo + ? "INFO" + : s == absl::LogSeverity::kWarning + ? "WARNING" + : s == absl::LogSeverity::kError + ? "ERROR" + : s == absl::LogSeverity::kFatal ? "FATAL" : "UNKNOWN"; +} + +// Note that out-of-range large severities normalize to kError, not kFatal. +constexpr absl::LogSeverity NormalizeLogSeverity(absl::LogSeverity s) { + return s < absl::LogSeverity::kInfo + ? absl::LogSeverity::kInfo + : s > absl::LogSeverity::kFatal ? absl::LogSeverity::kError : s; +} +constexpr absl::LogSeverity NormalizeLogSeverity(int s) { + return NormalizeLogSeverity(static_cast(s)); +} + +} // namespace absl + +#endif // ABSL_BASE_INTERNAL_LOG_SEVERITY_H_ diff --git a/Firestore/third_party/abseil-cpp/absl/base/internal/raw_logging.cc b/Firestore/third_party/abseil-cpp/absl/base/internal/raw_logging.cc new file mode 100644 index 0000000..1b849ab --- /dev/null +++ b/Firestore/third_party/abseil-cpp/absl/base/internal/raw_logging.cc @@ -0,0 +1,222 @@ +// Copyright 2017 The Abseil Authors. +// +// 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. + +#include "absl/base/internal/raw_logging.h" + +#include +#include +#include +#include +#include + +#include "absl/base/config.h" +#include "absl/base/internal/atomic_hook.h" +#include "absl/base/internal/log_severity.h" + +// We know how to perform low-level writes to stderr in POSIX and Windows. For +// these platforms, we define the token ABSL_LOW_LEVEL_WRITE_SUPPORTED. +// Much of raw_logging.cc becomes a no-op when we can't output messages, +// although a FATAL ABSL_RAW_LOG message will still abort the process. + +// ABSL_HAVE_POSIX_WRITE is defined when the platform provides posix write() +// (as from unistd.h) +// +// This preprocessor token is also defined in raw_io.cc. If you need to copy +// this, consider moving both to config.h instead. +#if defined(__linux__) || defined(__APPLE__) || defined(__Fuchsia__) +#include + + +#define ABSL_HAVE_POSIX_WRITE 1 +#define ABSL_LOW_LEVEL_WRITE_SUPPORTED 1 +#else +#undef ABSL_HAVE_POSIX_WRITE +#endif + +// ABSL_HAVE_SYSCALL_WRITE is defined when the platform provides the syscall +// syscall(SYS_write, /*int*/ fd, /*char* */ buf, /*size_t*/ len); +// for low level operations that want to avoid libc. +#if defined(__linux__) && !defined(__ANDROID__) +#include +#define ABSL_HAVE_SYSCALL_WRITE 1 +#define ABSL_LOW_LEVEL_WRITE_SUPPORTED 1 +#else +#undef ABSL_HAVE_SYSCALL_WRITE +#endif + +#ifdef _WIN32 +#include + +#define ABSL_HAVE_RAW_IO 1 +#define ABSL_LOW_LEVEL_WRITE_SUPPORTED 1 +#else +#undef ABSL_HAVE_RAW_IO +#endif + +// TODO(gfalcon): We want raw-logging to work on as many platforms as possible. +// Explicitly #error out when not ABSL_LOW_LEVEL_WRITE_SUPPORTED, except for a +// whitelisted set of platforms for which we expect not to be able to raw log. + +ABSL_CONST_INIT static absl::base_internal::AtomicHook< + absl::raw_logging_internal::LogPrefixHook> log_prefix_hook; +ABSL_CONST_INIT static absl::base_internal::AtomicHook< + absl::raw_logging_internal::AbortHook> abort_hook; + +#ifdef ABSL_LOW_LEVEL_WRITE_SUPPORTED +static const char kTruncated[] = " ... (message truncated)\n"; + +// sprintf the format to the buffer, adjusting *buf and *size to reflect the +// consumed bytes, and return whether the message fit without truncation. If +// truncation occurred, if possible leave room in the buffer for the message +// kTruncated[]. +inline static bool VADoRawLog(char** buf, int* size, + const char* format, va_list ap) { + int n = vsnprintf(*buf, *size, format, ap); + bool result = true; + if (n < 0 || n > *size) { + result = false; + if (static_cast(*size) > sizeof(kTruncated)) { + n = *size - sizeof(kTruncated); // room for truncation message + } else { + n = 0; // no room for truncation message + } + } + *size -= n; + *buf += n; + return result; +} +#endif // ABSL_LOW_LEVEL_WRITE_SUPPORTED + +static constexpr int kLogBufSize = 3000; + +namespace absl { +namespace raw_logging_internal { +void SafeWriteToStderr(const char *s, size_t len); +} // namespace raw_logging_internal +} // namespace absl + +namespace { + +// CAVEAT: vsnprintf called from *DoRawLog below has some (exotic) code paths +// that invoke malloc() and getenv() that might acquire some locks. + +// Helper for RawLog below. +// *DoRawLog writes to *buf of *size and move them past the written portion. +// It returns true iff there was no overflow or error. +bool DoRawLog(char** buf, int* size, const char* format, ...) + ABSL_PRINTF_ATTRIBUTE(3, 4); +bool DoRawLog(char** buf, int* size, const char* format, ...) { + va_list ap; + va_start(ap, format); + int n = vsnprintf(*buf, *size, format, ap); + va_end(ap); + if (n < 0 || n > *size) return false; + *size -= n; + *buf += n; + return true; +} + +void RawLogVA(absl::LogSeverity severity, const char* file, int line, + const char* format, va_list ap) { + char buffer[kLogBufSize]; + char* buf = buffer; + int size = sizeof(buffer); +#ifdef ABSL_LOW_LEVEL_WRITE_SUPPORTED + bool enabled = true; +#else + bool enabled = false; +#endif + +#ifdef ABSL_MIN_LOG_LEVEL + if (static_cast(severity) < ABSL_MIN_LOG_LEVEL && + severity < absl::LogSeverity::kFatal) { + enabled = false; + } +#endif + + auto log_prefix_hook_ptr = log_prefix_hook.Load(); + if (log_prefix_hook_ptr) { + enabled = log_prefix_hook_ptr(severity, file, line, &buf, &size); + } else { + if (enabled) { + DoRawLog(&buf, &size, "[%s : %d] RAW: ", file, line); + } + } + const char* const prefix_end = buf; + +#ifdef ABSL_LOW_LEVEL_WRITE_SUPPORTED + if (enabled) { + bool no_chop = VADoRawLog(&buf, &size, format, ap); + if (no_chop) { + DoRawLog(&buf, &size, "\n"); + } else { + DoRawLog(&buf, &size, "%s", kTruncated); + } + absl::raw_logging_internal::SafeWriteToStderr(buffer, strlen(buffer)); + } +#else + static_cast(format); + static_cast(ap); +#endif + + // Abort the process after logging a FATAL message, even if the output itself + // was suppressed. + if (severity == absl::LogSeverity::kFatal) { + abort_hook(file, line, buffer, prefix_end, buffer + kLogBufSize); + abort(); + } +} + +} // namespace + +namespace absl { +namespace raw_logging_internal { + +// Writes the provided buffer directly to stderr, in a safe, low-level manner. +// +// In POSIX this means calling write(), which is async-signal safe and does +// not malloc. If the platform supports the SYS_write syscall, we invoke that +// directly to side-step any libc interception. +void SafeWriteToStderr(const char *s, size_t len) { +#if defined(ABSL_HAVE_SYSCALL_WRITE) + syscall(SYS_write, STDERR_FILENO, s, len); +#elif defined(ABSL_HAVE_POSIX_WRITE) + write(STDERR_FILENO, s, len); +#elif defined(ABSL_HAVE_RAW_IO) + _write(/* stderr */ 2, s, len); +#else + // stderr logging unsupported on this platform + (void) s; + (void) len; +#endif +} + +void RawLog(absl::LogSeverity severity, const char* file, int line, + const char* format, ...) { + va_list ap; + va_start(ap, format); + RawLogVA(severity, file, line, format, ap); + va_end(ap); +} + +bool RawLoggingFullySupported() { +#ifdef ABSL_LOW_LEVEL_WRITE_SUPPORTED + return true; +#else // !ABSL_LOW_LEVEL_WRITE_SUPPORTED + return false; +#endif // !ABSL_LOW_LEVEL_WRITE_SUPPORTED +} + +} // namespace raw_logging_internal +} // namespace absl diff --git a/Firestore/third_party/abseil-cpp/absl/base/internal/raw_logging.h b/Firestore/third_party/abseil-cpp/absl/base/internal/raw_logging.h new file mode 100644 index 0000000..568d2af --- /dev/null +++ b/Firestore/third_party/abseil-cpp/absl/base/internal/raw_logging.h @@ -0,0 +1,130 @@ +// Copyright 2017 The Abseil Authors. +// +// 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. +// +// Thread-safe logging routines that do not allocate any memory or +// acquire any locks, and can therefore be used by low-level memory +// allocation, synchronization, and signal-handling code. + +#ifndef ABSL_BASE_INTERNAL_RAW_LOGGING_H_ +#define ABSL_BASE_INTERNAL_RAW_LOGGING_H_ + +#include "absl/base/attributes.h" +#include "absl/base/internal/log_severity.h" +#include "absl/base/macros.h" +#include "absl/base/port.h" + +// This is similar to LOG(severity) << format..., but +// * it is to be used ONLY by low-level modules that can't use normal LOG() +// * it is designed to be a low-level logger that does not allocate any +// memory and does not need any locks, hence: +// * it logs straight and ONLY to STDERR w/o buffering +// * it uses an explicit printf-format and arguments list +// * it will silently chop off really long message strings +// Usage example: +// ABSL_RAW_LOG(ERROR, "Failed foo with %i: %s", status, error); +// This will print an almost standard log line like this to stderr only: +// E0821 211317 file.cc:123] RAW: Failed foo with 22: bad_file +#define ABSL_RAW_LOG(severity, ...) \ + do { \ + constexpr const char* absl_raw_logging_internal_basename = \ + ::absl::raw_logging_internal::Basename(__FILE__, \ + sizeof(__FILE__) - 1); \ + ::absl::raw_logging_internal::RawLog(ABSL_RAW_LOGGING_INTERNAL_##severity, \ + absl_raw_logging_internal_basename, \ + __LINE__, __VA_ARGS__); \ + } while (0) + +// Similar to CHECK(condition) << message, but for low-level modules: +// we use only ABSL_RAW_LOG that does not allocate memory. +// We do not want to provide args list here to encourage this usage: +// if (!cond) ABSL_RAW_LOG(FATAL, "foo ...", hard_to_compute_args); +// so that the args are not computed when not needed. +#define ABSL_RAW_CHECK(condition, message) \ + do { \ + if (ABSL_PREDICT_FALSE(!(condition))) { \ + ABSL_RAW_LOG(FATAL, "Check %s failed: %s", #condition, message); \ + } \ + } while (0) + +#define ABSL_RAW_LOGGING_INTERNAL_INFO ::absl::LogSeverity::kInfo +#define ABSL_RAW_LOGGING_INTERNAL_WARNING ::absl::LogSeverity::kWarning +#define ABSL_RAW_LOGGING_INTERNAL_ERROR ::absl::LogSeverity::kError +#define ABSL_RAW_LOGGING_INTERNAL_FATAL ::absl::LogSeverity::kFatal +#define ABSL_RAW_LOGGING_INTERNAL_LEVEL(severity) \ + ::absl::NormalizeLogSeverity(severity) + +namespace absl { +namespace raw_logging_internal { + +// Helper function to implement ABSL_RAW_LOG +// Logs format... at "severity" level, reporting it +// as called from file:line. +// This does not allocate memory or acquire locks. +void RawLog(absl::LogSeverity severity, const char* file, int line, + const char* format, ...) ABSL_PRINTF_ATTRIBUTE(4, 5); + +// compile-time function to get the "base" filename, that is, the part of +// a filename after the last "/" or "\" path separator. The search starts at +// the end of the std::string; the second parameter is the length of the std::string. +constexpr const char* Basename(const char* fname, int offset) { + return offset == 0 || fname[offset - 1] == '/' || fname[offset - 1] == '\\' + ? fname + offset + : Basename(fname, offset - 1); +} + +// For testing only. +// Returns true if raw logging is fully supported. When it is not +// fully supported, no messages will be emitted, but a log at FATAL +// severity will cause an abort. +// +// TODO(gfalcon): Come up with a better name for this method. +bool RawLoggingFullySupported(); + +// Function type for a raw_logging customization hook for suppressing messages +// by severity, and for writing custom prefixes on non-suppressed messages. +// +// The installed hook is called for every raw log invocation. The message will +// be logged to stderr only if the hook returns true. FATAL errors will cause +// the process to abort, even if writing to stderr is suppressed. The hook is +// also provided with an output buffer, where it can write a custom log message +// prefix. +// +// The raw_logging system does not allocate memory or grab locks. User-provided +// hooks must avoid these operations, and must not throw exceptions. +// +// 'severity' is the severity level of the message being written. +// 'file' and 'line' are the file and line number where the ABSL_RAW_LOG macro +// was located. +// 'buffer' and 'buf_size' are pointers to the buffer and buffer size. If the +// hook writes a prefix, it must increment *buffer and decrement *buf_size +// accordingly. +using LogPrefixHook = bool (*)(absl::LogSeverity severity, const char* file, + int line, char** buffer, int* buf_size); + +// Function type for a raw_logging customization hook called to abort a process +// when a FATAL message is logged. If the provided AbortHook() returns, the +// logging system will call abort(). +// +// 'file' and 'line' are the file and line number where the ABSL_RAW_LOG macro +// was located. +// The null-terminated logged message lives in the buffer between 'buf_start' +// and 'buf_end'. 'prefix_end' points to the first non-prefix character of the +// buffer (as written by the LogPrefixHook.) +using AbortHook = void (*)(const char* file, int line, const char* buf_start, + const char* prefix_end, const char* buf_end); + +} // namespace raw_logging_internal +} // namespace absl + +#endif // ABSL_BASE_INTERNAL_RAW_LOGGING_H_ diff --git a/Firestore/third_party/abseil-cpp/absl/base/internal/throw_delegate.cc b/Firestore/third_party/abseil-cpp/absl/base/internal/throw_delegate.cc new file mode 100644 index 0000000..46dc573 --- /dev/null +++ b/Firestore/third_party/abseil-cpp/absl/base/internal/throw_delegate.cc @@ -0,0 +1,106 @@ +// Copyright 2017 The Abseil Authors. +// +// 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. + +#include "absl/base/internal/throw_delegate.h" + +#include +#include +#include +#include +#include "absl/base/config.h" +#include "absl/base/internal/raw_logging.h" + +namespace absl { +namespace base_internal { + +namespace { +template +[[noreturn]] void Throw(const T& error) { +#ifdef ABSL_HAVE_EXCEPTIONS + throw error; +#else + ABSL_RAW_LOG(ERROR, "%s", error.what()); + abort(); +#endif +} +} // namespace + +void ThrowStdLogicError(const std::string& what_arg) { + Throw(std::logic_error(what_arg)); +} +void ThrowStdLogicError(const char* what_arg) { + Throw(std::logic_error(what_arg)); +} +void ThrowStdInvalidArgument(const std::string& what_arg) { + Throw(std::invalid_argument(what_arg)); +} +void ThrowStdInvalidArgument(const char* what_arg) { + Throw(std::invalid_argument(what_arg)); +} + +void ThrowStdDomainError(const std::string& what_arg) { + Throw(std::domain_error(what_arg)); +} +void ThrowStdDomainError(const char* what_arg) { + Throw(std::domain_error(what_arg)); +} + +void ThrowStdLengthError(const std::string& what_arg) { + Throw(std::length_error(what_arg)); +} +void ThrowStdLengthError(const char* what_arg) { + Throw(std::length_error(what_arg)); +} + +void ThrowStdOutOfRange(const std::string& what_arg) { + Throw(std::out_of_range(what_arg)); +} +void ThrowStdOutOfRange(const char* what_arg) { + Throw(std::out_of_range(what_arg)); +} + +void ThrowStdRuntimeError(const std::string& what_arg) { + Throw(std::runtime_error(what_arg)); +} +void ThrowStdRuntimeError(const char* what_arg) { + Throw(std::runtime_error(what_arg)); +} + +void ThrowStdRangeError(const std::string& what_arg) { + Throw(std::range_error(what_arg)); +} +void ThrowStdRangeError(const char* what_arg) { + Throw(std::range_error(what_arg)); +} + +void ThrowStdOverflowError(const std::string& what_arg) { + Throw(std::overflow_error(what_arg)); +} +void ThrowStdOverflowError(const char* what_arg) { + Throw(std::overflow_error(what_arg)); +} + +void ThrowStdUnderflowError(const std::string& what_arg) { + Throw(std::underflow_error(what_arg)); +} +void ThrowStdUnderflowError(const char* what_arg) { + Throw(std::underflow_error(what_arg)); +} + +void ThrowStdBadFunctionCall() { Throw(std::bad_function_call()); } + +void ThrowStdBadAlloc() { Throw(std::bad_alloc()); } + +} // namespace base_internal +} // namespace absl diff --git a/Firestore/third_party/abseil-cpp/absl/base/internal/throw_delegate.h b/Firestore/third_party/abseil-cpp/absl/base/internal/throw_delegate.h new file mode 100644 index 0000000..70e2d77 --- /dev/null +++ b/Firestore/third_party/abseil-cpp/absl/base/internal/throw_delegate.h @@ -0,0 +1,71 @@ +// +// Copyright 2017 The Abseil Authors. +// +// 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. +// + +#ifndef ABSL_BASE_INTERNAL_THROW_DELEGATE_H_ +#define ABSL_BASE_INTERNAL_THROW_DELEGATE_H_ + +#include + +namespace absl { +namespace base_internal { + +// Helper functions that allow throwing exceptions consistently from anywhere. +// The main use case is for header-based libraries (eg templates), as they will +// be built by many different targets with their own compiler options. +// In particular, this will allow a safe way to throw exceptions even if the +// caller is compiled with -fno-exceptions. This is intended for implementing +// things like map<>::at(), which the standard documents as throwing an +// exception on error. +// +// Using other techniques like #if tricks could lead to ODR violations. +// +// You shouldn't use it unless you're writing code that you know will be built +// both with and without exceptions and you need to conform to an interface +// that uses exceptions. + +[[noreturn]] void ThrowStdLogicError(const std::string& what_arg); +[[noreturn]] void ThrowStdLogicError(const char* what_arg); +[[noreturn]] void ThrowStdInvalidArgument(const std::string& what_arg); +[[noreturn]] void ThrowStdInvalidArgument(const char* what_arg); +[[noreturn]] void ThrowStdDomainError(const std::string& what_arg); +[[noreturn]] void ThrowStdDomainError(const char* what_arg); +[[noreturn]] void ThrowStdLengthError(const std::string& what_arg); +[[noreturn]] void ThrowStdLengthError(const char* what_arg); +[[noreturn]] void ThrowStdOutOfRange(const std::string& what_arg); +[[noreturn]] void ThrowStdOutOfRange(const char* what_arg); +[[noreturn]] void ThrowStdRuntimeError(const std::string& what_arg); +[[noreturn]] void ThrowStdRuntimeError(const char* what_arg); +[[noreturn]] void ThrowStdRangeError(const std::string& what_arg); +[[noreturn]] void ThrowStdRangeError(const char* what_arg); +[[noreturn]] void ThrowStdOverflowError(const std::string& what_arg); +[[noreturn]] void ThrowStdOverflowError(const char* what_arg); +[[noreturn]] void ThrowStdUnderflowError(const std::string& what_arg); +[[noreturn]] void ThrowStdUnderflowError(const char* what_arg); + +[[noreturn]] void ThrowStdBadFunctionCall(); +[[noreturn]] void ThrowStdBadAlloc(); + +// ThrowStdBadArrayNewLength() cannot be consistently supported because +// std::bad_array_new_length is missing in libstdc++ until 4.9.0. +// https://gcc.gnu.org/onlinedocs/gcc-4.8.3/libstdc++/api/a01379_source.html +// https://gcc.gnu.org/onlinedocs/gcc-4.9.0/libstdc++/api/a01327_source.html +// libcxx (as of 3.2) and msvc (as of 2015) both have it. +// [[noreturn]] void ThrowStdBadArrayNewLength(); + +} // namespace base_internal +} // namespace absl + +#endif // ABSL_BASE_INTERNAL_THROW_DELEGATE_H_ diff --git a/Firestore/third_party/abseil-cpp/absl/base/macros.h b/Firestore/third_party/abseil-cpp/absl/base/macros.h new file mode 100644 index 0000000..d414087 --- /dev/null +++ b/Firestore/third_party/abseil-cpp/absl/base/macros.h @@ -0,0 +1,202 @@ +// +// Copyright 2017 The Abseil Authors. +// +// 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. +// +// ----------------------------------------------------------------------------- +// File: macros.h +// ----------------------------------------------------------------------------- +// +// This header file defines the set of language macros used within Abseil code. +// For the set of macros used to determine supported compilers and platforms, +// see absl/base/config.h instead. +// +// This code is compiled directly on many platforms, including client +// platforms like Windows, Mac, and embedded systems. Before making +// any changes here, make sure that you're not breaking any platforms. +// + +#ifndef ABSL_BASE_MACROS_H_ +#define ABSL_BASE_MACROS_H_ + +#include +#include + +#include "absl/base/port.h" + +// ABSL_ARRAYSIZE() +// +// Returns the # of elements in an array as a compile-time constant, which can +// be used in defining new arrays. If you use this macro on a pointer by +// mistake, you will get a compile-time error. +// +// Note: this template function declaration is used in defining arraysize. +// Note that the function doesn't need an implementation, as we only +// use its type. +namespace absl { +namespace macros_internal { +template +char (&ArraySizeHelper(T (&array)[N]))[N]; +} // namespace macros_internal +} // namespace absl +#define ABSL_ARRAYSIZE(array) \ + (sizeof(::absl::macros_internal::ArraySizeHelper(array))) + +// kLinkerInitialized +// +// An enum used only as a constructor argument to indicate that a variable has +// static storage duration, and that the constructor should do nothing to its +// state. Use of this macro indicates to the reader that it is legal to +// declare a static instance of the class, provided the constructor is given +// the absl::base_internal::kLinkerInitialized argument. +// +// Normally, it is unsafe to declare a static variable that has a constructor or +// a destructor because invocation order is undefined. However, if the type can +// be zero-initialized (which the loader does for static variables) into a valid +// state and the type's destructor does not affect storage, then a constructor +// for static initialization can be declared. +// +// Example: +// // Declaration +// explicit MyClass(absl::base_internal:LinkerInitialized x) {} +// +// // Invocation +// static MyClass my_global(absl::base_internal::kLinkerInitialized); +namespace absl { +namespace base_internal { +enum LinkerInitialized { + kLinkerInitialized = 0, +}; +} // namespace base_internal +} // namespace absl + +// ABSL_FALLTHROUGH_INTENDED +// +// Annotates implicit fall-through between switch labels, allowing a case to +// indicate intentional fallthrough and turn off warnings about any lack of a +// `break` statement. The ABSL_FALLTHROUGH_INTENDED macro should be followed by +// a semicolon and can be used in most places where `break` can, provided that +// no statements exist between it and the next switch label. +// +// Example: +// +// switch (x) { +// case 40: +// case 41: +// if (truth_is_out_there) { +// ++x; +// ABSL_FALLTHROUGH_INTENDED; // Use instead of/along with annotations +// // in comments +// } else { +// return x; +// } +// case 42: +// ... +// +// Notes: when compiled with clang in C++11 mode, the ABSL_FALLTHROUGH_INTENDED +// macro is expanded to the [[clang::fallthrough]] attribute, which is analysed +// when performing switch labels fall-through diagnostic +// (`-Wimplicit-fallthrough`). See clang documentation on language extensions +// for details: +// http://clang.llvm.org/docs/AttributeReference.html#fallthrough-clang-fallthrough +// +// When used with unsupported compilers, the ABSL_FALLTHROUGH_INTENDED macro +// has no effect on diagnostics. In any case this macro has no effect on runtime +// behavior and performance of code. +#ifdef ABSL_FALLTHROUGH_INTENDED +#error "ABSL_FALLTHROUGH_INTENDED should not be defined." +#endif + +// TODO(zhangxy): Use c++17 standard [[fallthrough]] macro, when supported. +#if defined(__clang__) && defined(__has_warning) +#if __has_feature(cxx_attributes) && __has_warning("-Wimplicit-fallthrough") +#define ABSL_FALLTHROUGH_INTENDED [[clang::fallthrough]] +#endif +#elif defined(__GNUC__) && __GNUC__ >= 7 +#define ABSL_FALLTHROUGH_INTENDED [[gnu::fallthrough]] +#endif + +#ifndef ABSL_FALLTHROUGH_INTENDED +#define ABSL_FALLTHROUGH_INTENDED \ + do { \ + } while (0) +#endif + +// ABSL_DEPRECATED() +// +// Marks a deprecated class, struct, enum, function, method and variable +// declarations. The macro argument is used as a custom diagnostic message (e.g. +// suggestion of a better alternative). +// +// Example: +// +// class ABSL_DEPRECATED("Use Bar instead") Foo {...}; +// ABSL_DEPRECATED("Use Baz instead") void Bar() {...} +// +// Every usage of a deprecated entity will trigger a warning when compiled with +// clang's `-Wdeprecated-declarations` option. This option is turned off by +// default, but the warnings will be reported by clang-tidy. +#if defined(__clang__) && __cplusplus >= 201103L && defined(__has_warning) +#define ABSL_DEPRECATED(message) __attribute__((deprecated(message))) +#endif + +#ifndef ABSL_DEPRECATED +#define ABSL_DEPRECATED(message) +#endif + +// ABSL_BAD_CALL_IF() +// +// Used on a function overload to trap bad calls: any call that matches the +// overload will cause a compile-time error. This macro uses a clang-specific +// "enable_if" attribute, as described at +// http://clang.llvm.org/docs/AttributeReference.html#enable-if +// +// Overloads which use this macro should be bracketed by +// `#ifdef ABSL_BAD_CALL_IF`. +// +// Example: +// +// int isdigit(int c); +// #ifdef ABSL_BAD_CALL_IF +// int isdigit(int c) +// ABSL_BAD_CALL_IF(c <= -1 || c > 255, +// "'c' must have the value of an unsigned char or EOF"); +// #endif // ABSL_BAD_CALL_IF + +#if defined(__clang__) +# if __has_attribute(enable_if) +# define ABSL_BAD_CALL_IF(expr, msg) \ + __attribute__((enable_if(expr, "Bad call trap"), unavailable(msg))) +# endif +#endif + +// ABSL_ASSERT() +// +// In C++11, `assert` can't be used portably within constexpr functions. +// ABSL_ASSERT functions as a runtime assert but works in C++11 constexpr +// functions. Example: +// +// constexpr double Divide(double a, double b) { +// return ABSL_ASSERT(b != 0), a / b; +// } +// +// This macro is inspired by +// https://akrzemi1.wordpress.com/2017/05/18/asserts-in-constexpr-functions/ +#if defined(NDEBUG) +#define ABSL_ASSERT(expr) (false ? (void)(expr) : (void)0) +#else +#define ABSL_ASSERT(expr) \ + (ABSL_PREDICT_TRUE((expr)) ? (void)0 : [] { assert(false && #expr); }()) +#endif + +#endif // ABSL_BASE_MACROS_H_ diff --git a/Firestore/third_party/abseil-cpp/absl/base/optimization.h b/Firestore/third_party/abseil-cpp/absl/base/optimization.h new file mode 100644 index 0000000..aaaffa4 --- /dev/null +++ b/Firestore/third_party/abseil-cpp/absl/base/optimization.h @@ -0,0 +1,165 @@ +// +// Copyright 2017 The Abseil Authors. +// +// 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. +// +// ----------------------------------------------------------------------------- +// File: optimization.h +// ----------------------------------------------------------------------------- +// +// This header file defines portable macros for performance optimization. + +#ifndef ABSL_BASE_OPTIMIZATION_H_ +#define ABSL_BASE_OPTIMIZATION_H_ + +#include "absl/base/config.h" + +// ABSL_BLOCK_TAIL_CALL_OPTIMIZATION +// +// Instructs the compiler to avoid optimizing tail-call recursion. Use of this +// macro is useful when you wish to preserve the existing function order within +// a stack trace for logging, debugging, or profiling purposes. +// +// Example: +// +// int f() { +// int result = g(); +// ABSL_BLOCK_TAIL_CALL_OPTIMIZATION(); +// return result; +// } +#if defined(__pnacl__) +#define ABSL_BLOCK_TAIL_CALL_OPTIMIZATION() if (volatile int x = 0) { (void)x; } +#elif defined(__clang__) +// Clang will not tail call given inline volatile assembly. +#define ABSL_BLOCK_TAIL_CALL_OPTIMIZATION() __asm__ __volatile__("") +#elif defined(__GNUC__) +// GCC will not tail call given inline volatile assembly. +#define ABSL_BLOCK_TAIL_CALL_OPTIMIZATION() __asm__ __volatile__("") +#elif defined(_MSC_VER) +#include +// The __nop() intrinsic blocks the optimisation. +#define ABSL_BLOCK_TAIL_CALL_OPTIMIZATION() __nop() +#else +#define ABSL_BLOCK_TAIL_CALL_OPTIMIZATION() if (volatile int x = 0) { (void)x; } +#endif + +// ABSL_CACHELINE_SIZE +// +// Explicitly defines the size of the L1 cache for purposes of alignment. +// Setting the cacheline size allows you to specify that certain objects be +// aligned on a cacheline boundary with `ABSL_CACHELINE_ALIGNED` declarations. +// (See below.) +// +// NOTE: this macro should be replaced with the following C++17 features, when +// those are generally available: +// +// * `std::hardware_constructive_interference_size` +// * `std::hardware_destructive_interference_size` +// +// See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0154r1.html +// for more information. +#if defined(__GNUC__) +// Cache line alignment +#if defined(__i386__) || defined(__x86_64__) +#define ABSL_CACHELINE_SIZE 64 +#elif defined(__powerpc64__) +#define ABSL_CACHELINE_SIZE 128 +#elif defined(__aarch64__) +// We would need to read special register ctr_el0 to find out L1 dcache size. +// This value is a good estimate based on a real aarch64 machine. +#define ABSL_CACHELINE_SIZE 64 +#elif defined(__arm__) +// Cache line sizes for ARM: These values are not strictly correct since +// cache line sizes depend on implementations, not architectures. There +// are even implementations with cache line sizes configurable at boot +// time. +#if defined(__ARM_ARCH_5T__) +#define ABSL_CACHELINE_SIZE 32 +#elif defined(__ARM_ARCH_7A__) +#define ABSL_CACHELINE_SIZE 64 +#endif +#endif + +#ifndef ABSL_CACHELINE_SIZE +// A reasonable default guess. Note that overestimates tend to waste more +// space, while underestimates tend to waste more time. +#define ABSL_CACHELINE_SIZE 64 +#endif + +// ABSL_CACHELINE_ALIGNED +// +// Indicates that the declared object be cache aligned using +// `ABSL_CACHELINE_SIZE` (see above). Cacheline aligning objects allows you to +// load a set of related objects in the L1 cache for performance improvements. +// Cacheline aligning objects properly allows constructive memory sharing and +// prevents destructive (or "false") memory sharing. +// +// NOTE: this macro should be replaced with usage of `alignas()` using +// `std::hardware_constructive_interference_size` and/or +// `std::hardware_destructive_interference_size` when available within C++17. +// +// See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0154r1.html +// for more information. +// +// On some compilers, `ABSL_CACHELINE_ALIGNED` expands to +// `__attribute__((aligned(ABSL_CACHELINE_SIZE)))`. For compilers where this is +// not known to work, the macro expands to nothing. +// +// No further guarantees are made here. The result of applying the macro +// to variables and types is always implementation-defined. +// +// WARNING: It is easy to use this attribute incorrectly, even to the point +// of causing bugs that are difficult to diagnose, crash, etc. It does not +// of itself guarantee that objects are aligned to a cache line. +// +// Recommendations: +// +// 1) Consult compiler documentation; this comment is not kept in sync as +// toolchains evolve. +// 2) Verify your use has the intended effect. This often requires inspecting +// the generated machine code. +// 3) Prefer applying this attribute to individual variables. Avoid +// applying it to types. This tends to localize the effect. +#define ABSL_CACHELINE_ALIGNED __attribute__((aligned(ABSL_CACHELINE_SIZE))) + +#else // not GCC +#define ABSL_CACHELINE_SIZE 64 +#define ABSL_CACHELINE_ALIGNED +#endif + +// ABSL_PREDICT_TRUE, ABSL_PREDICT_FALSE +// +// Enables the compiler to prioritize compilation using static analysis for +// likely paths within a boolean branch. +// +// Example: +// +// if (ABSL_PREDICT_TRUE(expression)) { +// return result; // Faster if more likely +// } else { +// return 0; +// } +// +// Compilers can use the information that a certain branch is not likely to be +// taken (for instance, a CHECK failure) to optimize for the common case in +// the absence of better information (ie. compiling gcc with `-fprofile-arcs`). +#if ABSL_HAVE_BUILTIN(__builtin_expect) || \ + (defined(__GNUC__) && !defined(__clang__)) +#define ABSL_PREDICT_FALSE(x) (__builtin_expect(x, 0)) +#define ABSL_PREDICT_TRUE(x) (__builtin_expect(!!(x), 1)) +#else +#define ABSL_PREDICT_FALSE(x) x +#define ABSL_PREDICT_TRUE(x) x +#endif + +#endif // ABSL_BASE_OPTIMIZATION_H_ diff --git a/Firestore/third_party/abseil-cpp/absl/base/policy_checks.h b/Firestore/third_party/abseil-cpp/absl/base/policy_checks.h new file mode 100644 index 0000000..17c05c1 --- /dev/null +++ b/Firestore/third_party/abseil-cpp/absl/base/policy_checks.h @@ -0,0 +1,99 @@ +// Copyright 2017 The Abseil Authors. +// +// 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. +// +// ----------------------------------------------------------------------------- +// File: policy_checks.h +// ----------------------------------------------------------------------------- +// +// This header enforces a minimum set of policies at build time, such as the +// supported compiler and library versions. Unsupported configurations are +// reported with `#error`. This enforcement is best effort, so successfully +// compiling this header does not guarantee a supported configuration. + +#ifndef ABSL_BASE_POLICY_CHECKS_H_ +#define ABSL_BASE_POLICY_CHECKS_H_ + +// Included for the __GLIBC_PREREQ macro used below. +#include + +// Included for the _STLPORT_VERSION macro used below. +#if defined(__cplusplus) +#include +#endif + +// ----------------------------------------------------------------------------- +// Operating System Check +// ----------------------------------------------------------------------------- + +#if defined(__CYGWIN__) +#error "Cygwin is not supported." +#endif + +// ----------------------------------------------------------------------------- +// Compiler Check +// ----------------------------------------------------------------------------- + +// We support MSVC++ 14.0 update 2 and later. +// This minimum will go up. +#if defined(_MSC_FULL_VER) && _MSC_FULL_VER < 190023918 +#error "This package requires Visual Studio 2015 Update 2 or higher" +#endif + +// We support gcc 4.7 and later. +// This minimum will go up. +#if defined(__GNUC__) && !defined(__clang__) +#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 7) +#error "This package requires gcc 4.7 or higher" +#endif +#endif + +// We support Apple Xcode clang 4.2.1 (version 421.11.65) and later. +// This corresponds to Apple Xcode version 4.5. +// This minimum will go up. +#if defined(__apple_build_version__) && __apple_build_version__ < 4211165 +#error "This package requires __apple_build_version__ of 4211165 or higher" +#endif + +// ----------------------------------------------------------------------------- +// C++ Version Check +// ----------------------------------------------------------------------------- + +// Enforce C++11 as the minimum. Note that Visual Studio has not +// advanced __cplusplus despite being good enough for our purposes, so +// so we exempt it from the check. +#if defined(__cplusplus) && !defined(_MSC_VER) +#if __cplusplus < 201103L +#error "C++ versions less than C++11 are not supported." +#endif +#endif + +// ----------------------------------------------------------------------------- +// Standard Library Check +// ----------------------------------------------------------------------------- + +// We have chosen glibc 2.12 as the minimum as it was tagged for release +// in May, 2010 and includes some functionality used in Google software +// (for instance pthread_setname_np): +// https://sourceware.org/ml/libc-alpha/2010-05/msg00000.html +#ifdef __GLIBC_PREREQ +#if !__GLIBC_PREREQ(2, 12) +#error "Minimum required version of glibc is 2.12." +#endif +#endif + +#if defined(_STLPORT_VERSION) +#error "STLPort is not supported." +#endif + +#endif // ABSL_BASE_POLICY_CHECKS_H_ diff --git a/Firestore/third_party/abseil-cpp/absl/base/port.h b/Firestore/third_party/abseil-cpp/absl/base/port.h new file mode 100644 index 0000000..1c67257 --- /dev/null +++ b/Firestore/third_party/abseil-cpp/absl/base/port.h @@ -0,0 +1,26 @@ +// Copyright 2017 The Abseil Authors. +// +// 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. +// +// This files is a forwarding header for other headers containing various +// portability macros and functions. +// This file is used for both C and C++! + +#ifndef ABSL_BASE_PORT_H_ +#define ABSL_BASE_PORT_H_ + +#include "absl/base/attributes.h" +#include "absl/base/config.h" +#include "absl/base/optimization.h" + +#endif // ABSL_BASE_PORT_H_ diff --git a/Firestore/third_party/abseil-cpp/absl/base/raw_logging_test.cc b/Firestore/third_party/abseil-cpp/absl/base/raw_logging_test.cc new file mode 100644 index 0000000..dae4b35 --- /dev/null +++ b/Firestore/third_party/abseil-cpp/absl/base/raw_logging_test.cc @@ -0,0 +1,50 @@ +// Copyright 2017 The Abseil Authors. +// +// 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. + +// This test serves primarily as a compilation test for base/raw_logging.h. +// Raw logging testing is covered by logging_unittest.cc, which is not as +// portable as this test. + +#include "absl/base/internal/raw_logging.h" + +#include "gtest/gtest.h" + +namespace { + +TEST(RawLoggingCompilationTest, Log) { + ABSL_RAW_LOG(INFO, "RAW INFO: %d", 1); + ABSL_RAW_LOG(ERROR, "RAW ERROR: %d", 1); +} + +TEST(RawLoggingCompilationTest, PassingCheck) { + ABSL_RAW_CHECK(true, "RAW CHECK"); +} + +// Not all platforms support output from raw log, so we don't verify any +// particular output for RAW check failures (expecting the empty std::string +// accomplishes this). This test is primarily a compilation test, but we +// are verifying process death when EXPECT_DEATH works for a platform. +const char kExpectedDeathOutput[] = ""; + +TEST(RawLoggingDeathTest, FailingCheck) { + EXPECT_DEATH_IF_SUPPORTED(ABSL_RAW_CHECK(1 == 0, "explanation"), + kExpectedDeathOutput); +} + +TEST(RawLoggingDeathTest, LogFatal) { + EXPECT_DEATH_IF_SUPPORTED(ABSL_RAW_LOG(FATAL, "my dog has fleas"), + kExpectedDeathOutput); +} + +} // namespace diff --git a/Firestore/third_party/abseil-cpp/absl/meta/CMakeLists.txt b/Firestore/third_party/abseil-cpp/absl/meta/CMakeLists.txt new file mode 100644 index 0000000..d56fced --- /dev/null +++ b/Firestore/third_party/abseil-cpp/absl/meta/CMakeLists.txt @@ -0,0 +1,49 @@ +# +# Copyright 2017 The Abseil Authors. +# +# 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. +# + +list(APPEND META_PUBLIC_HEADERS + "type_traits.h" +) + + +# +## TESTS +# + +# test type_traits_test +list(APPEND TYPE_TRAITS_TEST_SRC + "type_traits_test.cc" + ${META_PUBLIC_HEADERS} +) + +absl_header_library( + TARGET + absl_meta + EXPORT_NAME + meta + ) + +absl_test( + TARGET + type_traits_test + SOURCES + ${TYPE_TRAITS_TEST_SRC} + PUBLIC_LIBRARIES + ${TYPE_TRAITS_TEST_PUBLIC_LIBRARIES} absl::meta +) + + + diff --git a/Firestore/third_party/abseil-cpp/absl/meta/type_traits.h b/Firestore/third_party/abseil-cpp/absl/meta/type_traits.h new file mode 100644 index 0000000..6f7138c --- /dev/null +++ b/Firestore/third_party/abseil-cpp/absl/meta/type_traits.h @@ -0,0 +1,327 @@ +// +// Copyright 2017 The Abseil Authors. +// +// 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. +// +// ----------------------------------------------------------------------------- +// type_traits.h +// ----------------------------------------------------------------------------- +// +// This file contains C++11-compatible versions of standard API +// functions for determining the characteristics of types. Such traits can +// support type inference, classification, and transformation, as well as +// make it easier to write templates based on generic type behavior. +// +// See http://en.cppreference.com/w/cpp/header/type_traits +// +// WARNING: use of many of the constructs in this header will count as "complex +// template metaprogramming", so before proceeding, please carefully consider +// https://google.github.io/styleguide/cppguide.html#Template_metaprogramming +// +// WARNING: using template metaprogramming to detect or depend on API +// features is brittle and not guaranteed. Neither the standard library nor +// Abseil provides any guarantee that APIs are stable in the face of template +// metaprogramming. Use with caution. +#ifndef ABSL_META_TYPE_TRAITS_H_ +#define ABSL_META_TYPE_TRAITS_H_ + +#include +#include + +#include "absl/base/config.h" + +namespace absl { + +namespace type_traits_internal { +template +struct VoidTImpl { + using type = void; +}; + +// This trick to retrieve a default alignment is necessary for our +// implementation of aligned_storage_t to be consistent with any implementation +// of std::aligned_storage. +template > +struct default_alignment_of_aligned_storage; + +template +struct default_alignment_of_aligned_storage> { + static constexpr size_t value = Align; +}; + +} // namespace type_traits_internal + +// void_t() +// +// Ignores the type of any its arguments and returns `void`. In general, this +// metafunction allows you to create a general case that maps to `void` while +// allowing specializations that map to specific types. +// +// This metafunction is designed to be a drop-in replacement for the C++17 +// `std::void_t` metafunction. +// +// NOTE: `absl::void_t` does not use the standard-specified implementation so +// that it can remain compatibile with gcc < 5.1. This can introduce slightly +// different behavior, such as when ordering partial specializations. +template +using void_t = typename type_traits_internal::VoidTImpl::type; + +// conjunction +// +// Performs a compile-time logical AND operation on the passed types (which +// must have `::value` members convertible to `bool`. Short-circuits if it +// encounters any `false` members (and does not compare the `::value` members +// of any remaining arguments). +// +// This metafunction is designed to be a drop-in replacement for the C++17 +// `std::conjunction` metafunction. +template +struct conjunction; + +template +struct conjunction + : std::conditional, T>::type {}; + +template +struct conjunction : T {}; + +template <> +struct conjunction<> : std::true_type {}; + +// disjunction +// +// Performs a compile-time logical OR operation on the passed types (which +// must have `::value` members convertible to `bool`. Short-circuits if it +// encounters any `true` members (and does not compare the `::value` members +// of any remaining arguments). +// +// This metafunction is designed to be a drop-in replacement for the C++17 +// `std::disjunction` metafunction. +template +struct disjunction; + +template +struct disjunction : + std::conditional>::type {}; + +template +struct disjunction : T {}; + +template <> +struct disjunction<> : std::false_type {}; + +// negation +// +// Performs a compile-time logical NOT operation on the passed type (which +// must have `::value` members convertible to `bool`. +// +// This metafunction is designed to be a drop-in replacement for the C++17 +// `std::negation` metafunction. +template +struct negation : std::integral_constant {}; + +// is_trivially_destructible() +// +// Determines whether the passed type `T` is trivially destructable. +// +// This metafunction is designed to be a drop-in replacement for the C++11 +// `std::is_trivially_destructible()` metafunction for platforms that have +// incomplete C++11 support (such as libstdc++ 4.x). On any platforms that do +// fully support C++11, we check whether this yields the same result as the std +// implementation. +// +// NOTE: the extensions (__has_trivial_xxx) are implemented in gcc (version >= +// 4.3) and clang. Since we are supporting libstdc++ > 4.7, they should always +// be present. These extensions are documented at +// https://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html#Type-Traits. +template +struct is_trivially_destructible + : std::integral_constant::value> { +#ifdef ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE + static_assert(std::is_trivially_destructible::value == + is_trivially_destructible::value, + "Not compliant with std::is_trivially_destructible"); +#endif // ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE +}; + +// is_trivially_default_constructible() +// +// Determines whether the passed type `T` is trivially default constructible. +// +// This metafunction is designed to be a drop-in replacement for the C++11 +// `std::is_trivially_default_constructible()` metafunction for platforms that +// have incomplete C++11 support (such as libstdc++ 4.x). On any platforms that +// do fully support C++11, we check whether this yields the same result as the +// std implementation. +// +// NOTE: according to the C++ standard, Section: 20.15.4.3 [meta.unary.prop] +// "The predicate condition for a template specialization is_constructible shall be satisfied if and only if the following variable +// definition would be well-formed for some invented variable t: +// +// T t(declval()...); +// +// is_trivially_constructible additionally requires that the +// variable definition does not call any operation that is not trivial. +// For the purposes of this check, the call to std::declval is considered +// trivial." +// +// Notes from http://en.cppreference.com/w/cpp/types/is_constructible: +// In many implementations, is_nothrow_constructible also checks if the +// destructor throws because it is effectively noexcept(T(arg)). Same +// applies to is_trivially_constructible, which, in these implementations, also +// requires that the destructor is trivial. +// GCC bug 51452: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51452 +// LWG issue 2116: http://cplusplus.github.io/LWG/lwg-active.html#2116. +// +// "T obj();" need to be well-formed and not call any non-trivial operation. +// Nontrivally destructible types will cause the expression to be nontrivial. +template +struct is_trivially_default_constructible + : std::integral_constant::value && + is_trivially_destructible::value> { +#ifdef ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE + static_assert(std::is_trivially_default_constructible::value == + is_trivially_default_constructible::value, + "Not compliant with std::is_trivially_default_constructible"); +#endif // ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE +}; + +// is_trivially_copy_constructible() +// +// Determines whether the passed type `T` is trivially copy constructible. +// +// This metafunction is designed to be a drop-in replacement for the C++11 +// `std::is_trivially_copy_constructible()` metafunction for platforms that have +// incomplete C++11 support (such as libstdc++ 4.x). On any platforms that do +// fully support C++11, we check whether this yields the same result as the std +// implementation. +// +// NOTE: `T obj(declval());` needs to be well-formed and not call any +// nontrivial operation. Nontrivally destructible types will cause the +// expression to be nontrivial. +template +struct is_trivially_copy_constructible + : std::integral_constant::value && + is_trivially_destructible::value> { +#ifdef ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE + static_assert(std::is_trivially_copy_constructible::value == + is_trivially_copy_constructible::value, + "Not compliant with std::is_trivially_copy_constructible"); +#endif // ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE +}; + +// is_trivially_copy_assignable() +// +// Determines whether the passed type `T` is trivially copy assignable. +// +// This metafunction is designed to be a drop-in replacement for the C++11 +// `std::is_trivially_copy_assignable()` metafunction for platforms that have +// incomplete C++11 support (such as libstdc++ 4.x). On any platforms that do +// fully support C++11, we check whether this yields the same result as the std +// implementation. +// +// NOTE: `is_assignable::value` is `true` if the expression +// `declval() = declval()` is well-formed when treated as an unevaluated +// operand. `is_trivially_assignable` requires the assignment to call no +// operation that is not trivial. `is_trivially_copy_assignable` is simply +// `is_trivially_assignable`. +template +struct is_trivially_copy_assignable + : std::integral_constant::value> { +#ifdef ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE + static_assert(std::is_trivially_copy_assignable::value == + is_trivially_copy_assignable::value, + "Not compliant with std::is_trivially_copy_assignable"); +#endif // ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE +}; + +// ----------------------------------------------------------------------------- +// C++14 "_t" trait aliases +// ----------------------------------------------------------------------------- + +template +using remove_cv_t = typename std::remove_cv::type; + +template +using remove_const_t = typename std::remove_const::type; + +template +using remove_volatile_t = typename std::remove_volatile::type; + +template +using add_cv_t = typename std::add_cv::type; + +template +using add_const_t = typename std::add_const::type; + +template +using add_volatile_t = typename std::add_volatile::type; + +template +using remove_reference_t = typename std::remove_reference::type; + +template +using add_lvalue_reference_t = typename std::add_lvalue_reference::type; + +template +using add_rvalue_reference_t = typename std::add_rvalue_reference::type; + +template +using remove_pointer_t = typename std::remove_pointer::type; + +template +using add_pointer_t = typename std::add_pointer::type; + +template +using make_signed_t = typename std::make_signed::type; + +template +using make_unsigned_t = typename std::make_unsigned::type; + +template +using remove_extent_t = typename std::remove_extent::type; + +template +using remove_all_extents_t = typename std::remove_all_extents::type; + +template ::value> +using aligned_storage_t = typename std::aligned_storage::type; + +template +using decay_t = typename std::decay::type; + +template +using enable_if_t = typename std::enable_if::type; + +template +using conditional_t = typename std::conditional::type; + +template +using common_type_t = typename std::common_type::type; + +template +using underlying_type_t = typename std::underlying_type::type; + +template +using result_of_t = typename std::result_of::type; + +} // namespace absl +#endif // ABSL_META_TYPE_TRAITS_H_ diff --git a/Firestore/third_party/abseil-cpp/absl/meta/type_traits_test.cc b/Firestore/third_party/abseil-cpp/absl/meta/type_traits_test.cc new file mode 100644 index 0000000..15e1c28 --- /dev/null +++ b/Firestore/third_party/abseil-cpp/absl/meta/type_traits_test.cc @@ -0,0 +1,640 @@ +// Copyright 2017 The Abseil Authors. +// +// 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. + +#include "absl/meta/type_traits.h" + +#include +#include +#include +#include +#include + +#include "gtest/gtest.h" + +namespace { + +using ::testing::StaticAssertTypeEq; + +struct Dummy {}; + +TEST(VoidTTest, BasicUsage) { + StaticAssertTypeEq>(); + StaticAssertTypeEq>(); +} + +TEST(ConjunctionTest, BasicBooleanLogic) { + EXPECT_TRUE(absl::conjunction<>::value); + EXPECT_TRUE(absl::conjunction::value); + EXPECT_TRUE((absl::conjunction::value)); + EXPECT_FALSE((absl::conjunction::value)); + EXPECT_FALSE((absl::conjunction::value)); + EXPECT_FALSE((absl::conjunction::value)); +} + +struct MyTrueType { + static constexpr bool value = true; +}; + +struct MyFalseType { + static constexpr bool value = false; +}; + +TEST(ConjunctionTest, ShortCircuiting) { + EXPECT_FALSE( + (absl::conjunction::value)); + EXPECT_TRUE((std::is_base_of>::value)); + EXPECT_TRUE( + (std::is_base_of>::value)); +} + +TEST(DisjunctionTest, BasicBooleanLogic) { + EXPECT_FALSE(absl::disjunction<>::value); + EXPECT_FALSE(absl::disjunction::value); + EXPECT_TRUE((absl::disjunction::value)); + EXPECT_TRUE((absl::disjunction::value)); + EXPECT_TRUE((absl::disjunction::value)); + EXPECT_FALSE((absl::disjunction::value)); +} + +TEST(DisjunctionTest, ShortCircuiting) { + EXPECT_TRUE( + (absl::disjunction::value)); + EXPECT_TRUE(( + std::is_base_of>::value)); + EXPECT_TRUE(( + std::is_base_of>::value)); +} + +TEST(NegationTest, BasicBooleanLogic) { + EXPECT_FALSE(absl::negation::value); + EXPECT_FALSE(absl::negation::value); + EXPECT_TRUE(absl::negation::value); + EXPECT_TRUE(absl::negation::value); +} + +// all member functions are trivial +class Trivial { + int n_; +}; + +class TrivialDefaultCtor { + public: + TrivialDefaultCtor() = default; + explicit TrivialDefaultCtor(int n) : n_(n) {} + + private: + int n_; +}; + +class TrivialCopyCtor { + public: + explicit TrivialCopyCtor(int n) : n_(n) {} + TrivialCopyCtor(const TrivialCopyCtor&) = default; + TrivialCopyCtor& operator=(const TrivialCopyCtor& t) { + n_ = t.n_; + return *this; + } + + private: + int n_; +}; + +class TrivialCopyAssign { + public: + explicit TrivialCopyAssign(int n) : n_(n) {} + TrivialCopyAssign(const TrivialCopyAssign& t) : n_(t.n_) {} + TrivialCopyAssign& operator=(const TrivialCopyAssign& t) = default; + ~TrivialCopyAssign() {} // can have non trivial destructor + private: + int n_; +}; + +struct NonTrivialDestructor { + ~NonTrivialDestructor() {} +}; + +struct TrivialDestructor { + ~TrivialDestructor() = default; +}; + +struct NonCopyable { + NonCopyable() = default; + NonCopyable(const NonCopyable&) = delete; + NonCopyable& operator=(const NonCopyable&) = delete; +}; + +class Base { + public: + virtual ~Base() {} +}; + +// In GCC/Clang, std::is_trivially_constructible requires that the destructor is +// trivial. However, MSVC doesn't require that. This results in different +// behavior when checking is_trivially_constructible on any type with nontrivial +// destructor. Since absl::is_trivially_default_constructible and +// absl::is_trivially_copy_constructible both follows Clang/GCC's interpretation +// and check is_trivially_destructible, it results in inconsistency with +// std::is_trivially_xxx_constructible on MSVC. This macro is used to work +// around this issue in test. In practice, a trivially constructible type +// should also be trivially destructible. +// GCC bug 51452: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51452 +// LWG issue 2116: http://cplusplus.github.io/LWG/lwg-active.html#2116. +#ifdef _MSC_VER +#define ABSL_TRIVIALLY_CONSTRUCTIBLE_VERIFY_TRIVIALLY_DESTRUCTIBLE +#endif + +TEST(TypeTraitsTest, TestTrivialDefaultCtor) { + // arithmetic types and pointers have trivial default constructors. + EXPECT_TRUE(absl::is_trivially_default_constructible::value); + EXPECT_TRUE(absl::is_trivially_default_constructible::value); + EXPECT_TRUE(absl::is_trivially_default_constructible::value); + EXPECT_TRUE(absl::is_trivially_default_constructible::value); + EXPECT_TRUE(absl::is_trivially_default_constructible::value); + EXPECT_TRUE(absl::is_trivially_default_constructible::value); + EXPECT_TRUE(absl::is_trivially_default_constructible::value); + EXPECT_TRUE(absl::is_trivially_default_constructible::value); + EXPECT_TRUE(absl::is_trivially_default_constructible::value); + EXPECT_TRUE(absl::is_trivially_default_constructible::value); + EXPECT_TRUE(absl::is_trivially_default_constructible::value); + EXPECT_TRUE(absl::is_trivially_default_constructible::value); + EXPECT_TRUE(absl::is_trivially_default_constructible::value); + EXPECT_TRUE(absl::is_trivially_default_constructible::value); + EXPECT_TRUE(absl::is_trivially_default_constructible::value); + EXPECT_TRUE(absl::is_trivially_default_constructible::value); + EXPECT_TRUE( + absl::is_trivially_default_constructible::value); + EXPECT_TRUE( + absl::is_trivially_default_constructible::value); + + // types with compiler generated default ctors + EXPECT_TRUE(absl::is_trivially_default_constructible::value); + EXPECT_TRUE( + absl::is_trivially_default_constructible::value); + +#ifndef ABSL_TRIVIALLY_CONSTRUCTIBLE_VERIFY_TRIVIALLY_DESTRUCTIBLE + // types with non trivial destructor are non trivial + EXPECT_FALSE( + absl::is_trivially_default_constructible::value); +#endif + + // types with vtables + EXPECT_FALSE(absl::is_trivially_default_constructible::value); + + // Verify that arrays of such types are trivially default constructible + typedef int int10[10]; + EXPECT_TRUE(absl::is_trivially_default_constructible::value); + typedef Trivial Trivial10[10]; + EXPECT_TRUE(absl::is_trivially_default_constructible::value); + typedef Trivial TrivialDefaultCtor10[10]; + EXPECT_TRUE( + absl::is_trivially_default_constructible::value); + + // Verify that std::pair has non-trivial constructors. + EXPECT_FALSE( + (absl::is_trivially_default_constructible>::value)); + + // Verify that types without trivial constructors are + // correctly marked as such. + EXPECT_FALSE(absl::is_trivially_default_constructible::value); + EXPECT_FALSE( + absl::is_trivially_default_constructible>::value); +} + +TEST(TypeTraitsTest, TestTrivialCopyCtor) { + // Verify that arithmetic types and pointers have trivial copy + // constructors. + EXPECT_TRUE(absl::is_trivially_copy_constructible::value); + EXPECT_TRUE(absl::is_trivially_copy_constructible::value); + EXPECT_TRUE(absl::is_trivially_copy_constructible::value); + EXPECT_TRUE(absl::is_trivially_copy_constructible::value); + EXPECT_TRUE(absl::is_trivially_copy_constructible::value); + EXPECT_TRUE(absl::is_trivially_copy_constructible::value); + EXPECT_TRUE(absl::is_trivially_copy_constructible::value); + EXPECT_TRUE(absl::is_trivially_copy_constructible::value); + EXPECT_TRUE(absl::is_trivially_copy_constructible::value); + EXPECT_TRUE(absl::is_trivially_copy_constructible::value); + EXPECT_TRUE(absl::is_trivially_copy_constructible::value); + EXPECT_TRUE(absl::is_trivially_copy_constructible::value); + EXPECT_TRUE(absl::is_trivially_copy_constructible::value); + EXPECT_TRUE(absl::is_trivially_copy_constructible::value); + EXPECT_TRUE(absl::is_trivially_copy_constructible::value); + EXPECT_TRUE(absl::is_trivially_copy_constructible::value); + EXPECT_TRUE( + absl::is_trivially_copy_constructible::value); + EXPECT_TRUE(absl::is_trivially_copy_constructible::value); + + // types with compiler generated copy ctors + EXPECT_TRUE(absl::is_trivially_copy_constructible::value); + EXPECT_TRUE(absl::is_trivially_copy_constructible::value); + +#ifndef ABSL_TRIVIALLY_CONSTRUCTIBLE_VERIFY_TRIVIALLY_DESTRUCTIBLE + // type with non-trivial destructor are non-trivial copy construbtible + EXPECT_FALSE( + absl::is_trivially_copy_constructible::value); +#endif + + // types with vtables + EXPECT_FALSE(absl::is_trivially_copy_constructible::value); + + // Verify that std pair of such types is trivially copy constructible + EXPECT_TRUE( + (absl::is_trivially_copy_constructible>::value)); + EXPECT_TRUE( + (absl::is_trivially_copy_constructible>::value)); + EXPECT_TRUE((absl::is_trivially_copy_constructible< + std::pair>::value)); + + // Verify that arrays are not + typedef int int10[10]; + EXPECT_FALSE(absl::is_trivially_copy_constructible::value); + + // Verify that pairs of types without trivial copy constructors + // are not marked as trivial. + EXPECT_FALSE((absl::is_trivially_copy_constructible< + std::pair>::value)); + EXPECT_FALSE((absl::is_trivially_copy_constructible< + std::pair>::value)); + + // Verify that types without trivial copy constructors are + // correctly marked as such. + EXPECT_FALSE(absl::is_trivially_copy_constructible::value); + EXPECT_FALSE(absl::is_trivially_copy_constructible>::value); + + // types with deleted copy constructors are not copy constructible + EXPECT_FALSE(absl::is_trivially_copy_constructible::value); +} + +TEST(TypeTraitsTest, TestTrivialCopyAssign) { + // Verify that arithmetic types and pointers have trivial copy + // constructors. + EXPECT_TRUE(absl::is_trivially_copy_assignable::value); + EXPECT_TRUE(absl::is_trivially_copy_assignable::value); + EXPECT_TRUE(absl::is_trivially_copy_assignable::value); + EXPECT_TRUE(absl::is_trivially_copy_assignable::value); + EXPECT_TRUE(absl::is_trivially_copy_assignable::value); + EXPECT_TRUE(absl::is_trivially_copy_assignable::value); + EXPECT_TRUE(absl::is_trivially_copy_assignable::value); + EXPECT_TRUE(absl::is_trivially_copy_assignable::value); + EXPECT_TRUE(absl::is_trivially_copy_assignable::value); + EXPECT_TRUE(absl::is_trivially_copy_assignable::value); + EXPECT_TRUE(absl::is_trivially_copy_assignable::value); + EXPECT_TRUE(absl::is_trivially_copy_assignable::value); + EXPECT_TRUE(absl::is_trivially_copy_assignable::value); + EXPECT_TRUE(absl::is_trivially_copy_assignable::value); + EXPECT_TRUE(absl::is_trivially_copy_assignable::value); + EXPECT_TRUE(absl::is_trivially_copy_assignable::value); + EXPECT_TRUE( + absl::is_trivially_copy_assignable::value); + EXPECT_TRUE(absl::is_trivially_copy_assignable::value); + + // const qualified types are not assignable + EXPECT_FALSE(absl::is_trivially_copy_assignable::value); + + // types with compiler generated copy assignment + EXPECT_TRUE(absl::is_trivially_copy_assignable::value); + EXPECT_TRUE(absl::is_trivially_copy_assignable::value); + + // types with vtables + EXPECT_FALSE(absl::is_trivially_copy_assignable::value); + + // Verify that arrays are not trivially copy assignable + typedef int int10[10]; + EXPECT_FALSE(absl::is_trivially_copy_assignable::value); + + // Verify that std::pair is not trivially assignable + EXPECT_FALSE( + (absl::is_trivially_copy_assignable>::value)); + + // Verify that types without trivial copy constructors are + // correctly marked as such. + EXPECT_FALSE(absl::is_trivially_copy_assignable::value); + EXPECT_FALSE(absl::is_trivially_copy_assignable>::value); + + // types with deleted copy assignment are not copy assignable + EXPECT_FALSE(absl::is_trivially_copy_assignable::value); +} + +TEST(TypeTraitsTest, TestTrivialDestructor) { + // Verify that arithmetic types and pointers have trivial copy + // constructors. + EXPECT_TRUE(absl::is_trivially_destructible::value); + EXPECT_TRUE(absl::is_trivially_destructible::value); + EXPECT_TRUE(absl::is_trivially_destructible::value); + EXPECT_TRUE(absl::is_trivially_destructible::value); + EXPECT_TRUE(absl::is_trivially_destructible::value); + EXPECT_TRUE(absl::is_trivially_destructible::value); + EXPECT_TRUE(absl::is_trivially_destructible::value); + EXPECT_TRUE(absl::is_trivially_destructible::value); + EXPECT_TRUE(absl::is_trivially_destructible::value); + EXPECT_TRUE(absl::is_trivially_destructible::value); + EXPECT_TRUE(absl::is_trivially_destructible::value); + EXPECT_TRUE(absl::is_trivially_destructible::value); + EXPECT_TRUE(absl::is_trivially_destructible::value); + EXPECT_TRUE(absl::is_trivially_destructible::value); + EXPECT_TRUE(absl::is_trivially_destructible::value); + EXPECT_TRUE(absl::is_trivially_destructible::value); + EXPECT_TRUE(absl::is_trivially_destructible::value); + EXPECT_TRUE(absl::is_trivially_destructible::value); + + // classes with destructors + EXPECT_TRUE(absl::is_trivially_destructible::value); + EXPECT_TRUE(absl::is_trivially_destructible::value); + EXPECT_FALSE(absl::is_trivially_destructible::value); + + // std::pair of such types is trivial + EXPECT_TRUE((absl::is_trivially_destructible>::value)); + EXPECT_TRUE((absl::is_trivially_destructible< + std::pair>::value)); + + // array of such types is trivial + typedef int int10[10]; + EXPECT_TRUE(absl::is_trivially_destructible::value); + typedef TrivialDestructor TrivialDestructor10[10]; + EXPECT_TRUE(absl::is_trivially_destructible::value); + typedef NonTrivialDestructor NonTrivialDestructor10[10]; + EXPECT_FALSE(absl::is_trivially_destructible::value); +} + +#define ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(trait_name, ...) \ + EXPECT_TRUE((std::is_same::type, \ + absl::trait_name##_t<__VA_ARGS__>>::value)) + +TEST(TypeTraitsTest, TestRemoveCVAliases) { + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_cv, int); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_cv, const int); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_cv, volatile int); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_cv, const volatile int); + + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_const, int); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_const, const int); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_const, volatile int); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_const, const volatile int); + + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_volatile, int); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_volatile, const int); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_volatile, volatile int); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_volatile, const volatile int); +} + +TEST(TypeTraitsTest, TestAddCVAliases) { + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_cv, int); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_cv, const int); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_cv, volatile int); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_cv, const volatile int); + + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_const, int); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_const, const int); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_const, volatile int); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_const, const volatile int); + + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_volatile, int); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_volatile, const int); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_volatile, volatile int); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_volatile, const volatile int); +} + +TEST(TypeTraitsTest, TestReferenceAliases) { + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_reference, int); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_reference, volatile int); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_reference, int&); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_reference, volatile int&); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_reference, int&&); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_reference, volatile int&&); + + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_lvalue_reference, int); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_lvalue_reference, volatile int); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_lvalue_reference, int&); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_lvalue_reference, volatile int&); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_lvalue_reference, int&&); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_lvalue_reference, volatile int&&); + + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_rvalue_reference, int); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_rvalue_reference, volatile int); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_rvalue_reference, int&); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_rvalue_reference, volatile int&); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_rvalue_reference, int&&); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_rvalue_reference, volatile int&&); +} + +TEST(TypeTraitsTest, TestPointerAliases) { + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_pointer, int*); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_pointer, volatile int*); + + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_pointer, int); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_pointer, volatile int); +} + +TEST(TypeTraitsTest, TestSignednessAliases) { + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(make_signed, int); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(make_signed, volatile int); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(make_signed, unsigned); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(make_signed, volatile unsigned); + + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(make_unsigned, int); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(make_unsigned, volatile int); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(make_unsigned, unsigned); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(make_unsigned, volatile unsigned); +} + +TEST(TypeTraitsTest, TestExtentAliases) { + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_extent, int[]); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_extent, int[1]); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_extent, int[1][1]); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_extent, int[][1]); + + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_all_extents, int[]); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_all_extents, int[1]); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_all_extents, int[1][1]); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_all_extents, int[][1]); +} + +TEST(TypeTraitsTest, TestAlignedStorageAlias) { + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 1); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 2); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 3); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 4); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 5); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 6); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 7); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 8); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 9); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 10); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 11); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 12); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 13); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 14); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 15); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 16); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 17); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 18); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 19); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 20); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 21); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 22); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 23); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 24); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 25); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 26); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 27); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 28); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 29); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 30); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 31); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 32); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 33); + + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 1, 128); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 2, 128); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 3, 128); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 4, 128); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 5, 128); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 6, 128); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 7, 128); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 8, 128); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 9, 128); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 10, 128); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 11, 128); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 12, 128); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 13, 128); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 14, 128); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 15, 128); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 16, 128); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 17, 128); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 18, 128); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 19, 128); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 20, 128); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 21, 128); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 22, 128); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 23, 128); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 24, 128); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 25, 128); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 26, 128); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 27, 128); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 28, 128); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 29, 128); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 30, 128); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 31, 128); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 32, 128); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 33, 128); +} + +TEST(TypeTraitsTest, TestDecay) { + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, int); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, const int); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, volatile int); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, const volatile int); + + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, int&); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, const int&); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, volatile int&); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, const volatile int&); + + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, int&); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, const int&); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, volatile int&); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, const volatile int&); + + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, int[1]); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, int[1][1]); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, int[][1]); + + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, int()); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, int(float)); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, int(char, ...)); +} + +struct TypeA {}; +struct TypeB {}; +struct TypeC {}; +struct TypeD {}; + +template +struct Wrap {}; + +enum class TypeEnum { A, B, C, D }; + +struct GetTypeT { + template ::value, int> = 0> + TypeEnum operator()(Wrap) const { + return TypeEnum::A; + } + + template ::value, int> = 0> + TypeEnum operator()(Wrap) const { + return TypeEnum::B; + } + + template ::value, int> = 0> + TypeEnum operator()(Wrap) const { + return TypeEnum::C; + } + + // NOTE: TypeD is intentionally not handled +} constexpr GetType = {}; + +TEST(TypeTraitsTest, TestEnableIf) { + EXPECT_EQ(TypeEnum::A, GetType(Wrap())); + EXPECT_EQ(TypeEnum::B, GetType(Wrap())); + EXPECT_EQ(TypeEnum::C, GetType(Wrap())); +} + +TEST(TypeTraitsTest, TestConditional) { + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(conditional, true, int, char); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(conditional, false, int, char); +} + +// TODO(calabrese) Check with specialized std::common_type +TEST(TypeTraitsTest, TestCommonType) { + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(common_type, int); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(common_type, int, char); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(common_type, int, char, int); + + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(common_type, int&); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(common_type, int, char&); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(common_type, int, char, int&); +} + +TEST(TypeTraitsTest, TestUnderlyingType) { + enum class enum_char : char {}; + enum class enum_long_long : long long {}; // NOLINT(runtime/int) + + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(underlying_type, enum_char); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(underlying_type, enum_long_long); +} + +struct GetTypeExtT { + template + absl::result_of_t operator()(T&& arg) const { + return GetType(std::forward(arg)); + } + + TypeEnum operator()(Wrap) const { return TypeEnum::D; } +} constexpr GetTypeExt = {}; + +TEST(TypeTraitsTest, TestResultOf) { + EXPECT_EQ(TypeEnum::A, GetTypeExt(Wrap())); + EXPECT_EQ(TypeEnum::B, GetTypeExt(Wrap())); + EXPECT_EQ(TypeEnum::C, GetTypeExt(Wrap())); + EXPECT_EQ(TypeEnum::D, GetTypeExt(Wrap())); +} + +} // namespace diff --git a/Firestore/third_party/abseil-cpp/absl/strings/CMakeLists.txt b/Firestore/third_party/abseil-cpp/absl/strings/CMakeLists.txt new file mode 100644 index 0000000..dcd4974 --- /dev/null +++ b/Firestore/third_party/abseil-cpp/absl/strings/CMakeLists.txt @@ -0,0 +1,299 @@ +# +# Copyright 2017 The Abseil Authors. +# +# 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. +# + + +list(APPEND STRINGS_PUBLIC_HEADERS + "ascii.h" + "escaping.h" + "match.h" + "numbers.h" + "str_cat.h" + "string_view.h" + "strip.h" + "str_join.h" + "str_replace.h" + "str_split.h" + "substitute.h" +) + + +list(APPEND STRINGS_INTERNAL_HEADERS + "internal/char_map.h" + "internal/memutil.h" + "internal/ostringstream.h" + "internal/resize_uninitialized.h" + "internal/str_join_internal.h" + "internal/str_split_internal.h" + "internal/utf8.h" +) + + + +# add string library +list(APPEND STRINGS_SRC + "ascii.cc" + "escaping.cc" + "internal/memutil.cc" + "internal/memutil.h" + "internal/utf8.cc" + "match.cc" + "numbers.cc" + "str_cat.cc" + "str_replace.cc" + "str_split.cc" + "string_view.cc" + "substitute.cc" + ${STRINGS_PUBLIC_HEADERS} + ${STRINGS_INTERNAL_HEADERS} +) +set(STRINGS_PUBLIC_LIBRARIES absl::base absl_throw_delegate) + +absl_library( + TARGET + absl_strings + SOURCES + ${STRINGS_SRC} + PUBLIC_LIBRARIES + ${STRINGS_PUBLIC_LIBRARIES} + EXPORT_NAME + strings +) + + +# +## TESTS +# + +# test match_test +set(MATCH_TEST_SRC "match_test.cc") +set(MATCH_TEST_PUBLIC_LIBRARIES absl::strings) + +absl_test( + TARGET + match_test + SOURCES + ${MATCH_TEST_SRC} + PUBLIC_LIBRARIES + ${MATCH_TEST_PUBLIC_LIBRARIES} +) + + +# test escaping_test +set(ESCAPING_TEST_SRC "escaping_test.cc") +set(ESCAPING_TEST_PUBLIC_LIBRARIES absl::strings absl::base) + +absl_test( + TARGET + escaping_test + SOURCES + ${ESCAPING_TEST_SRC} + PUBLIC_LIBRARIES + ${ESCAPING_TEST_PUBLIC_LIBRARIES} +) + + +# test ascii_test +set(ASCII_TEST_SRC "ascii_test.cc") +set(ASCII_TEST_PUBLIC_LIBRARIES absl::strings) + +absl_test( + TARGET + ascii_test + SOURCES + ${ASCII_TEST_SRC} + PUBLIC_LIBRARIES + ${ASCII_TEST_PUBLIC_LIBRARIES} +) + + +# test memutil_test +set(MEMUTIL_TEST_SRC "internal/memutil_test.cc") +set(MEMUTIL_TEST_PUBLIC_LIBRARIES absl::strings) + +absl_test( + TARGET + memutil_test + SOURCES + ${MEMUTIL_TEST_SRC} + PUBLIC_LIBRARIES + ${MEMUTIL_TEST_PUBLIC_LIBRARIES} +) + + +# test utf8_test +set(UTF8_TEST_SRC "internal/utf8_test.cc") +set(UTF8_TEST_PUBLIC_LIBRARIES absl::strings absl::base) + +absl_test( + TARGET + utf8_test + SOURCES + ${UTF8_TEST_SRC} + PUBLIC_LIBRARIES + ${UTF8_TEST_PUBLIC_LIBRARIES} +) + + +# test string_view_test +set(STRING_VIEW_TEST_SRC "string_view_test.cc") +set(STRING_VIEW_TEST_PUBLIC_LIBRARIES absl::strings absl_throw_delegate absl::base) + +absl_test( + TARGET + string_view_test + SOURCES + ${STRING_VIEW_TEST_SRC} + PUBLIC_LIBRARIES + ${STRING_VIEW_TEST_PUBLIC_LIBRARIES} +) + + +# test substitute_test +set(SUBSTITUTE_TEST_SRC "substitute_test.cc") +set(SUBSTITUTE_TEST_PUBLIC_LIBRARIES absl::strings absl::base) + +absl_test( + TARGET + substitute_test + SOURCES + ${SUBSTITUTE_TEST_SRC} + PUBLIC_LIBRARIES + ${SUBSTITUTE_TEST_PUBLIC_LIBRARIES} +) + + +# test str_replace_test +set(STR_REPLACE_TEST_SRC "str_replace_test.cc") +set(STR_REPLACE_TEST_PUBLIC_LIBRARIES absl::strings absl::base absl_throw_delegate) + +absl_test( + TARGET + str_replace_test + SOURCES + ${STR_REPLACE_TEST_SRC} + PUBLIC_LIBRARIES + ${STR_REPLACE_TEST_PUBLIC_LIBRARIES} +) + + +# test str_split_test +set(STR_SPLIT_TEST_SRC "str_split_test.cc") +set(STR_SPLIT_TEST_PUBLIC_LIBRARIES absl::strings absl::base absl_throw_delegate) + +absl_test( + TARGET + str_split_test + SOURCES + ${STR_SPLIT_TEST_SRC} + PUBLIC_LIBRARIES + ${STR_SPLIT_TEST_PUBLIC_LIBRARIES} +) + + +# test ostringstream_test +set(OSTRINGSTREAM_TEST_SRC "internal/ostringstream_test.cc") + +absl_test( + TARGET + ostringstream_test + SOURCES + ${OSTRINGSTREAM_TEST_SRC} +) + + +# test resize_uninitialized_test +set(RESIZE_UNINITIALIZED_TEST_SRC "internal/resize_uninitialized_test.cc") + +absl_test( + TARGET + resize_uninitialized_test + SOURCES + ${RESIZE_UNINITIALIZED_TEST_SRC} +) + + +# test str_join_test +set(STR_JOIN_TEST_SRC "str_join_test.cc") +set(STR_JOIN_TEST_PUBLIC_LIBRARIES absl::strings) + +absl_test( + TARGET + str_join_test + SOURCES + ${STR_JOIN_TEST_SRC} + PUBLIC_LIBRARIES + ${STR_JOIN_TEST_PUBLIC_LIBRARIES} +) + + +# test str_cat_test +set(STR_CAT_TEST_SRC "str_cat_test.cc") +set(STR_CAT_TEST_PUBLIC_LIBRARIES absl::strings) + +absl_test( + TARGET + str_cat_test + SOURCES + ${STR_CAT_TEST_SRC} + PUBLIC_LIBRARIES + ${STR_CAT_TEST_PUBLIC_LIBRARIES} +) + + +# test numbers_test +set(NUMBERS_TEST_SRC "numbers_test.cc") +set(NUMBERS_TEST_PUBLIC_LIBRARIES absl::strings) + +absl_test( + TARGET + numbers_test + SOURCES + ${NUMBERS_TEST_SRC} + PUBLIC_LIBRARIES + ${NUMBERS_TEST_PUBLIC_LIBRARIES} +) + + +# test strip_test +set(STRIP_TEST_SRC "strip_test.cc") +set(STRIP_TEST_PUBLIC_LIBRARIES absl::strings) + +absl_test( + TARGET + strip_test + SOURCES + ${STRIP_TEST_SRC} + PUBLIC_LIBRARIES + ${STRIP_TEST_PUBLIC_LIBRARIES} +) + + +# test char_map_test +set(CHAR_MAP_TEST_SRC "internal/char_map_test.cc") +set(CHAR_MAP_TEST_PUBLIC_LIBRARIES absl::strings) + +absl_test( + TARGET + char_map_test + SOURCES + ${CHAR_MAP_TEST_SRC} + PUBLIC_LIBRARIES + ${CHAR_MAP_TEST_PUBLIC_LIBRARIES} +) + + + + diff --git a/Firestore/third_party/abseil-cpp/absl/strings/ascii.cc b/Firestore/third_party/abseil-cpp/absl/strings/ascii.cc new file mode 100644 index 0000000..c9481e8 --- /dev/null +++ b/Firestore/third_party/abseil-cpp/absl/strings/ascii.cc @@ -0,0 +1,198 @@ +// Copyright 2017 The Abseil Authors. +// +// 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. + +#include "absl/strings/ascii.h" + +namespace absl { +namespace ascii_internal { + +// # Table generated by this Python code (bit 0x02 is currently unused): +// TODO(mbar) Move Python code for generation of table to BUILD and link here. + +// NOTE: The kAsciiPropertyBits table used within this code was generated by +// Python code of the following form. (Bit 0x02 is currently unused and +// available.) +// +// def Hex2(n): +// return '0x' + hex(n/16)[2:] + hex(n%16)[2:] +// def IsPunct(ch): +// return (ord(ch) >= 32 and ord(ch) < 127 and +// not ch.isspace() and not ch.isalnum()) +// def IsBlank(ch): +// return ch in ' \t' +// def IsCntrl(ch): +// return ord(ch) < 32 or ord(ch) == 127 +// def IsXDigit(ch): +// return ch.isdigit() or ch.lower() in 'abcdef' +// for i in range(128): +// ch = chr(i) +// mask = ((ch.isalpha() and 0x01 or 0) | +// (ch.isalnum() and 0x04 or 0) | +// (ch.isspace() and 0x08 or 0) | +// (IsPunct(ch) and 0x10 or 0) | +// (IsBlank(ch) and 0x20 or 0) | +// (IsCntrl(ch) and 0x40 or 0) | +// (IsXDigit(ch) and 0x80 or 0)) +// print Hex2(mask) + ',', +// if i % 16 == 7: +// print ' //', Hex2(i & 0x78) +// elif i % 16 == 15: +// print + +// clang-format off +// Array of bitfields holding character information. Each bit value corresponds +// to a particular character feature. For readability, and because the value +// of these bits is tightly coupled to this implementation, the individual bits +// are not named. Note that bitfields for all characters above ASCII 127 are +// zero-initialized. +const unsigned char kPropertyBits[256] = { + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, // 0x00 + 0x40, 0x68, 0x48, 0x48, 0x48, 0x48, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, // 0x10 + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + 0x28, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, // 0x20 + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, + 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, // 0x30 + 0x84, 0x84, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, + 0x10, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x05, // 0x40 + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, // 0x50 + 0x05, 0x05, 0x05, 0x10, 0x10, 0x10, 0x10, 0x10, + 0x10, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x05, // 0x60 + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, // 0x70 + 0x05, 0x05, 0x05, 0x10, 0x10, 0x10, 0x10, 0x40, +}; + +// Array of characters for the ascii_tolower() function. For values 'A' +// through 'Z', return the lower-case character; otherwise, return the +// identity of the passed character. +const char kToLower[256] = { + '\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07', + '\x08', '\x09', '\x0a', '\x0b', '\x0c', '\x0d', '\x0e', '\x0f', + '\x10', '\x11', '\x12', '\x13', '\x14', '\x15', '\x16', '\x17', + '\x18', '\x19', '\x1a', '\x1b', '\x1c', '\x1d', '\x1e', '\x1f', + '\x20', '\x21', '\x22', '\x23', '\x24', '\x25', '\x26', '\x27', + '\x28', '\x29', '\x2a', '\x2b', '\x2c', '\x2d', '\x2e', '\x2f', + '\x30', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37', + '\x38', '\x39', '\x3a', '\x3b', '\x3c', '\x3d', '\x3e', '\x3f', + '\x40', 'a', 'b', 'c', 'd', 'e', 'f', 'g', + 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', + 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', + 'x', 'y', 'z', '\x5b', '\x5c', '\x5d', '\x5e', '\x5f', + '\x60', '\x61', '\x62', '\x63', '\x64', '\x65', '\x66', '\x67', + '\x68', '\x69', '\x6a', '\x6b', '\x6c', '\x6d', '\x6e', '\x6f', + '\x70', '\x71', '\x72', '\x73', '\x74', '\x75', '\x76', '\x77', + '\x78', '\x79', '\x7a', '\x7b', '\x7c', '\x7d', '\x7e', '\x7f', + '\x80', '\x81', '\x82', '\x83', '\x84', '\x85', '\x86', '\x87', + '\x88', '\x89', '\x8a', '\x8b', '\x8c', '\x8d', '\x8e', '\x8f', + '\x90', '\x91', '\x92', '\x93', '\x94', '\x95', '\x96', '\x97', + '\x98', '\x99', '\x9a', '\x9b', '\x9c', '\x9d', '\x9e', '\x9f', + '\xa0', '\xa1', '\xa2', '\xa3', '\xa4', '\xa5', '\xa6', '\xa7', + '\xa8', '\xa9', '\xaa', '\xab', '\xac', '\xad', '\xae', '\xaf', + '\xb0', '\xb1', '\xb2', '\xb3', '\xb4', '\xb5', '\xb6', '\xb7', + '\xb8', '\xb9', '\xba', '\xbb', '\xbc', '\xbd', '\xbe', '\xbf', + '\xc0', '\xc1', '\xc2', '\xc3', '\xc4', '\xc5', '\xc6', '\xc7', + '\xc8', '\xc9', '\xca', '\xcb', '\xcc', '\xcd', '\xce', '\xcf', + '\xd0', '\xd1', '\xd2', '\xd3', '\xd4', '\xd5', '\xd6', '\xd7', + '\xd8', '\xd9', '\xda', '\xdb', '\xdc', '\xdd', '\xde', '\xdf', + '\xe0', '\xe1', '\xe2', '\xe3', '\xe4', '\xe5', '\xe6', '\xe7', + '\xe8', '\xe9', '\xea', '\xeb', '\xec', '\xed', '\xee', '\xef', + '\xf0', '\xf1', '\xf2', '\xf3', '\xf4', '\xf5', '\xf6', '\xf7', + '\xf8', '\xf9', '\xfa', '\xfb', '\xfc', '\xfd', '\xfe', '\xff', +}; + +// Array of characters for the ascii_toupper() function. For values 'a' +// through 'z', return the upper-case character; otherwise, return the +// identity of the passed character. +const char kToUpper[256] = { + '\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07', + '\x08', '\x09', '\x0a', '\x0b', '\x0c', '\x0d', '\x0e', '\x0f', + '\x10', '\x11', '\x12', '\x13', '\x14', '\x15', '\x16', '\x17', + '\x18', '\x19', '\x1a', '\x1b', '\x1c', '\x1d', '\x1e', '\x1f', + '\x20', '\x21', '\x22', '\x23', '\x24', '\x25', '\x26', '\x27', + '\x28', '\x29', '\x2a', '\x2b', '\x2c', '\x2d', '\x2e', '\x2f', + '\x30', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37', + '\x38', '\x39', '\x3a', '\x3b', '\x3c', '\x3d', '\x3e', '\x3f', + '\x40', '\x41', '\x42', '\x43', '\x44', '\x45', '\x46', '\x47', + '\x48', '\x49', '\x4a', '\x4b', '\x4c', '\x4d', '\x4e', '\x4f', + '\x50', '\x51', '\x52', '\x53', '\x54', '\x55', '\x56', '\x57', + '\x58', '\x59', '\x5a', '\x5b', '\x5c', '\x5d', '\x5e', '\x5f', + '\x60', 'A', 'B', 'C', 'D', 'E', 'F', 'G', + 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', + 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', + 'X', 'Y', 'Z', '\x7b', '\x7c', '\x7d', '\x7e', '\x7f', + '\x80', '\x81', '\x82', '\x83', '\x84', '\x85', '\x86', '\x87', + '\x88', '\x89', '\x8a', '\x8b', '\x8c', '\x8d', '\x8e', '\x8f', + '\x90', '\x91', '\x92', '\x93', '\x94', '\x95', '\x96', '\x97', + '\x98', '\x99', '\x9a', '\x9b', '\x9c', '\x9d', '\x9e', '\x9f', + '\xa0', '\xa1', '\xa2', '\xa3', '\xa4', '\xa5', '\xa6', '\xa7', + '\xa8', '\xa9', '\xaa', '\xab', '\xac', '\xad', '\xae', '\xaf', + '\xb0', '\xb1', '\xb2', '\xb3', '\xb4', '\xb5', '\xb6', '\xb7', + '\xb8', '\xb9', '\xba', '\xbb', '\xbc', '\xbd', '\xbe', '\xbf', + '\xc0', '\xc1', '\xc2', '\xc3', '\xc4', '\xc5', '\xc6', '\xc7', + '\xc8', '\xc9', '\xca', '\xcb', '\xcc', '\xcd', '\xce', '\xcf', + '\xd0', '\xd1', '\xd2', '\xd3', '\xd4', '\xd5', '\xd6', '\xd7', + '\xd8', '\xd9', '\xda', '\xdb', '\xdc', '\xdd', '\xde', '\xdf', + '\xe0', '\xe1', '\xe2', '\xe3', '\xe4', '\xe5', '\xe6', '\xe7', + '\xe8', '\xe9', '\xea', '\xeb', '\xec', '\xed', '\xee', '\xef', + '\xf0', '\xf1', '\xf2', '\xf3', '\xf4', '\xf5', '\xf6', '\xf7', + '\xf8', '\xf9', '\xfa', '\xfb', '\xfc', '\xfd', '\xfe', '\xff', +}; +// clang-format on + +} // namespace ascii_internal + +void AsciiStrToLower(std::string* s) { + for (auto& ch : *s) { + ch = absl::ascii_tolower(ch); + } +} + +void AsciiStrToUpper(std::string* s) { + for (auto& ch : *s) { + ch = absl::ascii_toupper(ch); + } +} + +void RemoveExtraAsciiWhitespace(std::string* str) { + auto stripped = StripAsciiWhitespace(*str); + + if (stripped.empty()) { + str->clear(); + return; + } + + auto input_it = stripped.begin(); + auto input_end = stripped.end(); + auto output_it = &(*str)[0]; + bool is_ws = false; + + for (; input_it < input_end; ++input_it) { + if (is_ws) { + // Consecutive whitespace? Keep only the last. + is_ws = absl::ascii_isspace(*input_it); + if (is_ws) --output_it; + } else { + is_ws = absl::ascii_isspace(*input_it); + } + + *output_it = *input_it; + ++output_it; + } + + str->erase(output_it - &(*str)[0]); +} + +} // namespace absl diff --git a/Firestore/third_party/abseil-cpp/absl/strings/ascii.h b/Firestore/third_party/abseil-cpp/absl/strings/ascii.h new file mode 100644 index 0000000..fc2bb33 --- /dev/null +++ b/Firestore/third_party/abseil-cpp/absl/strings/ascii.h @@ -0,0 +1,239 @@ +// +// Copyright 2017 The Abseil Authors. +// +// 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. +// +// ----------------------------------------------------------------------------- +// File: ascii.h +// ----------------------------------------------------------------------------- +// +// This package contains functions operating on characters and strings +// restricted to standard ASCII. These include character classification +// functions analogous to those found in the ANSI C Standard Library +// header file. +// +// C++ implementations provide functionality based on their +// C environment locale. In general, reliance on such a locale is not ideal, as +// the locale standard is problematic (and may not return invariant information +// for the same character set, for example). These `ascii_*()` functions are +// hard-wired for standard ASCII, much faster, and guaranteed to behave +// consistently. They will never be overloaded, nor will their function +// signature change. +// +// `ascii_isalnum()`, `ascii_isalpha()`, `ascii_isascii()`, `ascii_isblank()`, +// `ascii_iscntrl()`, `ascii_isdigit()`, `ascii_isgraph()`, `ascii_islower()`, +// `ascii_isprint()`, `ascii_ispunct()`, `ascii_isspace()`, `ascii_isupper()`, +// `ascii_isxdigit()` +// Analagous to the functions with similar names, these +// functions take an unsigned char and return a bool, based on whether the +// character matches the condition specified. +// +// If the input character has a numerical value greater than 127, these +// functions return `false`. +// +// `ascii_tolower()`, `ascii_toupper()` +// Analagous to the functions with similar names, these functions +// take an unsigned char and return a char. +// +// If the input character is not an ASCII {lower,upper}-case letter (including +// numerical values greater than 127) then the functions return the same value +// as the input character. + +#ifndef ABSL_STRINGS_ASCII_H_ +#define ABSL_STRINGS_ASCII_H_ + +#include +#include + +#include "absl/base/attributes.h" +#include "absl/strings/string_view.h" + +namespace absl { +namespace ascii_internal { + +// Declaration for an array of bitfields holding character information. +extern const unsigned char kPropertyBits[256]; + +// Declaration for the array of characters to upper-case characters. +extern const char kToUpper[256]; + +// Declaration for the array of characters to lower-case characters. +extern const char kToLower[256]; + +} // namespace ascii_internal + +// ascii_isalpha() +// +// Determines whether the given character is an alphabetic character. +inline bool ascii_isalpha(unsigned char c) { + return (ascii_internal::kPropertyBits[c] & 0x01) != 0; +} + +// ascii_isalnum() +// +// Determines whether the given character is an alphanumeric character. +inline bool ascii_isalnum(unsigned char c) { + return (ascii_internal::kPropertyBits[c] & 0x04) != 0; +} + +// ascii_isspace() +// +// Determines whether the given character is a whitespace character (space, +// tab, vertical tab, formfeed, linefeed, or carriage return). +inline bool ascii_isspace(unsigned char c) { + return (ascii_internal::kPropertyBits[c] & 0x08) != 0; +} + +// ascii_ispunct() +// +// Determines whether the given character is a punctuation character. +inline bool ascii_ispunct(unsigned char c) { + return (ascii_internal::kPropertyBits[c] & 0x10) != 0; +} + +// ascii_isblank() +// +// Determines whether the given character is a blank character (tab or space). +inline bool ascii_isblank(unsigned char c) { + return (ascii_internal::kPropertyBits[c] & 0x20) != 0; +} + +// ascii_iscntrl() +// +// Determines whether the given character is a control character. +inline bool ascii_iscntrl(unsigned char c) { + return (ascii_internal::kPropertyBits[c] & 0x40) != 0; +} + +// ascii_isxdigit() +// +// Determines whether the given character can be represented as a hexadecimal +// digit character (i.e. {0-9} or {A-F}). +inline bool ascii_isxdigit(unsigned char c) { + return (ascii_internal::kPropertyBits[c] & 0x80) != 0; +} + +// ascii_isdigit() +// +// Determines whether the given character can be represented as a decimal +// digit character (i.e. {0-9}). +inline bool ascii_isdigit(unsigned char c) { return c >= '0' && c <= '9'; } + +// ascii_isprint() +// +// Determines whether the given character is printable, including whitespace. +inline bool ascii_isprint(unsigned char c) { return c >= 32 && c < 127; } + +// ascii_isgraph() +// +// Determines whether the given character has a graphical representation. +inline bool ascii_isgraph(unsigned char c) { return c > 32 && c < 127; } + +// ascii_isupper() +// +// Determines whether the given character is uppercase. +inline bool ascii_isupper(unsigned char c) { return c >= 'A' && c <= 'Z'; } + +// ascii_islower() +// +// Determines whether the given character is lowercase. +inline bool ascii_islower(unsigned char c) { return c >= 'a' && c <= 'z'; } + +// ascii_isascii() +// +// Determines whether the given character is ASCII. +inline bool ascii_isascii(unsigned char c) { return c < 128; } + +// ascii_tolower() +// +// Returns an ASCII character, converting to lowercase if uppercase is +// passed. Note that character values > 127 are simply returned. +inline char ascii_tolower(unsigned char c) { + return ascii_internal::kToLower[c]; +} + +// Converts the characters in `s` to lowercase, changing the contents of `s`. +void AsciiStrToLower(std::string* s); + +// Creates a lowercase std::string from a given absl::string_view. +ABSL_MUST_USE_RESULT inline std::string AsciiStrToLower(absl::string_view s) { + std::string result(s); + absl::AsciiStrToLower(&result); + return result; +} + +// ascii_toupper() +// +// Returns the ASCII character, converting to upper-case if lower-case is +// passed. Note that characters values > 127 are simply returned. +inline char ascii_toupper(unsigned char c) { + return ascii_internal::kToUpper[c]; +} + +// Converts the characters in `s` to uppercase, changing the contents of `s`. +void AsciiStrToUpper(std::string* s); + +// Creates an uppercase std::string from a given absl::string_view. +ABSL_MUST_USE_RESULT inline std::string AsciiStrToUpper(absl::string_view s) { + std::string result(s); + absl::AsciiStrToUpper(&result); + return result; +} + +// Returns absl::string_view with whitespace stripped from the beginning of the +// given string_view. +ABSL_MUST_USE_RESULT inline absl::string_view StripLeadingAsciiWhitespace( + absl::string_view str) { + auto it = std::find_if_not(str.begin(), str.end(), absl::ascii_isspace); + return absl::string_view(it, str.end() - it); +} + +// Strips in place whitespace from the beginning of the given std::string. +inline void StripLeadingAsciiWhitespace(std::string* str) { + auto it = std::find_if_not(str->begin(), str->end(), absl::ascii_isspace); + str->erase(str->begin(), it); +} + +// Returns absl::string_view with whitespace stripped from the end of the given +// string_view. +ABSL_MUST_USE_RESULT inline absl::string_view StripTrailingAsciiWhitespace( + absl::string_view str) { + auto it = std::find_if_not(str.rbegin(), str.rend(), absl::ascii_isspace); + return absl::string_view(str.begin(), str.rend() - it); +} + +// Strips in place whitespace from the end of the given std::string +inline void StripTrailingAsciiWhitespace(std::string* str) { + auto it = std::find_if_not(str->rbegin(), str->rend(), absl::ascii_isspace); + str->erase(str->rend() - it); +} + +// Returns absl::string_view with whitespace stripped from both ends of the +// given string_view. +ABSL_MUST_USE_RESULT inline absl::string_view StripAsciiWhitespace( + absl::string_view str) { + return StripTrailingAsciiWhitespace(StripLeadingAsciiWhitespace(str)); +} + +// Strips in place whitespace from both ends of the given std::string +inline void StripAsciiWhitespace(std::string* str) { + StripTrailingAsciiWhitespace(str); + StripLeadingAsciiWhitespace(str); +} + +// Removes leading, trailing, and consecutive internal whitespace. +void RemoveExtraAsciiWhitespace(std::string*); + +} // namespace absl + +#endif // ABSL_STRINGS_ASCII_H_ diff --git a/Firestore/third_party/abseil-cpp/absl/strings/ascii_test.cc b/Firestore/third_party/abseil-cpp/absl/strings/ascii_test.cc new file mode 100644 index 0000000..97f3601 --- /dev/null +++ b/Firestore/third_party/abseil-cpp/absl/strings/ascii_test.cc @@ -0,0 +1,354 @@ +// Copyright 2017 The Abseil Authors. +// +// 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. + +#include "absl/strings/ascii.h" + +#include +#include +#include +#include + +#include "gtest/gtest.h" +#include "absl/base/macros.h" +#include "absl/base/port.h" + +namespace { + +TEST(AsciiIsFoo, All) { + for (int i = 0; i < 256; i++) { + if ((i >= 'a' && i <= 'z') || (i >= 'A' && i <= 'Z')) + EXPECT_TRUE(absl::ascii_isalpha(i)) << ": failed on " << i; + else + EXPECT_TRUE(!absl::ascii_isalpha(i)) << ": failed on " << i; + } + for (int i = 0; i < 256; i++) { + if ((i >= '0' && i <= '9')) + EXPECT_TRUE(absl::ascii_isdigit(i)) << ": failed on " << i; + else + EXPECT_TRUE(!absl::ascii_isdigit(i)) << ": failed on " << i; + } + for (int i = 0; i < 256; i++) { + if (absl::ascii_isalpha(i) || absl::ascii_isdigit(i)) + EXPECT_TRUE(absl::ascii_isalnum(i)) << ": failed on " << i; + else + EXPECT_TRUE(!absl::ascii_isalnum(i)) << ": failed on " << i; + } + for (int i = 0; i < 256; i++) { + if (i != '\0' && strchr(" \r\n\t\v\f", i)) + EXPECT_TRUE(absl::ascii_isspace(i)) << ": failed on " << i; + else + EXPECT_TRUE(!absl::ascii_isspace(i)) << ": failed on " << i; + } + for (int i = 0; i < 256; i++) { + if (i >= 32 && i < 127) + EXPECT_TRUE(absl::ascii_isprint(i)) << ": failed on " << i; + else + EXPECT_TRUE(!absl::ascii_isprint(i)) << ": failed on " << i; + } + for (int i = 0; i < 256; i++) { + if (absl::ascii_isprint(i) && !absl::ascii_isspace(i) && + !absl::ascii_isalnum(i)) + EXPECT_TRUE(absl::ascii_ispunct(i)) << ": failed on " << i; + else + EXPECT_TRUE(!absl::ascii_ispunct(i)) << ": failed on " << i; + } + for (int i = 0; i < 256; i++) { + if (i == ' ' || i == '\t') + EXPECT_TRUE(absl::ascii_isblank(i)) << ": failed on " << i; + else + EXPECT_TRUE(!absl::ascii_isblank(i)) << ": failed on " << i; + } + for (int i = 0; i < 256; i++) { + if (i < 32 || i == 127) + EXPECT_TRUE(absl::ascii_iscntrl(i)) << ": failed on " << i; + else + EXPECT_TRUE(!absl::ascii_iscntrl(i)) << ": failed on " << i; + } + for (int i = 0; i < 256; i++) { + if (absl::ascii_isdigit(i) || (i >= 'A' && i <= 'F') || + (i >= 'a' && i <= 'f')) + EXPECT_TRUE(absl::ascii_isxdigit(i)) << ": failed on " << i; + else + EXPECT_TRUE(!absl::ascii_isxdigit(i)) << ": failed on " << i; + } + for (int i = 0; i < 256; i++) { + if (i > 32 && i < 127) + EXPECT_TRUE(absl::ascii_isgraph(i)) << ": failed on " << i; + else + EXPECT_TRUE(!absl::ascii_isgraph(i)) << ": failed on " << i; + } + for (int i = 0; i < 256; i++) { + if (i >= 'A' && i <= 'Z') + EXPECT_TRUE(absl::ascii_isupper(i)) << ": failed on " << i; + else + EXPECT_TRUE(!absl::ascii_isupper(i)) << ": failed on " << i; + } + for (int i = 0; i < 256; i++) { + if (i >= 'a' && i <= 'z') + EXPECT_TRUE(absl::ascii_islower(i)) << ": failed on " << i; + else + EXPECT_TRUE(!absl::ascii_islower(i)) << ": failed on " << i; + } + for (int i = 0; i < 128; i++) { + EXPECT_TRUE(absl::ascii_isascii(i)) << ": failed on " << i; + } + for (int i = 128; i < 256; i++) { + EXPECT_TRUE(!absl::ascii_isascii(i)) << ": failed on " << i; + } + + // The official is* functions don't accept negative signed chars, but + // our absl::ascii_is* functions do. + for (int i = 0; i < 256; i++) { + signed char sc = static_cast(static_cast(i)); + EXPECT_EQ(absl::ascii_isalpha(i), absl::ascii_isalpha(sc)) << i; + EXPECT_EQ(absl::ascii_isdigit(i), absl::ascii_isdigit(sc)) << i; + EXPECT_EQ(absl::ascii_isalnum(i), absl::ascii_isalnum(sc)) << i; + EXPECT_EQ(absl::ascii_isspace(i), absl::ascii_isspace(sc)) << i; + EXPECT_EQ(absl::ascii_ispunct(i), absl::ascii_ispunct(sc)) << i; + EXPECT_EQ(absl::ascii_isblank(i), absl::ascii_isblank(sc)) << i; + EXPECT_EQ(absl::ascii_iscntrl(i), absl::ascii_iscntrl(sc)) << i; + EXPECT_EQ(absl::ascii_isxdigit(i), absl::ascii_isxdigit(sc)) << i; + EXPECT_EQ(absl::ascii_isprint(i), absl::ascii_isprint(sc)) << i; + EXPECT_EQ(absl::ascii_isgraph(i), absl::ascii_isgraph(sc)) << i; + EXPECT_EQ(absl::ascii_isupper(i), absl::ascii_isupper(sc)) << i; + EXPECT_EQ(absl::ascii_islower(i), absl::ascii_islower(sc)) << i; + EXPECT_EQ(absl::ascii_isascii(i), absl::ascii_isascii(sc)) << i; + } +} + +// Checks that absl::ascii_isfoo returns the same value as isfoo in the C +// locale. +TEST(AsciiIsFoo, SameAsIsFoo) { + // temporarily change locale to C. It should already be C, but just for safety + std::string old_locale = setlocale(LC_CTYPE, nullptr); + ASSERT_TRUE(setlocale(LC_CTYPE, "C")); + + for (int i = 0; i < 256; i++) { + EXPECT_EQ(isalpha(i) != 0, absl::ascii_isalpha(i)) << i; + EXPECT_EQ(isdigit(i) != 0, absl::ascii_isdigit(i)) << i; + EXPECT_EQ(isalnum(i) != 0, absl::ascii_isalnum(i)) << i; + EXPECT_EQ(isspace(i) != 0, absl::ascii_isspace(i)) << i; + EXPECT_EQ(ispunct(i) != 0, absl::ascii_ispunct(i)) << i; + EXPECT_EQ(isblank(i) != 0, absl::ascii_isblank(i)) << i; + EXPECT_EQ(iscntrl(i) != 0, absl::ascii_iscntrl(i)) << i; + EXPECT_EQ(isxdigit(i) != 0, absl::ascii_isxdigit(i)) << i; + EXPECT_EQ(isprint(i) != 0, absl::ascii_isprint(i)) << i; + EXPECT_EQ(isgraph(i) != 0, absl::ascii_isgraph(i)) << i; + EXPECT_EQ(isupper(i) != 0, absl::ascii_isupper(i)) << i; + EXPECT_EQ(islower(i) != 0, absl::ascii_islower(i)) << i; + EXPECT_EQ(isascii(i) != 0, absl::ascii_isascii(i)) << i; + } + + // restore the old locale. + ASSERT_TRUE(setlocale(LC_CTYPE, old_locale.c_str())); +} + +TEST(AsciiToFoo, All) { + // temporarily change locale to C. It should already be C, but just for safety + std::string old_locale = setlocale(LC_CTYPE, nullptr); + ASSERT_TRUE(setlocale(LC_CTYPE, "C")); + + for (int i = 0; i < 256; i++) { + if (absl::ascii_islower(i)) + EXPECT_EQ(absl::ascii_toupper(i), 'A' + (i - 'a')) << i; + else + EXPECT_EQ(absl::ascii_toupper(i), static_cast(i)) << i; + + if (absl::ascii_isupper(i)) + EXPECT_EQ(absl::ascii_tolower(i), 'a' + (i - 'A')) << i; + else + EXPECT_EQ(absl::ascii_tolower(i), static_cast(i)) << i; + + // These CHECKs only hold in a C locale. + EXPECT_EQ(static_cast(tolower(i)), absl::ascii_tolower(i)) << i; + EXPECT_EQ(static_cast(toupper(i)), absl::ascii_toupper(i)) << i; + + // The official to* functions don't accept negative signed chars, but + // our absl::ascii_to* functions do. + signed char sc = static_cast(static_cast(i)); + EXPECT_EQ(absl::ascii_tolower(i), absl::ascii_tolower(sc)) << i; + EXPECT_EQ(absl::ascii_toupper(i), absl::ascii_toupper(sc)) << i; + } + + // restore the old locale. + ASSERT_TRUE(setlocale(LC_CTYPE, old_locale.c_str())); +} + +TEST(AsciiStrTo, Lower) { + const char buf[] = "ABCDEF"; + const std::string str("GHIJKL"); + const std::string str2("MNOPQR"); + const absl::string_view sp(str2); + + EXPECT_EQ("abcdef", absl::AsciiStrToLower(buf)); + EXPECT_EQ("ghijkl", absl::AsciiStrToLower(str)); + EXPECT_EQ("mnopqr", absl::AsciiStrToLower(sp)); + + char mutable_buf[] = "Mutable"; + std::transform(mutable_buf, mutable_buf + strlen(mutable_buf), + mutable_buf, absl::ascii_tolower); + EXPECT_STREQ("mutable", mutable_buf); +} + +TEST(AsciiStrTo, Upper) { + const char buf[] = "abcdef"; + const std::string str("ghijkl"); + const std::string str2("mnopqr"); + const absl::string_view sp(str2); + + EXPECT_EQ("ABCDEF", absl::AsciiStrToUpper(buf)); + EXPECT_EQ("GHIJKL", absl::AsciiStrToUpper(str)); + EXPECT_EQ("MNOPQR", absl::AsciiStrToUpper(sp)); + + char mutable_buf[] = "Mutable"; + std::transform(mutable_buf, mutable_buf + strlen(mutable_buf), + mutable_buf, absl::ascii_toupper); + EXPECT_STREQ("MUTABLE", mutable_buf); +} + +TEST(StripLeadingAsciiWhitespace, FromStringView) { + EXPECT_EQ(absl::string_view{}, + absl::StripLeadingAsciiWhitespace(absl::string_view{})); + EXPECT_EQ("foo", absl::StripLeadingAsciiWhitespace({"foo"})); + EXPECT_EQ("foo", absl::StripLeadingAsciiWhitespace({"\t \n\f\r\n\vfoo"})); + EXPECT_EQ("foo foo\n ", + absl::StripLeadingAsciiWhitespace({"\t \n\f\r\n\vfoo foo\n "})); + EXPECT_EQ(absl::string_view{}, absl::StripLeadingAsciiWhitespace( + {"\t \n\f\r\v\n\t \n\f\r\v\n"})); +} + +TEST(StripLeadingAsciiWhitespace, InPlace) { + std::string str; + + absl::StripLeadingAsciiWhitespace(&str); + EXPECT_EQ("", str); + + str = "foo"; + absl::StripLeadingAsciiWhitespace(&str); + EXPECT_EQ("foo", str); + + str = "\t \n\f\r\n\vfoo"; + absl::StripLeadingAsciiWhitespace(&str); + EXPECT_EQ("foo", str); + + str = "\t \n\f\r\n\vfoo foo\n "; + absl::StripLeadingAsciiWhitespace(&str); + EXPECT_EQ("foo foo\n ", str); + + str = "\t \n\f\r\v\n\t \n\f\r\v\n"; + absl::StripLeadingAsciiWhitespace(&str); + EXPECT_EQ(absl::string_view{}, str); +} + +TEST(StripTrailingAsciiWhitespace, FromStringView) { + EXPECT_EQ(absl::string_view{}, + absl::StripTrailingAsciiWhitespace(absl::string_view{})); + EXPECT_EQ("foo", absl::StripTrailingAsciiWhitespace({"foo"})); + EXPECT_EQ("foo", absl::StripTrailingAsciiWhitespace({"foo\t \n\f\r\n\v"})); + EXPECT_EQ(" \nfoo foo", + absl::StripTrailingAsciiWhitespace({" \nfoo foo\t \n\f\r\n\v"})); + EXPECT_EQ(absl::string_view{}, absl::StripTrailingAsciiWhitespace( + {"\t \n\f\r\v\n\t \n\f\r\v\n"})); +} + +TEST(StripTrailingAsciiWhitespace, InPlace) { + std::string str; + + absl::StripTrailingAsciiWhitespace(&str); + EXPECT_EQ("", str); + + str = "foo"; + absl::StripTrailingAsciiWhitespace(&str); + EXPECT_EQ("foo", str); + + str = "foo\t \n\f\r\n\v"; + absl::StripTrailingAsciiWhitespace(&str); + EXPECT_EQ("foo", str); + + str = " \nfoo foo\t \n\f\r\n\v"; + absl::StripTrailingAsciiWhitespace(&str); + EXPECT_EQ(" \nfoo foo", str); + + str = "\t \n\f\r\v\n\t \n\f\r\v\n"; + absl::StripTrailingAsciiWhitespace(&str); + EXPECT_EQ(absl::string_view{}, str); +} + +TEST(StripAsciiWhitespace, FromStringView) { + EXPECT_EQ(absl::string_view{}, + absl::StripAsciiWhitespace(absl::string_view{})); + EXPECT_EQ("foo", absl::StripAsciiWhitespace({"foo"})); + EXPECT_EQ("foo", + absl::StripAsciiWhitespace({"\t \n\f\r\n\vfoo\t \n\f\r\n\v"})); + EXPECT_EQ("foo foo", absl::StripAsciiWhitespace( + {"\t \n\f\r\n\vfoo foo\t \n\f\r\n\v"})); + EXPECT_EQ(absl::string_view{}, + absl::StripAsciiWhitespace({"\t \n\f\r\v\n\t \n\f\r\v\n"})); +} + +TEST(StripAsciiWhitespace, InPlace) { + std::string str; + + absl::StripAsciiWhitespace(&str); + EXPECT_EQ("", str); + + str = "foo"; + absl::StripAsciiWhitespace(&str); + EXPECT_EQ("foo", str); + + str = "\t \n\f\r\n\vfoo\t \n\f\r\n\v"; + absl::StripAsciiWhitespace(&str); + EXPECT_EQ("foo", str); + + str = "\t \n\f\r\n\vfoo foo\t \n\f\r\n\v"; + absl::StripAsciiWhitespace(&str); + EXPECT_EQ("foo foo", str); + + str = "\t \n\f\r\v\n\t \n\f\r\v\n"; + absl::StripAsciiWhitespace(&str); + EXPECT_EQ(absl::string_view{}, str); +} + +TEST(RemoveExtraAsciiWhitespace, InPlace) { + const char* inputs[] = {"No extra space", + " Leading whitespace", + "Trailing whitespace ", + " Leading and trailing ", + " Whitespace \t in\v middle ", + "'Eeeeep! \n Newlines!\n", + "nospaces", + "", + "\n\t a\t\n\nb \t\n"}; + + const char* outputs[] = { + "No extra space", + "Leading whitespace", + "Trailing whitespace", + "Leading and trailing", + "Whitespace in middle", + "'Eeeeep! Newlines!", + "nospaces", + "", + "a\nb", + }; + const int NUM_TESTS = ABSL_ARRAYSIZE(inputs); + + for (int i = 0; i < NUM_TESTS; i++) { + std::string s(inputs[i]); + absl::RemoveExtraAsciiWhitespace(&s); + EXPECT_EQ(outputs[i], s); + } +} + +} // namespace diff --git a/Firestore/third_party/abseil-cpp/absl/strings/internal/memutil.cc b/Firestore/third_party/abseil-cpp/absl/strings/internal/memutil.cc new file mode 100644 index 0000000..a0de70d --- /dev/null +++ b/Firestore/third_party/abseil-cpp/absl/strings/internal/memutil.cc @@ -0,0 +1,110 @@ +// Copyright 2017 The Abseil Authors. +// +// 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. + +#include "absl/strings/internal/memutil.h" + +#include + +namespace absl { +namespace strings_internal { + +int memcasecmp(const char* s1, const char* s2, size_t len) { + const unsigned char* us1 = reinterpret_cast(s1); + const unsigned char* us2 = reinterpret_cast(s2); + + for (size_t i = 0; i < len; i++) { + const int diff = + int{static_cast(absl::ascii_tolower(us1[i]))} - + int{static_cast(absl::ascii_tolower(us2[i]))}; + if (diff != 0) return diff; + } + return 0; +} + +char* memdup(const char* s, size_t slen) { + void* copy; + if ((copy = malloc(slen)) == nullptr) return nullptr; + memcpy(copy, s, slen); + return reinterpret_cast(copy); +} + +char* memrchr(const char* s, int c, size_t slen) { + for (const char* e = s + slen - 1; e >= s; e--) { + if (*e == c) return const_cast(e); + } + return nullptr; +} + +size_t memspn(const char* s, size_t slen, const char* accept) { + const char* p = s; + const char* spanp; + char c, sc; + +cont: + c = *p++; + if (slen-- == 0) return p - 1 - s; + for (spanp = accept; (sc = *spanp++) != '\0';) + if (sc == c) goto cont; + return p - 1 - s; +} + +size_t memcspn(const char* s, size_t slen, const char* reject) { + const char* p = s; + const char* spanp; + char c, sc; + + while (slen-- != 0) { + c = *p++; + for (spanp = reject; (sc = *spanp++) != '\0';) + if (sc == c) return p - 1 - s; + } + return p - s; +} + +char* mempbrk(const char* s, size_t slen, const char* accept) { + const char* scanp; + int sc; + + for (; slen; ++s, --slen) { + for (scanp = accept; (sc = *scanp++) != '\0';) + if (sc == *s) return const_cast(s); + } + return nullptr; +} + +// This is significantly faster for case-sensitive matches with very +// few possible matches. See unit test for benchmarks. +const char* memmatch(const char* phaystack, size_t haylen, const char* pneedle, + size_t neelen) { + if (0 == neelen) { + return phaystack; // even if haylen is 0 + } + if (haylen < neelen) return nullptr; + + const char* match; + const char* hayend = phaystack + haylen - neelen + 1; + // A static cast is used here to work around the fact that memchr returns + // a void* on Posix-compliant systems and const void* on Windows. + while ((match = static_cast( + memchr(phaystack, pneedle[0], hayend - phaystack)))) { + if (memcmp(match, pneedle, neelen) == 0) + return match; + else + phaystack = match + 1; + } + return nullptr; +} + +} // namespace strings_internal +} // namespace absl diff --git a/Firestore/third_party/abseil-cpp/absl/strings/internal/memutil.h b/Firestore/third_party/abseil-cpp/absl/strings/internal/memutil.h new file mode 100644 index 0000000..a6f1c69 --- /dev/null +++ b/Firestore/third_party/abseil-cpp/absl/strings/internal/memutil.h @@ -0,0 +1,146 @@ +// +// Copyright 2017 The Abseil Authors. +// +// 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. +// + +// These routines provide mem versions of standard C std::string routines, +// such as strpbrk. They function exactly the same as the str versions, +// so if you wonder what they are, replace the word "mem" by +// "str" and check out the man page. I could return void*, as the +// strutil.h mem*() routines tend to do, but I return char* instead +// since this is by far the most common way these functions are called. +// +// The difference between the mem and str versions is the mem version +// takes a pointer and a length, rather than a '\0'-terminated std::string. +// The memcase* routines defined here assume the locale is "C" +// (they use absl::ascii_tolower instead of tolower). +// +// These routines are based on the BSD library. +// +// Here's a list of routines from std::string.h, and their mem analogues. +// Functions in lowercase are defined in std::string.h; those in UPPERCASE +// are defined here: +// +// strlen -- +// strcat strncat MEMCAT +// strcpy strncpy memcpy +// -- memccpy (very cool function, btw) +// -- memmove +// -- memset +// strcmp strncmp memcmp +// strcasecmp strncasecmp MEMCASECMP +// strchr memchr +// strcoll -- +// strxfrm -- +// strdup strndup MEMDUP +// strrchr MEMRCHR +// strspn MEMSPN +// strcspn MEMCSPN +// strpbrk MEMPBRK +// strstr MEMSTR MEMMEM +// (g)strcasestr MEMCASESTR MEMCASEMEM +// strtok -- +// strprefix MEMPREFIX (strprefix is from strutil.h) +// strcaseprefix MEMCASEPREFIX (strcaseprefix is from strutil.h) +// strsuffix MEMSUFFIX (strsuffix is from strutil.h) +// strcasesuffix MEMCASESUFFIX (strcasesuffix is from strutil.h) +// -- MEMIS +// -- MEMCASEIS +// strcount MEMCOUNT (strcount is from strutil.h) + +#ifndef ABSL_STRINGS_INTERNAL_MEMUTIL_H_ +#define ABSL_STRINGS_INTERNAL_MEMUTIL_H_ + +#include +#include + +#include "absl/base/port.h" // disable some warnings on Windows +#include "absl/strings/ascii.h" // for absl::ascii_tolower + +namespace absl { +namespace strings_internal { + +inline char* memcat(char* dest, size_t destlen, const char* src, + size_t srclen) { + return reinterpret_cast(memcpy(dest + destlen, src, srclen)); +} + +int memcasecmp(const char* s1, const char* s2, size_t len); +char* memdup(const char* s, size_t slen); +char* memrchr(const char* s, int c, size_t slen); +size_t memspn(const char* s, size_t slen, const char* accept); +size_t memcspn(const char* s, size_t slen, const char* reject); +char* mempbrk(const char* s, size_t slen, const char* accept); + +// This is for internal use only. Don't call this directly +template +const char* int_memmatch(const char* haystack, size_t haylen, + const char* needle, size_t neelen) { + if (0 == neelen) { + return haystack; // even if haylen is 0 + } + const char* hayend = haystack + haylen; + const char* needlestart = needle; + const char* needleend = needlestart + neelen; + + for (; haystack < hayend; ++haystack) { + char hay = case_sensitive + ? *haystack + : absl::ascii_tolower(static_cast(*haystack)); + char nee = case_sensitive + ? *needle + : absl::ascii_tolower(static_cast(*needle)); + if (hay == nee) { + if (++needle == needleend) { + return haystack + 1 - neelen; + } + } else if (needle != needlestart) { + // must back up haystack in case a prefix matched (find "aab" in "aaab") + haystack -= needle - needlestart; // for loop will advance one more + needle = needlestart; + } + } + return nullptr; +} + +// These are the guys you can call directly +inline const char* memstr(const char* phaystack, size_t haylen, + const char* pneedle) { + return int_memmatch(phaystack, haylen, pneedle, strlen(pneedle)); +} + +inline const char* memcasestr(const char* phaystack, size_t haylen, + const char* pneedle) { + return int_memmatch(phaystack, haylen, pneedle, strlen(pneedle)); +} + +inline const char* memmem(const char* phaystack, size_t haylen, + const char* pneedle, size_t needlelen) { + return int_memmatch(phaystack, haylen, pneedle, needlelen); +} + +inline const char* memcasemem(const char* phaystack, size_t haylen, + const char* pneedle, size_t needlelen) { + return int_memmatch(phaystack, haylen, pneedle, needlelen); +} + +// This is significantly faster for case-sensitive matches with very +// few possible matches. See unit test for benchmarks. +const char* memmatch(const char* phaystack, size_t haylen, const char* pneedle, + size_t neelen); + +} // namespace strings_internal +} // namespace absl + +#endif // ABSL_STRINGS_INTERNAL_MEMUTIL_H_ diff --git a/Firestore/third_party/abseil-cpp/absl/strings/internal/memutil_test.cc b/Firestore/third_party/abseil-cpp/absl/strings/internal/memutil_test.cc new file mode 100644 index 0000000..09424de --- /dev/null +++ b/Firestore/third_party/abseil-cpp/absl/strings/internal/memutil_test.cc @@ -0,0 +1,179 @@ +// Copyright 2017 The Abseil Authors. +// +// 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. + +// Unit test for memutil.cc + +#include "absl/strings/internal/memutil.h" + +#include + +#include "gtest/gtest.h" +#include "absl/strings/ascii.h" + +namespace { + +static char* memcasechr(const char* s, int c, size_t slen) { + c = absl::ascii_tolower(c); + for (; slen; ++s, --slen) { + if (absl::ascii_tolower(*s) == c) return const_cast(s); + } + return nullptr; +} + +static const char* memcasematch(const char* phaystack, size_t haylen, + const char* pneedle, size_t neelen) { + if (0 == neelen) { + return phaystack; // even if haylen is 0 + } + if (haylen < neelen) return nullptr; + + const char* match; + const char* hayend = phaystack + haylen - neelen + 1; + while ((match = static_cast( + memcasechr(phaystack, pneedle[0], hayend - phaystack)))) { + if (absl::strings_internal::memcasecmp(match, pneedle, neelen) == 0) + return match; + else + phaystack = match + 1; + } + return nullptr; +} + +TEST(MemUtilTest, AllTests) { + // check memutil functions + char a[1000]; + absl::strings_internal::memcat(a, 0, "hello", sizeof("hello") - 1); + absl::strings_internal::memcat(a, 5, " there", sizeof(" there") - 1); + + EXPECT_EQ(absl::strings_internal::memcasecmp(a, "heLLO there", + sizeof("hello there") - 1), + 0); + EXPECT_EQ(absl::strings_internal::memcasecmp(a, "heLLO therf", + sizeof("hello there") - 1), + -1); + EXPECT_EQ(absl::strings_internal::memcasecmp(a, "heLLO therf", + sizeof("hello there") - 2), + 0); + EXPECT_EQ(absl::strings_internal::memcasecmp(a, "whatever", 0), 0); + + char* p = absl::strings_internal::memdup("hello", 5); + free(p); + + p = absl::strings_internal::memrchr("hello there", 'e', + sizeof("hello there") - 1); + EXPECT_TRUE(p && p[-1] == 'r'); + p = absl::strings_internal::memrchr("hello there", 'e', + sizeof("hello there") - 2); + EXPECT_TRUE(p && p[-1] == 'h'); + p = absl::strings_internal::memrchr("hello there", 'u', + sizeof("hello there") - 1); + EXPECT_TRUE(p == nullptr); + + int len = absl::strings_internal::memspn("hello there", + sizeof("hello there") - 1, "hole"); + EXPECT_EQ(len, sizeof("hello") - 1); + len = absl::strings_internal::memspn("hello there", sizeof("hello there") - 1, + "u"); + EXPECT_EQ(len, 0); + len = absl::strings_internal::memspn("hello there", sizeof("hello there") - 1, + ""); + EXPECT_EQ(len, 0); + len = absl::strings_internal::memspn("hello there", sizeof("hello there") - 1, + "trole h"); + EXPECT_EQ(len, sizeof("hello there") - 1); + len = absl::strings_internal::memspn("hello there!", + sizeof("hello there!") - 1, "trole h"); + EXPECT_EQ(len, sizeof("hello there") - 1); + len = absl::strings_internal::memspn("hello there!", + sizeof("hello there!") - 2, "trole h!"); + EXPECT_EQ(len, sizeof("hello there!") - 2); + + len = absl::strings_internal::memcspn("hello there", + sizeof("hello there") - 1, "leho"); + EXPECT_EQ(len, 0); + len = absl::strings_internal::memcspn("hello there", + sizeof("hello there") - 1, "u"); + EXPECT_EQ(len, sizeof("hello there") - 1); + len = absl::strings_internal::memcspn("hello there", + sizeof("hello there") - 1, ""); + EXPECT_EQ(len, sizeof("hello there") - 1); + len = absl::strings_internal::memcspn("hello there", + sizeof("hello there") - 1, " "); + EXPECT_EQ(len, 5); + + p = absl::strings_internal::mempbrk("hello there", sizeof("hello there") - 1, + "leho"); + EXPECT_TRUE(p && p[1] == 'e' && p[2] == 'l'); + p = absl::strings_internal::mempbrk("hello there", sizeof("hello there") - 1, + "nu"); + EXPECT_TRUE(p == nullptr); + p = absl::strings_internal::mempbrk("hello there!", + sizeof("hello there!") - 2, "!"); + EXPECT_TRUE(p == nullptr); + p = absl::strings_internal::mempbrk("hello there", sizeof("hello there") - 1, + " t "); + EXPECT_TRUE(p && p[-1] == 'o' && p[1] == 't'); + + { + const char kHaystack[] = "0123456789"; + EXPECT_EQ(absl::strings_internal::memmem(kHaystack, 0, "", 0), kHaystack); + EXPECT_EQ(absl::strings_internal::memmem(kHaystack, 10, "012", 3), + kHaystack); + EXPECT_EQ(absl::strings_internal::memmem(kHaystack, 10, "0xx", 1), + kHaystack); + EXPECT_EQ(absl::strings_internal::memmem(kHaystack, 10, "789", 3), + kHaystack + 7); + EXPECT_EQ(absl::strings_internal::memmem(kHaystack, 10, "9xx", 1), + kHaystack + 9); + EXPECT_TRUE(absl::strings_internal::memmem(kHaystack, 10, "9xx", 3) == + nullptr); + EXPECT_TRUE(absl::strings_internal::memmem(kHaystack, 10, "xxx", 1) == + nullptr); + } + { + const char kHaystack[] = "aBcDeFgHiJ"; + EXPECT_EQ(absl::strings_internal::memcasemem(kHaystack, 0, "", 0), + kHaystack); + EXPECT_EQ(absl::strings_internal::memcasemem(kHaystack, 10, "Abc", 3), + kHaystack); + EXPECT_EQ(absl::strings_internal::memcasemem(kHaystack, 10, "Axx", 1), + kHaystack); + EXPECT_EQ(absl::strings_internal::memcasemem(kHaystack, 10, "hIj", 3), + kHaystack + 7); + EXPECT_EQ(absl::strings_internal::memcasemem(kHaystack, 10, "jxx", 1), + kHaystack + 9); + EXPECT_TRUE(absl::strings_internal::memcasemem(kHaystack, 10, "jxx", 3) == + nullptr); + EXPECT_TRUE(absl::strings_internal::memcasemem(kHaystack, 10, "xxx", 1) == + nullptr); + } + { + const char kHaystack[] = "0123456789"; + EXPECT_EQ(absl::strings_internal::memmatch(kHaystack, 0, "", 0), kHaystack); + EXPECT_EQ(absl::strings_internal::memmatch(kHaystack, 10, "012", 3), + kHaystack); + EXPECT_EQ(absl::strings_internal::memmatch(kHaystack, 10, "0xx", 1), + kHaystack); + EXPECT_EQ(absl::strings_internal::memmatch(kHaystack, 10, "789", 3), + kHaystack + 7); + EXPECT_EQ(absl::strings_internal::memmatch(kHaystack, 10, "9xx", 1), + kHaystack + 9); + EXPECT_TRUE(absl::strings_internal::memmatch(kHaystack, 10, "9xx", 3) == + nullptr); + EXPECT_TRUE(absl::strings_internal::memmatch(kHaystack, 10, "xxx", 1) == + nullptr); + } +} + +} // namespace diff --git a/Firestore/third_party/abseil-cpp/absl/strings/internal/resize_uninitialized.h b/Firestore/third_party/abseil-cpp/absl/strings/internal/resize_uninitialized.h new file mode 100644 index 0000000..0157ca0 --- /dev/null +++ b/Firestore/third_party/abseil-cpp/absl/strings/internal/resize_uninitialized.h @@ -0,0 +1,69 @@ +// +// Copyright 2017 The Abseil Authors. +// +// 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. +// + +#ifndef ABSL_STRINGS_INTERNAL_RESIZE_UNINITIALIZED_H_ +#define ABSL_STRINGS_INTERNAL_RESIZE_UNINITIALIZED_H_ + +#include +#include + +#include "absl/base/port.h" +#include "absl/meta/type_traits.h" // for void_t + +namespace absl { +namespace strings_internal { + +// Is a subclass of true_type or false_type, depending on whether or not +// T has a resize_uninitialized member. +template +struct HasResizeUninitialized : std::false_type {}; +template +struct HasResizeUninitialized< + T, absl::void_t().resize_uninitialized(237))>> + : std::true_type {}; + +template +void ResizeUninit(string_type* s, size_t new_size, std::true_type) { + s->resize_uninitialized(new_size); +} +template +void ResizeUninit(string_type* s, size_t new_size, std::false_type) { + s->resize(new_size); +} + +// Returns true if the std::string implementation supports a resize where +// the new characters added to the std::string are left untouched. +// +// (A better name might be "STLStringSupportsUninitializedResize", alluding to +// the previous function.) +template +inline constexpr bool STLStringSupportsNontrashingResize(string_type*) { + return HasResizeUninitialized(); +} + +// Like str->resize(new_size), except any new characters added to "*str" as a +// result of resizing may be left uninitialized, rather than being filled with +// '0' bytes. Typically used when code is then going to overwrite the backing +// store of the std::string with known data. Uses a Google extension to std::string. +template +inline void STLStringResizeUninitialized(string_type* s, size_t new_size) { + ResizeUninit(s, new_size, HasResizeUninitialized()); +} + +} // namespace strings_internal +} // namespace absl + +#endif // ABSL_STRINGS_INTERNAL_RESIZE_UNINITIALIZED_H_ diff --git a/Firestore/third_party/abseil-cpp/absl/strings/internal/resize_uninitialized_test.cc b/Firestore/third_party/abseil-cpp/absl/strings/internal/resize_uninitialized_test.cc new file mode 100644 index 0000000..ad282ef --- /dev/null +++ b/Firestore/third_party/abseil-cpp/absl/strings/internal/resize_uninitialized_test.cc @@ -0,0 +1,68 @@ +// Copyright 2017 The Abseil Authors. +// +// 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. + +#include "absl/strings/internal/resize_uninitialized.h" + +#include "gtest/gtest.h" + +namespace { + +int resize_call_count = 0; + +struct resizable_string { + void resize(size_t) { resize_call_count += 1; } +}; + +int resize_uninitialized_call_count = 0; + +struct resize_uninitializable_string { + void resize(size_t) { resize_call_count += 1; } + void resize_uninitialized(size_t) { resize_uninitialized_call_count += 1; } +}; + +TEST(ResizeUninit, WithAndWithout) { + resize_call_count = 0; + resize_uninitialized_call_count = 0; + { + resizable_string rs; + + EXPECT_EQ(resize_call_count, 0); + EXPECT_EQ(resize_uninitialized_call_count, 0); + EXPECT_FALSE( + absl::strings_internal::STLStringSupportsNontrashingResize(&rs)); + EXPECT_EQ(resize_call_count, 0); + EXPECT_EQ(resize_uninitialized_call_count, 0); + absl::strings_internal::STLStringResizeUninitialized(&rs, 237); + EXPECT_EQ(resize_call_count, 1); + EXPECT_EQ(resize_uninitialized_call_count, 0); + } + + resize_call_count = 0; + resize_uninitialized_call_count = 0; + { + resize_uninitializable_string rus; + + EXPECT_EQ(resize_call_count, 0); + EXPECT_EQ(resize_uninitialized_call_count, 0); + EXPECT_TRUE( + absl::strings_internal::STLStringSupportsNontrashingResize(&rus)); + EXPECT_EQ(resize_call_count, 0); + EXPECT_EQ(resize_uninitialized_call_count, 0); + absl::strings_internal::STLStringResizeUninitialized(&rus, 237); + EXPECT_EQ(resize_call_count, 0); + EXPECT_EQ(resize_uninitialized_call_count, 1); + } +} + +} // namespace diff --git a/Firestore/third_party/abseil-cpp/absl/strings/match.cc b/Firestore/third_party/abseil-cpp/absl/strings/match.cc new file mode 100644 index 0000000..25bd7f0 --- /dev/null +++ b/Firestore/third_party/abseil-cpp/absl/strings/match.cc @@ -0,0 +1,40 @@ +// Copyright 2017 The Abseil Authors. +// +// 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. + +#include "absl/strings/match.h" + +#include "absl/strings/internal/memutil.h" + +namespace absl { + +namespace { +bool CaseEqual(absl::string_view piece1, absl::string_view piece2) { + return (piece1.size() == piece2.size() && + 0 == strings_internal::memcasecmp(piece1.data(), piece2.data(), + piece1.size())); + // memcasecmp uses ascii_tolower(). +} +} // namespace + +bool StartsWithIgnoreCase(absl::string_view text, absl::string_view prefix) { + return (text.size() >= prefix.size()) && + CaseEqual(text.substr(0, prefix.size()), prefix); +} + +bool EndsWithIgnoreCase(absl::string_view text, absl::string_view suffix) { + return (text.size() >= suffix.size()) && + CaseEqual(text.substr(text.size() - suffix.size()), suffix); +} + +} // namespace absl diff --git a/Firestore/third_party/abseil-cpp/absl/strings/match.h b/Firestore/third_party/abseil-cpp/absl/strings/match.h new file mode 100644 index 0000000..6005533 --- /dev/null +++ b/Firestore/third_party/abseil-cpp/absl/strings/match.h @@ -0,0 +1,84 @@ +// +// Copyright 2017 The Abseil Authors. +// +// 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. +// +// ----------------------------------------------------------------------------- +// File: match.h +// ----------------------------------------------------------------------------- +// +// This file contains simple utilities for performing std::string matching checks. +// All of these function parameters are specified as `absl::string_view`, +// meaning that these functions can accept `std::string`, `absl::string_view` or +// nul-terminated C-style strings. +// +// Examples: +// std::string s = "foo"; +// absl::string_view sv = "f"; +// assert(absl::StrContains(s, sv)); +// +// Note: The order of parameters in these functions is designed to mimic the +// order an equivalent member function would exhibit; +// e.g. `s.Contains(x)` ==> `absl::StrContains(s, x). +#ifndef ABSL_STRINGS_MATCH_H_ +#define ABSL_STRINGS_MATCH_H_ + +#include + +#include "absl/strings/string_view.h" + +namespace absl { + +// StrContains() +// +// Returns whether a given std::string `haystack` contains the substring `needle`. +inline bool StrContains(absl::string_view haystack, absl::string_view needle) { + return static_cast(haystack.find(needle, 0)) != + haystack.npos; +} + +// StartsWith() +// +// Returns whether a given std::string `text` begins with `prefix`. +inline bool StartsWith(absl::string_view text, absl::string_view prefix) { + return prefix.empty() || + (text.size() >= prefix.size() && + memcmp(text.data(), prefix.data(), prefix.size()) == 0); +} + +// EndsWith() +// +// Returns whether a given std::string `text` ends with `suffix`. +inline bool EndsWith(absl::string_view text, absl::string_view suffix) { + return suffix.empty() || + (text.size() >= suffix.size() && + memcmp(text.data() + (text.size() - suffix.size()), suffix.data(), + suffix.size()) == 0 + ); +} + +// StartsWithIgnoreCase() +// +// Returns whether a given std::string `text` starts with `starts_with`, ignoring +// case in the comparison. +bool StartsWithIgnoreCase(absl::string_view text, absl::string_view prefix); + +// EndsWithIgnoreCase() +// +// Returns whether a given std::string `text` ends with `ends_with`, ignoring case +// in the comparison. +bool EndsWithIgnoreCase(absl::string_view text, absl::string_view suffix); + +} // namespace absl + +#endif // ABSL_STRINGS_MATCH_H_ diff --git a/Firestore/third_party/abseil-cpp/absl/strings/match_test.cc b/Firestore/third_party/abseil-cpp/absl/strings/match_test.cc new file mode 100644 index 0000000..d194f0e --- /dev/null +++ b/Firestore/third_party/abseil-cpp/absl/strings/match_test.cc @@ -0,0 +1,99 @@ +// Copyright 2017 The Abseil Authors. +// +// 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. + +#include "absl/strings/match.h" + +#include "gtest/gtest.h" + +namespace { + +TEST(MatchTest, StartsWith) { + const std::string s1("123" "\0" "456", 7); + const absl::string_view a("foobar"); + const absl::string_view b(s1); + const absl::string_view e; + EXPECT_TRUE(absl::StartsWith(a, a)); + EXPECT_TRUE(absl::StartsWith(a, "foo")); + EXPECT_TRUE(absl::StartsWith(a, e)); + EXPECT_TRUE(absl::StartsWith(b, s1)); + EXPECT_TRUE(absl::StartsWith(b, b)); + EXPECT_TRUE(absl::StartsWith(b, e)); + EXPECT_TRUE(absl::StartsWith(e, "")); + EXPECT_FALSE(absl::StartsWith(a, b)); + EXPECT_FALSE(absl::StartsWith(b, a)); + EXPECT_FALSE(absl::StartsWith(e, a)); +} + +TEST(MatchTest, EndsWith) { + const std::string s1("123" "\0" "456", 7); + const absl::string_view a("foobar"); + const absl::string_view b(s1); + const absl::string_view e; + EXPECT_TRUE(absl::EndsWith(a, a)); + EXPECT_TRUE(absl::EndsWith(a, "bar")); + EXPECT_TRUE(absl::EndsWith(a, e)); + EXPECT_TRUE(absl::EndsWith(b, s1)); + EXPECT_TRUE(absl::EndsWith(b, b)); + EXPECT_TRUE(absl::EndsWith(b, e)); + EXPECT_TRUE(absl::EndsWith(e, "")); + EXPECT_FALSE(absl::EndsWith(a, b)); + EXPECT_FALSE(absl::EndsWith(b, a)); + EXPECT_FALSE(absl::EndsWith(e, a)); +} + +TEST(MatchTest, Contains) { + absl::string_view a("abcdefg"); + absl::string_view b("abcd"); + absl::string_view c("efg"); + absl::string_view d("gh"); + EXPECT_TRUE(absl::StrContains(a, a)); + EXPECT_TRUE(absl::StrContains(a, b)); + EXPECT_TRUE(absl::StrContains(a, c)); + EXPECT_FALSE(absl::StrContains(a, d)); + EXPECT_TRUE(absl::StrContains("", "")); + EXPECT_TRUE(absl::StrContains("abc", "")); + EXPECT_FALSE(absl::StrContains("", "a")); +} + +TEST(MatchTest, ContainsNull) { + const std::string s = "foo"; + const char* cs = "foo"; + const absl::string_view sv("foo"); + const absl::string_view sv2("foo\0bar", 4); + EXPECT_EQ(s, "foo"); + EXPECT_EQ(sv, "foo"); + EXPECT_NE(sv2, "foo"); + EXPECT_TRUE(absl::EndsWith(s, sv)); + EXPECT_TRUE(absl::StartsWith(cs, sv)); + EXPECT_TRUE(absl::StrContains(cs, sv)); + EXPECT_FALSE(absl::StrContains(cs, sv2)); +} + +TEST(MatchTest, StartsWithIgnoreCase) { + EXPECT_TRUE(absl::StartsWithIgnoreCase("foo", "foo")); + EXPECT_TRUE(absl::StartsWithIgnoreCase("foo", "Fo")); + EXPECT_TRUE(absl::StartsWithIgnoreCase("foo", "")); + EXPECT_FALSE(absl::StartsWithIgnoreCase("foo", "fooo")); + EXPECT_FALSE(absl::StartsWithIgnoreCase("", "fo")); +} + +TEST(MatchTest, EndsWithIgnoreCase) { + EXPECT_TRUE(absl::EndsWithIgnoreCase("foo", "foo")); + EXPECT_TRUE(absl::EndsWithIgnoreCase("foo", "Oo")); + EXPECT_TRUE(absl::EndsWithIgnoreCase("foo", "")); + EXPECT_FALSE(absl::EndsWithIgnoreCase("foo", "fooo")); + EXPECT_FALSE(absl::EndsWithIgnoreCase("", "fo")); +} + +} // namespace diff --git a/Firestore/third_party/abseil-cpp/absl/strings/string_view.cc b/Firestore/third_party/abseil-cpp/absl/strings/string_view.cc new file mode 100644 index 0000000..0e17295 --- /dev/null +++ b/Firestore/third_party/abseil-cpp/absl/strings/string_view.cc @@ -0,0 +1,247 @@ +// Copyright 2017 The Abseil Authors. +// +// 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. + +#include "absl/strings/string_view.h" + +#ifndef ABSL_HAVE_STD_STRING_VIEW + +#include +#include +#include +#include + +#include "absl/strings/internal/memutil.h" +#include "absl/strings/internal/resize_uninitialized.h" +#include "absl/strings/match.h" + +namespace absl { + +namespace { +void WritePadding(std::ostream& o, size_t pad) { + char fill_buf[32]; + memset(fill_buf, o.fill(), sizeof(fill_buf)); + while (pad) { + size_t n = std::min(pad, sizeof(fill_buf)); + o.write(fill_buf, n); + pad -= n; + } +} + +class LookupTable { + public: + // For each character in wanted, sets the index corresponding + // to the ASCII code of that character. This is used by + // the find_.*_of methods below to tell whether or not a character is in + // the lookup table in constant time. + explicit LookupTable(string_view wanted) { + for (char c : wanted) { + table_[Index(c)] = true; + } + } + bool operator[](char c) const { return table_[Index(c)]; } + + private: + static unsigned char Index(char c) { return static_cast(c); } + bool table_[UCHAR_MAX + 1] = {}; +}; + +} // namespace + +std::ostream& operator<<(std::ostream& o, string_view piece) { + std::ostream::sentry sentry(o); + if (sentry) { + size_t lpad = 0; + size_t rpad = 0; + if (static_cast(o.width()) > piece.size()) { + size_t pad = o.width() - piece.size(); + if ((o.flags() & o.adjustfield) == o.left) { + rpad = pad; + } else { + lpad = pad; + } + } + if (lpad) WritePadding(o, lpad); + o.write(piece.data(), piece.size()); + if (rpad) WritePadding(o, rpad); + o.width(0); + } + return o; +} + +string_view::size_type string_view::copy(char* buf, size_type n, + size_type pos) const { + size_type ulen = length_; + assert(pos <= ulen); + size_type rlen = std::min(ulen - pos, n); + if (rlen > 0) { + const char* start = ptr_ + pos; + std::copy(start, start + rlen, buf); + } + return rlen; +} + +string_view::size_type string_view::find(string_view s, size_type pos) const + noexcept { + if (empty() || pos > length_) { + if (empty() && pos == 0 && s.empty()) return 0; + return npos; + } + const char* result = + strings_internal::memmatch(ptr_ + pos, length_ - pos, s.ptr_, s.length_); + return result ? result - ptr_ : npos; +} + +string_view::size_type string_view::find(char c, size_type pos) const noexcept { + if (empty() || pos >= length_) { + return npos; + } + const char* result = + static_cast(memchr(ptr_ + pos, c, length_ - pos)); + return result != nullptr ? result - ptr_ : npos; +} + +string_view::size_type string_view::rfind(string_view s, size_type pos) const + noexcept { + if (length_ < s.length_) return npos; + if (s.empty()) return std::min(length_, pos); + const char* last = ptr_ + std::min(length_ - s.length_, pos) + s.length_; + const char* result = std::find_end(ptr_, last, s.ptr_, s.ptr_ + s.length_); + return result != last ? result - ptr_ : npos; +} + +// Search range is [0..pos] inclusive. If pos == npos, search everything. +string_view::size_type string_view::rfind(char c, size_type pos) const + noexcept { + // Note: memrchr() is not available on Windows. + if (empty()) return npos; + for (size_type i = std::min(pos, length_ - 1);; --i) { + if (ptr_[i] == c) { + return i; + } + if (i == 0) break; + } + return npos; +} + +string_view::size_type string_view::find_first_of(string_view s, + size_type pos) const + noexcept { + if (empty() || s.empty()) { + return npos; + } + // Avoid the cost of LookupTable() for a single-character search. + if (s.length_ == 1) return find_first_of(s.ptr_[0], pos); + LookupTable tbl(s); + for (size_type i = pos; i < length_; ++i) { + if (tbl[ptr_[i]]) { + return i; + } + } + return npos; +} + +string_view::size_type string_view::find_first_not_of(string_view s, + size_type pos) const + noexcept { + if (empty()) return npos; + // Avoid the cost of LookupTable() for a single-character search. + if (s.length_ == 1) return find_first_not_of(s.ptr_[0], pos); + LookupTable tbl(s); + for (size_type i = pos; i < length_; ++i) { + if (!tbl[ptr_[i]]) { + return i; + } + } + return npos; +} + +string_view::size_type string_view::find_first_not_of(char c, + size_type pos) const + noexcept { + if (empty()) return npos; + for (; pos < length_; ++pos) { + if (ptr_[pos] != c) { + return pos; + } + } + return npos; +} + +string_view::size_type string_view::find_last_of(string_view s, + size_type pos) const noexcept { + if (empty() || s.empty()) return npos; + // Avoid the cost of LookupTable() for a single-character search. + if (s.length_ == 1) return find_last_of(s.ptr_[0], pos); + LookupTable tbl(s); + for (size_type i = std::min(pos, length_ - 1);; --i) { + if (tbl[ptr_[i]]) { + return i; + } + if (i == 0) break; + } + return npos; +} + +string_view::size_type string_view::find_last_not_of(string_view s, + size_type pos) const + noexcept { + if (empty()) return npos; + size_type i = std::min(pos, length_ - 1); + if (s.empty()) return i; + // Avoid the cost of LookupTable() for a single-character search. + if (s.length_ == 1) return find_last_not_of(s.ptr_[0], pos); + LookupTable tbl(s); + for (;; --i) { + if (!tbl[ptr_[i]]) { + return i; + } + if (i == 0) break; + } + return npos; +} + +string_view::size_type string_view::find_last_not_of(char c, + size_type pos) const + noexcept { + if (empty()) return npos; + size_type i = std::min(pos, length_ - 1); + for (;; --i) { + if (ptr_[i] != c) { + return i; + } + if (i == 0) break; + } + return npos; +} + +// MSVC has non-standard behavior that implicitly creates definitions for static +// const members. These implicit definitions conflict with explicit out-of-class +// member definitions that are required by the C++ standard, resulting in +// LNK1169 "multiply defined" errors at link time. __declspec(selectany) asks +// MSVC to choose only one definition for the symbol it decorates. See details +// at http://msdn.microsoft.com/en-us/library/34h23df8(v=vs.100).aspx +#ifdef _MSC_VER +#define ABSL_STRING_VIEW_SELECTANY __declspec(selectany) +#else +#define ABSL_STRING_VIEW_SELECTANY +#endif + +ABSL_STRING_VIEW_SELECTANY +constexpr string_view::size_type string_view::npos; +ABSL_STRING_VIEW_SELECTANY +constexpr string_view::size_type string_view::kMaxSize; + +} // namespace absl + +#endif // ABSL_HAVE_STD_STRING_VIEW diff --git a/Firestore/third_party/abseil-cpp/absl/strings/string_view.h b/Firestore/third_party/abseil-cpp/absl/strings/string_view.h new file mode 100644 index 0000000..c3acd72 --- /dev/null +++ b/Firestore/third_party/abseil-cpp/absl/strings/string_view.h @@ -0,0 +1,570 @@ +// +// Copyright 2017 The Abseil Authors. +// +// 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. +// +// ----------------------------------------------------------------------------- +// File: string_view.h +// ----------------------------------------------------------------------------- +// +// This file contains the definition of the `absl::string_view` class. A +// `string_view` points to a contiguous span of characters, often part or all of +// another `std::string`, double-quoted std::string literal, character array, or even +// another `string_view`. +// +// This `absl::string_view` abstraction is designed to be a drop-in +// replacement for the C++17 `std::string_view` abstraction. +#ifndef ABSL_STRINGS_STRING_VIEW_H_ +#define ABSL_STRINGS_STRING_VIEW_H_ + +#include +#include "absl/base/config.h" + +#ifdef ABSL_HAVE_STD_STRING_VIEW + +#include + +namespace absl { +using std::string_view; +}; + +#else // ABSL_HAVE_STD_STRING_VIEW + +#include +#include +#include +#include +#include +#include +#include + +#include "absl/base/internal/throw_delegate.h" +#include "absl/base/macros.h" +#include "absl/base/port.h" + +namespace absl { + +// absl::string_view +// +// A `string_view` provides a lightweight view into the std::string data provided by +// a `std::string`, double-quoted std::string literal, character array, or even +// another `string_view`. A `string_view` does *not* own the std::string to which it +// points, and that data cannot be modified through the view. +// +// You can use `string_view` as a function or method parameter anywhere a +// parameter can receive a double-quoted std::string literal, `const char*`, +// `std::string`, or another `absl::string_view` argument with no need to copy +// the std::string data. Systematic use of `string_view` within function arguments +// reduces data copies and `strlen()` calls. +// +// Because of its small size, prefer passing `string_view` by value: +// +// void MyFunction(absl::string_view arg); +// +// If circumstances require, you may also pass one by const reference: +// +// void MyFunction(const absl::string_view& arg); // not preferred +// +// Passing by value generates slightly smaller code for many architectures. +// +// In either case, the source data of the `string_view` must outlive the +// `string_view` itself. +// +// A `string_view` is also suitable for local variables if you know that the +// lifetime of the underlying object is longer than the lifetime of your +// `string_view` variable. However, beware of binding a `string_view` to a +// temporary value: +// +// // BAD use of string_view: lifetime problem +// absl::string_view sv = obj.ReturnAString(); +// +// // GOOD use of string_view: str outlives sv +// std::string str = obj.ReturnAString(); +// absl::string_view sv = str; +// +// Due to lifetime issues, a `string_view` is sometimes a poor choice for a +// return value and usually a poor choice for a data member. If you do use a +// `string_view` this way, it is your responsibility to ensure that the object +// pointed to by the `string_view` outlives the `string_view`. +// +// A `string_view` may represent a whole std::string or just part of a std::string. For +// example, when splitting a std::string, `std::vector` is a +// natural data type for the output. +// +// +// When constructed from a source which is nul-terminated, the `string_view` +// itself will not include the nul-terminator unless a specific size (including +// the nul) is passed to the constructor. As a result, common idioms that work +// on nul-terminated strings do not work on `string_view` objects. If you write +// code that scans a `string_view`, you must check its length rather than test +// for nul, for example. Note, however, that nuls may still be embedded within +// a `string_view` explicitly. +// +// You may create a null `string_view` in two ways: +// +// absl::string_view sv(); +// absl::string_view sv(nullptr, 0); +// +// For the above, `sv.data() == nullptr`, `sv.length() == 0`, and +// `sv.empty() == true`. Also, if you create a `string_view` with a non-null +// pointer then `sv.data() != nullptr`. Thus, you can use `string_view()` to +// signal an undefined value that is different from other `string_view` values +// in a similar fashion to how `const char* p1 = nullptr;` is different from +// `const char* p2 = "";`. However, in practice, it is not recommended to rely +// on this behavior. +// +// Be careful not to confuse a null `string_view` with an empty one. A null +// `string_view` is an empty `string_view`, but some empty `string_view`s are +// not null. Prefer checking for emptiness over checking for null. +// +// There are many ways to create an empty string_view: +// +// const char* nullcp = nullptr; +// // string_view.size() will return 0 in all cases. +// absl::string_view(); +// absl::string_view(nullcp, 0); +// absl::string_view(""); +// absl::string_view("", 0); +// absl::string_view("abcdef", 0); +// absl::string_view("abcdef" + 6, 0); +// +// All empty `string_view` objects whether null or not, are equal: +// +// absl::string_view() == absl::string_view("", 0) +// absl::string_view(nullptr, 0) == absl:: string_view("abcdef"+6, 0) +class string_view { + public: + using traits_type = std::char_traits; + using value_type = char; + using pointer = char*; + using const_pointer = const char*; + using reference = char&; + using const_reference = const char&; + using const_iterator = const char*; + using iterator = const_iterator; + using const_reverse_iterator = std::reverse_iterator; + using reverse_iterator = const_reverse_iterator; + using size_type = size_t; + using difference_type = std::ptrdiff_t; + + static constexpr size_type npos = static_cast(-1); + + // Null `string_view` constructor + constexpr string_view() noexcept : ptr_(nullptr), length_(0) {} + + // Implicit constructors + + template + string_view( // NOLINT(runtime/explicit) + const std::basic_string, Allocator>& + str) noexcept + : ptr_(str.data()), length_(str.size()) {} + + // Implicit constructor of a `string_view` from nul-terminated `str`. When + // accepting possibly null strings, use `absl::NullSafeStringView(str)` + // instead (see below). + constexpr string_view(const char* str) // NOLINT(runtime/explicit) + : ptr_(str), length_(StrLenInternal(str)) {} + + // Implicit constructor of a `string_view` from a `const char*` and length. + constexpr string_view(const char* data, size_type len) + : ptr_(data), length_(CheckLengthInternal(len)) {} + + // NOTE: Harmlessly omitted to work around gdb bug. + // constexpr string_view(const string_view&) noexcept = default; + // string_view& operator=(const string_view&) noexcept = default; + + // Iterators + + // string_view::begin() + // + // Returns an iterator pointing to the first character at the beginning of the + // `string_view`, or `end()` if the `string_view` is empty. + constexpr const_iterator begin() const noexcept { return ptr_; } + + // string_view::end() + // + // Returns an iterator pointing just beyond the last character at the end of + // the `string_view`. This iterator acts as a placeholder; attempting to + // access it results in undefined behavior. + constexpr const_iterator end() const noexcept { return ptr_ + length_; } + + // string_view::cbegin() + // + // Returns a const iterator pointing to the first character at the beginning + // of the `string_view`, or `end()` if the `string_view` is empty. + constexpr const_iterator cbegin() const noexcept { return begin(); } + + // string_view::cend() + // + // Returns a const iterator pointing just beyond the last character at the end + // of the `string_view`. This pointer acts as a placeholder; attempting to + // access its element results in undefined behavior. + constexpr const_iterator cend() const noexcept { return end(); } + + // string_view::rbegin() + // + // Returns a reverse iterator pointing to the last character at the end of the + // `string_view`, or `rend()` if the `string_view` is empty. + const_reverse_iterator rbegin() const noexcept { + return const_reverse_iterator(end()); + } + + // string_view::rend() + // + // Returns a reverse iterator pointing just before the first character at the + // beginning of the `string_view`. This pointer acts as a placeholder; + // attempting to access its element results in undefined behavior. + const_reverse_iterator rend() const noexcept { + return const_reverse_iterator(begin()); + } + + // string_view::crbegin() + // + // Returns a const reverse iterator pointing to the last character at the end + // of the `string_view`, or `crend()` if the `string_view` is empty. + const_reverse_iterator crbegin() const noexcept { return rbegin(); } + + // string_view::crend() + // + // Returns a const reverse iterator pointing just before the first character + // at the beginning of the `string_view`. This pointer acts as a placeholder; + // attempting to access its element results in undefined behavior. + const_reverse_iterator crend() const noexcept { return rend(); } + + // Capacity Utilities + + // string_view::size() + // + // Returns the number of characters in the `string_view`. + constexpr size_type size() const noexcept { + return length_; + } + + // string_view::length() + // + // Returns the number of characters in the `string_view`. Alias for `size()`. + constexpr size_type length() const noexcept { return size(); } + + // string_view::max_size() + // + // Returns the maximum number of characters the `string_view` can hold. + constexpr size_type max_size() const noexcept { return kMaxSize; } + + // string_view::empty() + // + // Checks if the `string_view` is empty (refers to no characters). + constexpr bool empty() const noexcept { return length_ == 0; } + + // std::string:view::operator[] + // + // Returns the ith element of an `string_view` using the array operator. + // Note that this operator does not perform any bounds checking. + constexpr const_reference operator[](size_type i) const { return ptr_[i]; } + + // string_view::front() + // + // Returns the first element of a `string_view`. + constexpr const_reference front() const { return ptr_[0]; } + + // string_view::back() + // + // Returns the last element of a `string_view`. + constexpr const_reference back() const { return ptr_[size() - 1]; } + + // string_view::data() + // + // Returns a pointer to the underlying character array (which is of course + // stored elsewhere). Note that `string_view::data()` may contain embedded nul + // characters, but the returned buffer may or may not be nul-terminated; + // therefore, do not pass `data()` to a routine that expects a nul-terminated + // std::string. + constexpr const_pointer data() const noexcept { return ptr_; } + + // Modifiers + + // string_view::remove_prefix() + // + // Removes the first `n` characters from the `string_view`. Note that the + // underlying std::string is not changed, only the view. + void remove_prefix(size_type n) { + assert(n <= length_); + ptr_ += n; + length_ -= n; + } + + // string_view::remove_suffix() + // + // Removes the last `n` characters from the `string_view`. Note that the + // underlying std::string is not changed, only the view. + void remove_suffix(size_type n) { + assert(n <= length_); + length_ -= n; + } + + // string_view::swap() + // + // Swaps this `string_view` with another `string_view`. + void swap(string_view& s) noexcept { + auto t = *this; + *this = s; + s = t; + } + + // Explicit conversion operators + + // Converts to `std::basic_string`. + template + explicit operator std::basic_string() const { + if (!data()) return {}; + return std::basic_string(data(), size()); + } + + // string_view::copy() + // + // Copies the contents of the `string_view` at offset `pos` and length `n` + // into `buf`. + size_type copy(char* buf, size_type n, size_type pos = 0) const; + + // string_view::substr() + // + // Returns a "substring" of the `string_view` (at offset `pos` and length + // `n`) as another string_view. This function throws `std::out_of_bounds` if + // `pos > size'. + string_view substr(size_type pos, size_type n = npos) const { + if (ABSL_PREDICT_FALSE(pos > length_)) + base_internal::ThrowStdOutOfRange("absl::string_view::substr"); + n = std::min(n, length_ - pos); + return string_view(ptr_ + pos, n); + } + + // string_view::compare() + // + // Performs a lexicographical comparison between the `string_view` and + // another `absl::string_view), returning -1 if `this` is less than, 0 if + // `this` is equal to, and 1 if `this` is greater than the passed std::string + // view. Note that in the case of data equality, a further comparison is made + // on the respective sizes of the two `string_view`s to determine which is + // smaller, equal, or greater. + int compare(string_view x) const noexcept { + auto min_length = std::min(length_, x.length_); + if (min_length > 0) { + int r = memcmp(ptr_, x.ptr_, min_length); + if (r < 0) return -1; + if (r > 0) return 1; + } + if (length_ < x.length_) return -1; + if (length_ > x.length_) return 1; + return 0; + } + + // Overload of `string_view::compare()` for comparing a substring of the + // 'string_view` and another `absl::string_view`. + int compare(size_type pos1, size_type count1, string_view v) const { + return substr(pos1, count1).compare(v); + } + + // Overload of `string_view::compare()` for comparing a substring of the + // `string_view` and a substring of another `absl::string_view`. + int compare(size_type pos1, size_type count1, string_view v, size_type pos2, + size_type count2) const { + return substr(pos1, count1).compare(v.substr(pos2, count2)); + } + + // Overload of `string_view::compare()` for comparing a `string_view` and a + // a different C-style std::string `s`. + int compare(const char* s) const { return compare(string_view(s)); } + + // Overload of `string_view::compare()` for comparing a substring of the + // `string_view` and a different std::string C-style std::string `s`. + int compare(size_type pos1, size_type count1, const char* s) const { + return substr(pos1, count1).compare(string_view(s)); + } + + // Overload of `string_view::compare()` for comparing a substring of the + // `string_view` and a substring of a different C-style std::string `s`. + int compare(size_type pos1, size_type count1, const char* s, + size_type count2) const { + return substr(pos1, count1).compare(string_view(s, count2)); + } + + // Find Utilities + + // string_view::find() + // + // Finds the first occurrence of the substring `s` within the `string_view`, + // returning the position of the first character's match, or `npos` if no + // match was found. + size_type find(string_view s, size_type pos = 0) const noexcept; + + // Overload of `string_view::find()` for finding the given character `c` + // within the `string_view`. + size_type find(char c, size_type pos = 0) const noexcept; + + // string_view::rfind() + // + // Finds the last occurrence of a substring `s` within the `string_view`, + // returning the position of the first character's match, or `npos` if no + // match was found. + size_type rfind(string_view s, size_type pos = npos) const + noexcept; + + // Overload of `string_view::rfind()` for finding the given character `c` + // within the `string_view`. + size_type rfind(char c, size_type pos = npos) const noexcept; + + // string_view::find_first_of() + // + // Finds the first occurrence of any of the characters in `s` within the + // `string_view`, returning the start position of the match, or `npos` if no + // match was found. + size_type find_first_of(string_view s, size_type pos = 0) const + noexcept; + + // Overload of `string_view::find_first_of()` for finding a character `c` + // within the `string_view`. + size_type find_first_of(char c, size_type pos = 0) const + noexcept { + return find(c, pos); + } + + // string_view::find_last_of() + // + // Finds the last occurrence of any of the characters in `s` within the + // `string_view`, returning the start position of the match, or `npos` if no + // match was found. + size_type find_last_of(string_view s, size_type pos = npos) const + noexcept; + + // Overload of `string_view::find_last_of()` for finding a character `c` + // within the `string_view`. + size_type find_last_of(char c, size_type pos = npos) const + noexcept { + return rfind(c, pos); + } + + // string_view::find_first_not_of() + // + // Finds the first occurrence of any of the characters not in `s` within the + // `string_view`, returning the start position of the first non-match, or + // `npos` if no non-match was found. + size_type find_first_not_of(string_view s, size_type pos = 0) const noexcept; + + // Overload of `string_view::find_first_not_of()` for finding a character + // that is not `c` within the `string_view`. + size_type find_first_not_of(char c, size_type pos = 0) const noexcept; + + // string_view::find_last_not_of() + // + // Finds the last occurrence of any of the characters not in `s` within the + // `string_view`, returning the start position of the last non-match, or + // `npos` if no non-match was found. + size_type find_last_not_of(string_view s, + size_type pos = npos) const noexcept; + + // Overload of `string_view::find_last_not_of()` for finding a character + // that is not `c` within the `string_view`. + size_type find_last_not_of(char c, size_type pos = npos) const + noexcept; + + private: + static constexpr size_type kMaxSize = + std::numeric_limits::max() / 2 + 1; + + // check whether __builtin_strlen is provided by the compiler. + // GCC doesn't have __has_builtin() + // (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66970), + // but has __builtin_strlen according to + // https://gcc.gnu.org/onlinedocs/gcc-4.7.0/gcc/Other-Builtins.html. +#if ABSL_HAVE_BUILTIN(__builtin_strlen) || \ + (defined(__GNUC__) && !defined(__clang__)) + static constexpr size_type StrLenInternal(const char* str) { + return str ? __builtin_strlen(str) : 0; + } +#else + static constexpr size_type StrLenInternal(const char* str) { + return str ? strlen(str) : 0; + } +#endif + + static constexpr size_type CheckLengthInternal(size_type len) { + return ABSL_ASSERT(len <= kMaxSize), len; + } + + const char* ptr_; + size_type length_; +}; + +// This large function is defined inline so that in a fairly common case where +// one of the arguments is a literal, the compiler can elide a lot of the +// following comparisons. +inline bool operator==(string_view x, string_view y) noexcept { + auto len = x.size(); + if (len != y.size()) { + return false; + } + return x.data() == y.data() || len <= 0 || + memcmp(x.data(), y.data(), len) == 0; +} + +inline bool operator!=(string_view x, string_view y) noexcept { + return !(x == y); +} + +inline bool operator<(string_view x, string_view y) noexcept { + auto min_size = std::min(x.size(), y.size()); + const int r = min_size == 0 ? 0 : memcmp(x.data(), y.data(), min_size); + return (r < 0) || (r == 0 && x.size() < y.size()); +} + +inline bool operator>(string_view x, string_view y) noexcept { return y < x; } + +inline bool operator<=(string_view x, string_view y) noexcept { + return !(y < x); +} + +inline bool operator>=(string_view x, string_view y) noexcept { + return !(x < y); +} + +// IO Insertion Operator +std::ostream& operator<<(std::ostream& o, string_view piece); + +} // namespace absl + +#endif // ABSL_HAVE_STD_STRING_VIEW + +namespace absl { + +// ClippedSubstr() +// +// Like `s.substr(pos, n)`, but clips `pos` to an upper bound of `s.size()`. +// Provided because std::string_view::substr throws if `pos > size()` +inline string_view ClippedSubstr(string_view s, size_t pos, + size_t n = string_view::npos) { + pos = std::min(pos, static_cast(s.size())); + return s.substr(pos, n); +} + +// NullSafeStringView() +// +// Creates an `absl::string_view` from a pointer `p` even if it's null-valued. +// This function should be used where an `absl::string_view` can be created from +// a possibly-null pointer. +inline string_view NullSafeStringView(const char* p) { + return p ? string_view(p) : string_view(); +} + +} // namespace absl + +#endif // ABSL_STRINGS_STRING_VIEW_H_ diff --git a/Firestore/third_party/abseil-cpp/absl/strings/string_view_test.cc b/Firestore/third_party/abseil-cpp/absl/strings/string_view_test.cc new file mode 100644 index 0000000..13fc214 --- /dev/null +++ b/Firestore/third_party/abseil-cpp/absl/strings/string_view_test.cc @@ -0,0 +1,1101 @@ +// Copyright 2017 The Abseil Authors. +// +// 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. + +#include "absl/strings/string_view.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gtest/gtest.h" +#include "absl/base/config.h" +#include "absl/base/dynamic_annotations.h" + +namespace { + +// A minimal allocator that uses malloc(). +template +struct Mallocator { + typedef T value_type; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef T* pointer; + typedef const T* const_pointer; + typedef T& reference; + typedef const T& const_reference; + + size_type max_size() const { + return size_t(std::numeric_limits::max()) / sizeof(value_type); + } + template + struct rebind { + typedef Mallocator other; + }; + Mallocator() = default; + + T* allocate(size_t n) { return static_cast(std::malloc(n * sizeof(T))); } + void deallocate(T* p, size_t) { std::free(p); } +}; +template +bool operator==(const Mallocator&, const Mallocator&) { + return true; +} +template +bool operator!=(const Mallocator&, const Mallocator&) { + return false; +} + +TEST(StringViewTest, Ctor) { + { + // Null. + absl::string_view s10; + EXPECT_TRUE(s10.data() == nullptr); + EXPECT_EQ(0, s10.length()); + } + + { + // const char* without length. + const char* hello = "hello"; + absl::string_view s20(hello); + EXPECT_TRUE(s20.data() == hello); + EXPECT_EQ(5, s20.length()); + + // const char* with length. + absl::string_view s21(hello, 4); + EXPECT_TRUE(s21.data() == hello); + EXPECT_EQ(4, s21.length()); + + // Not recommended, but valid C++ + absl::string_view s22(hello, 6); + EXPECT_TRUE(s22.data() == hello); + EXPECT_EQ(6, s22.length()); + } + + { + // std::string. + std::string hola = "hola"; + absl::string_view s30(hola); + EXPECT_TRUE(s30.data() == hola.data()); + EXPECT_EQ(4, s30.length()); + + // std::string with embedded '\0'. + hola.push_back('\0'); + hola.append("h2"); + hola.push_back('\0'); + absl::string_view s31(hola); + EXPECT_TRUE(s31.data() == hola.data()); + EXPECT_EQ(8, s31.length()); + } + + { + using mstring = + std::basic_string, Mallocator>; + mstring str1("BUNGIE-JUMPING!"); + const mstring str2("SLEEPING!"); + + absl::string_view s1(str1); + s1.remove_prefix(strlen("BUNGIE-JUM")); + + absl::string_view s2(str2); + s2.remove_prefix(strlen("SLEE")); + + EXPECT_EQ(s1, s2); + EXPECT_EQ(s1, "PING!"); + } + + // TODO(mec): absl::string_view(const absl::string_view&); +} + +TEST(StringViewTest, Swap) { + absl::string_view a("a"); + absl::string_view b("bbb"); + EXPECT_TRUE(noexcept(a.swap(b))); + a.swap(b); + EXPECT_EQ(a, "bbb"); + EXPECT_EQ(b, "a"); + a.swap(b); + EXPECT_EQ(a, "a"); + EXPECT_EQ(b, "bbb"); +} + +TEST(StringViewTest, STLComparator) { + std::string s1("foo"); + std::string s2("bar"); + std::string s3("baz"); + + absl::string_view p1(s1); + absl::string_view p2(s2); + absl::string_view p3(s3); + + typedef std::map TestMap; + TestMap map; + + map.insert(std::make_pair(p1, 0)); + map.insert(std::make_pair(p2, 1)); + map.insert(std::make_pair(p3, 2)); + EXPECT_EQ(map.size(), 3); + + TestMap::const_iterator iter = map.begin(); + EXPECT_EQ(iter->second, 1); + ++iter; + EXPECT_EQ(iter->second, 2); + ++iter; + EXPECT_EQ(iter->second, 0); + ++iter; + EXPECT_TRUE(iter == map.end()); + + TestMap::iterator new_iter = map.find("zot"); + EXPECT_TRUE(new_iter == map.end()); + + new_iter = map.find("bar"); + EXPECT_TRUE(new_iter != map.end()); + + map.erase(new_iter); + EXPECT_EQ(map.size(), 2); + + iter = map.begin(); + EXPECT_EQ(iter->second, 2); + ++iter; + EXPECT_EQ(iter->second, 0); + ++iter; + EXPECT_TRUE(iter == map.end()); +} + +#define COMPARE(result, op, x, y) \ + EXPECT_EQ(result, absl::string_view((x)) op absl::string_view((y))); \ + EXPECT_EQ(result, absl::string_view((x)).compare(absl::string_view((y))) op 0) + +TEST(StringViewTest, ComparisonOperators) { + COMPARE(true, ==, "", ""); + COMPARE(true, ==, "", absl::string_view()); + COMPARE(true, ==, absl::string_view(), ""); + COMPARE(true, ==, "a", "a"); + COMPARE(true, ==, "aa", "aa"); + COMPARE(false, ==, "a", ""); + COMPARE(false, ==, "", "a"); + COMPARE(false, ==, "a", "b"); + COMPARE(false, ==, "a", "aa"); + COMPARE(false, ==, "aa", "a"); + + COMPARE(false, !=, "", ""); + COMPARE(false, !=, "a", "a"); + COMPARE(false, !=, "aa", "aa"); + COMPARE(true, !=, "a", ""); + COMPARE(true, !=, "", "a"); + COMPARE(true, !=, "a", "b"); + COMPARE(true, !=, "a", "aa"); + COMPARE(true, !=, "aa", "a"); + + COMPARE(true, <, "a", "b"); + COMPARE(true, <, "a", "aa"); + COMPARE(true, <, "aa", "b"); + COMPARE(true, <, "aa", "bb"); + COMPARE(false, <, "a", "a"); + COMPARE(false, <, "b", "a"); + COMPARE(false, <, "aa", "a"); + COMPARE(false, <, "b", "aa"); + COMPARE(false, <, "bb", "aa"); + + COMPARE(true, <=, "a", "a"); + COMPARE(true, <=, "a", "b"); + COMPARE(true, <=, "a", "aa"); + COMPARE(true, <=, "aa", "b"); + COMPARE(true, <=, "aa", "bb"); + COMPARE(false, <=, "b", "a"); + COMPARE(false, <=, "aa", "a"); + COMPARE(false, <=, "b", "aa"); + COMPARE(false, <=, "bb", "aa"); + + COMPARE(false, >=, "a", "b"); + COMPARE(false, >=, "a", "aa"); + COMPARE(false, >=, "aa", "b"); + COMPARE(false, >=, "aa", "bb"); + COMPARE(true, >=, "a", "a"); + COMPARE(true, >=, "b", "a"); + COMPARE(true, >=, "aa", "a"); + COMPARE(true, >=, "b", "aa"); + COMPARE(true, >=, "bb", "aa"); + + COMPARE(false, >, "a", "a"); + COMPARE(false, >, "a", "b"); + COMPARE(false, >, "a", "aa"); + COMPARE(false, >, "aa", "b"); + COMPARE(false, >, "aa", "bb"); + COMPARE(true, >, "b", "a"); + COMPARE(true, >, "aa", "a"); + COMPARE(true, >, "b", "aa"); + COMPARE(true, >, "bb", "aa"); +} + +TEST(StringViewTest, ComparisonOperatorsByCharacterPosition) { + std::string x; + for (int i = 0; i < 256; i++) { + x += 'a'; + std::string y = x; + COMPARE(true, ==, x, y); + for (int j = 0; j < i; j++) { + std::string z = x; + z[j] = 'b'; // Differs in position 'j' + COMPARE(false, ==, x, z); + COMPARE(true, <, x, z); + COMPARE(true, >, z, x); + if (j + 1 < i) { + z[j + 1] = 'A'; // Differs in position 'j+1' as well + COMPARE(false, ==, x, z); + COMPARE(true, <, x, z); + COMPARE(true, >, z, x); + z[j + 1] = 'z'; // Differs in position 'j+1' as well + COMPARE(false, ==, x, z); + COMPARE(true, <, x, z); + COMPARE(true, >, z, x); + } + } + } +} +#undef COMPARE + +// Sadly, our users often confuse std::string::npos with absl::string_view::npos; +// So much so that we test here that they are the same. They need to +// both be unsigned, and both be the maximum-valued integer of their type. + +template +struct is_type { + template + static bool same(U) { + return false; + } + static bool same(T) { return true; } +}; + +TEST(StringViewTest, NposMatchesStdStringView) { + EXPECT_EQ(absl::string_view::npos, std::string::npos); + + EXPECT_TRUE(is_type::same(absl::string_view::npos)); + EXPECT_FALSE(is_type::same("")); + + // Make sure absl::string_view::npos continues to be a header constant. + char test[absl::string_view::npos & 1] = {0}; + EXPECT_EQ(0, test[0]); +} + +TEST(StringViewTest, STL1) { + const absl::string_view a("abcdefghijklmnopqrstuvwxyz"); + const absl::string_view b("abc"); + const absl::string_view c("xyz"); + const absl::string_view d("foobar"); + const absl::string_view e; + std::string temp("123"); + temp += '\0'; + temp += "456"; + const absl::string_view f(temp); + + EXPECT_EQ(a[6], 'g'); + EXPECT_EQ(b[0], 'a'); + EXPECT_EQ(c[2], 'z'); + EXPECT_EQ(f[3], '\0'); + EXPECT_EQ(f[5], '5'); + + EXPECT_EQ(*d.data(), 'f'); + EXPECT_EQ(d.data()[5], 'r'); + EXPECT_TRUE(e.data() == nullptr); + + EXPECT_EQ(*a.begin(), 'a'); + EXPECT_EQ(*(b.begin() + 2), 'c'); + EXPECT_EQ(*(c.end() - 1), 'z'); + + EXPECT_EQ(*a.rbegin(), 'z'); + EXPECT_EQ(*(b.rbegin() + 2), 'a'); + EXPECT_EQ(*(c.rend() - 1), 'x'); + EXPECT_TRUE(a.rbegin() + 26 == a.rend()); + + EXPECT_EQ(a.size(), 26); + EXPECT_EQ(b.size(), 3); + EXPECT_EQ(c.size(), 3); + EXPECT_EQ(d.size(), 6); + EXPECT_EQ(e.size(), 0); + EXPECT_EQ(f.size(), 7); + + EXPECT_TRUE(!d.empty()); + EXPECT_TRUE(d.begin() != d.end()); + EXPECT_TRUE(d.begin() + 6 == d.end()); + + EXPECT_TRUE(e.empty()); + EXPECT_TRUE(e.begin() == e.end()); + + char buf[4] = { '%', '%', '%', '%' }; + EXPECT_EQ(a.copy(buf, 4), 4); + EXPECT_EQ(buf[0], a[0]); + EXPECT_EQ(buf[1], a[1]); + EXPECT_EQ(buf[2], a[2]); + EXPECT_EQ(buf[3], a[3]); + EXPECT_EQ(a.copy(buf, 3, 7), 3); + EXPECT_EQ(buf[0], a[7]); + EXPECT_EQ(buf[1], a[8]); + EXPECT_EQ(buf[2], a[9]); + EXPECT_EQ(buf[3], a[3]); + EXPECT_EQ(c.copy(buf, 99), 3); + EXPECT_EQ(buf[0], c[0]); + EXPECT_EQ(buf[1], c[1]); + EXPECT_EQ(buf[2], c[2]); + EXPECT_EQ(buf[3], a[3]); +} + +// Separated from STL1() because some compilers produce an overly +// large stack frame for the combined function. +TEST(StringViewTest, STL2) { + const absl::string_view a("abcdefghijklmnopqrstuvwxyz"); + const absl::string_view b("abc"); + const absl::string_view c("xyz"); + absl::string_view d("foobar"); + const absl::string_view e; + const absl::string_view f( + "123" + "\0" + "456", + 7); + + d = absl::string_view(); + EXPECT_EQ(d.size(), 0); + EXPECT_TRUE(d.empty()); + EXPECT_TRUE(d.data() == nullptr); + EXPECT_TRUE(d.begin() == d.end()); + + EXPECT_EQ(a.find(b), 0); + EXPECT_EQ(a.find(b, 1), absl::string_view::npos); + EXPECT_EQ(a.find(c), 23); + EXPECT_EQ(a.find(c, 9), 23); + EXPECT_EQ(a.find(c, absl::string_view::npos), absl::string_view::npos); + EXPECT_EQ(b.find(c), absl::string_view::npos); + EXPECT_EQ(b.find(c, absl::string_view::npos), absl::string_view::npos); + EXPECT_EQ(a.find(d), 0); + EXPECT_EQ(a.find(e), 0); + EXPECT_EQ(a.find(d, 12), 12); + EXPECT_EQ(a.find(e, 17), 17); + absl::string_view g("xx not found bb"); + EXPECT_EQ(a.find(g), absl::string_view::npos); + // empty std::string nonsense + EXPECT_EQ(d.find(b), absl::string_view::npos); + EXPECT_EQ(e.find(b), absl::string_view::npos); + EXPECT_EQ(d.find(b, 4), absl::string_view::npos); + EXPECT_EQ(e.find(b, 7), absl::string_view::npos); + + size_t empty_search_pos = std::string().find(std::string()); + EXPECT_EQ(d.find(d), empty_search_pos); + EXPECT_EQ(d.find(e), empty_search_pos); + EXPECT_EQ(e.find(d), empty_search_pos); + EXPECT_EQ(e.find(e), empty_search_pos); + EXPECT_EQ(d.find(d, 4), std::string().find(std::string(), 4)); + EXPECT_EQ(d.find(e, 4), std::string().find(std::string(), 4)); + EXPECT_EQ(e.find(d, 4), std::string().find(std::string(), 4)); + EXPECT_EQ(e.find(e, 4), std::string().find(std::string(), 4)); + + EXPECT_EQ(a.find('a'), 0); + EXPECT_EQ(a.find('c'), 2); + EXPECT_EQ(a.find('z'), 25); + EXPECT_EQ(a.find('$'), absl::string_view::npos); + EXPECT_EQ(a.find('\0'), absl::string_view::npos); + EXPECT_EQ(f.find('\0'), 3); + EXPECT_EQ(f.find('3'), 2); + EXPECT_EQ(f.find('5'), 5); + EXPECT_EQ(g.find('o'), 4); + EXPECT_EQ(g.find('o', 4), 4); + EXPECT_EQ(g.find('o', 5), 8); + EXPECT_EQ(a.find('b', 5), absl::string_view::npos); + // empty std::string nonsense + EXPECT_EQ(d.find('\0'), absl::string_view::npos); + EXPECT_EQ(e.find('\0'), absl::string_view::npos); + EXPECT_EQ(d.find('\0', 4), absl::string_view::npos); + EXPECT_EQ(e.find('\0', 7), absl::string_view::npos); + EXPECT_EQ(d.find('x'), absl::string_view::npos); + EXPECT_EQ(e.find('x'), absl::string_view::npos); + EXPECT_EQ(d.find('x', 4), absl::string_view::npos); + EXPECT_EQ(e.find('x', 7), absl::string_view::npos); + + EXPECT_EQ(a.rfind(b), 0); + EXPECT_EQ(a.rfind(b, 1), 0); + EXPECT_EQ(a.rfind(c), 23); + EXPECT_EQ(a.rfind(c, 22), absl::string_view::npos); + EXPECT_EQ(a.rfind(c, 1), absl::string_view::npos); + EXPECT_EQ(a.rfind(c, 0), absl::string_view::npos); + EXPECT_EQ(b.rfind(c), absl::string_view::npos); + EXPECT_EQ(b.rfind(c, 0), absl::string_view::npos); + EXPECT_EQ(a.rfind(d), std::string(a).rfind(std::string())); + EXPECT_EQ(a.rfind(e), std::string(a).rfind(std::string())); + EXPECT_EQ(a.rfind(d, 12), 12); + EXPECT_EQ(a.rfind(e, 17), 17); + EXPECT_EQ(a.rfind(g), absl::string_view::npos); + EXPECT_EQ(d.rfind(b), absl::string_view::npos); + EXPECT_EQ(e.rfind(b), absl::string_view::npos); + EXPECT_EQ(d.rfind(b, 4), absl::string_view::npos); + EXPECT_EQ(e.rfind(b, 7), absl::string_view::npos); + // empty std::string nonsense + EXPECT_EQ(d.rfind(d, 4), std::string().rfind(std::string())); + EXPECT_EQ(e.rfind(d, 7), std::string().rfind(std::string())); + EXPECT_EQ(d.rfind(e, 4), std::string().rfind(std::string())); + EXPECT_EQ(e.rfind(e, 7), std::string().rfind(std::string())); + EXPECT_EQ(d.rfind(d), std::string().rfind(std::string())); + EXPECT_EQ(e.rfind(d), std::string().rfind(std::string())); + EXPECT_EQ(d.rfind(e), std::string().rfind(std::string())); + EXPECT_EQ(e.rfind(e), std::string().rfind(std::string())); + + EXPECT_EQ(g.rfind('o'), 8); + EXPECT_EQ(g.rfind('q'), absl::string_view::npos); + EXPECT_EQ(g.rfind('o', 8), 8); + EXPECT_EQ(g.rfind('o', 7), 4); + EXPECT_EQ(g.rfind('o', 3), absl::string_view::npos); + EXPECT_EQ(f.rfind('\0'), 3); + EXPECT_EQ(f.rfind('\0', 12), 3); + EXPECT_EQ(f.rfind('3'), 2); + EXPECT_EQ(f.rfind('5'), 5); + // empty std::string nonsense + EXPECT_EQ(d.rfind('o'), absl::string_view::npos); + EXPECT_EQ(e.rfind('o'), absl::string_view::npos); + EXPECT_EQ(d.rfind('o', 4), absl::string_view::npos); + EXPECT_EQ(e.rfind('o', 7), absl::string_view::npos); +} + +// Continued from STL2 +TEST(StringViewTest, STL2FindFirst) { + const absl::string_view a("abcdefghijklmnopqrstuvwxyz"); + const absl::string_view b("abc"); + const absl::string_view c("xyz"); + absl::string_view d("foobar"); + const absl::string_view e; + const absl::string_view f( + "123" + "\0" + "456", + 7); + absl::string_view g("xx not found bb"); + + d = absl::string_view(); + EXPECT_EQ(a.find_first_of(b), 0); + EXPECT_EQ(a.find_first_of(b, 0), 0); + EXPECT_EQ(a.find_first_of(b, 1), 1); + EXPECT_EQ(a.find_first_of(b, 2), 2); + EXPECT_EQ(a.find_first_of(b, 3), absl::string_view::npos); + EXPECT_EQ(a.find_first_of(c), 23); + EXPECT_EQ(a.find_first_of(c, 23), 23); + EXPECT_EQ(a.find_first_of(c, 24), 24); + EXPECT_EQ(a.find_first_of(c, 25), 25); + EXPECT_EQ(a.find_first_of(c, 26), absl::string_view::npos); + EXPECT_EQ(g.find_first_of(b), 13); + EXPECT_EQ(g.find_first_of(c), 0); + EXPECT_EQ(a.find_first_of(f), absl::string_view::npos); + EXPECT_EQ(f.find_first_of(a), absl::string_view::npos); + // empty std::string nonsense + EXPECT_EQ(a.find_first_of(d), absl::string_view::npos); + EXPECT_EQ(a.find_first_of(e), absl::string_view::npos); + EXPECT_EQ(d.find_first_of(b), absl::string_view::npos); + EXPECT_EQ(e.find_first_of(b), absl::string_view::npos); + EXPECT_EQ(d.find_first_of(d), absl::string_view::npos); + EXPECT_EQ(e.find_first_of(d), absl::string_view::npos); + EXPECT_EQ(d.find_first_of(e), absl::string_view::npos); + EXPECT_EQ(e.find_first_of(e), absl::string_view::npos); + + EXPECT_EQ(a.find_first_not_of(b), 3); + EXPECT_EQ(a.find_first_not_of(c), 0); + EXPECT_EQ(b.find_first_not_of(a), absl::string_view::npos); + EXPECT_EQ(c.find_first_not_of(a), absl::string_view::npos); + EXPECT_EQ(f.find_first_not_of(a), 0); + EXPECT_EQ(a.find_first_not_of(f), 0); + EXPECT_EQ(a.find_first_not_of(d), 0); + EXPECT_EQ(a.find_first_not_of(e), 0); + // empty std::string nonsense + EXPECT_EQ(a.find_first_not_of(d), 0); + EXPECT_EQ(a.find_first_not_of(e), 0); + EXPECT_EQ(a.find_first_not_of(d, 1), 1); + EXPECT_EQ(a.find_first_not_of(e, 1), 1); + EXPECT_EQ(a.find_first_not_of(d, a.size() - 1), a.size() - 1); + EXPECT_EQ(a.find_first_not_of(e, a.size() - 1), a.size() - 1); + EXPECT_EQ(a.find_first_not_of(d, a.size()), absl::string_view::npos); + EXPECT_EQ(a.find_first_not_of(e, a.size()), absl::string_view::npos); + EXPECT_EQ(a.find_first_not_of(d, absl::string_view::npos), + absl::string_view::npos); + EXPECT_EQ(a.find_first_not_of(e, absl::string_view::npos), + absl::string_view::npos); + EXPECT_EQ(d.find_first_not_of(a), absl::string_view::npos); + EXPECT_EQ(e.find_first_not_of(a), absl::string_view::npos); + EXPECT_EQ(d.find_first_not_of(d), absl::string_view::npos); + EXPECT_EQ(e.find_first_not_of(d), absl::string_view::npos); + EXPECT_EQ(d.find_first_not_of(e), absl::string_view::npos); + EXPECT_EQ(e.find_first_not_of(e), absl::string_view::npos); + + absl::string_view h("===="); + EXPECT_EQ(h.find_first_not_of('='), absl::string_view::npos); + EXPECT_EQ(h.find_first_not_of('=', 3), absl::string_view::npos); + EXPECT_EQ(h.find_first_not_of('\0'), 0); + EXPECT_EQ(g.find_first_not_of('x'), 2); + EXPECT_EQ(f.find_first_not_of('\0'), 0); + EXPECT_EQ(f.find_first_not_of('\0', 3), 4); + EXPECT_EQ(f.find_first_not_of('\0', 2), 2); + // empty std::string nonsense + EXPECT_EQ(d.find_first_not_of('x'), absl::string_view::npos); + EXPECT_EQ(e.find_first_not_of('x'), absl::string_view::npos); + EXPECT_EQ(d.find_first_not_of('\0'), absl::string_view::npos); + EXPECT_EQ(e.find_first_not_of('\0'), absl::string_view::npos); +} + +// Continued from STL2 +TEST(StringViewTest, STL2FindLast) { + const absl::string_view a("abcdefghijklmnopqrstuvwxyz"); + const absl::string_view b("abc"); + const absl::string_view c("xyz"); + absl::string_view d("foobar"); + const absl::string_view e; + const absl::string_view f( + "123" + "\0" + "456", + 7); + absl::string_view g("xx not found bb"); + absl::string_view h("===="); + absl::string_view i("56"); + + d = absl::string_view(); + EXPECT_EQ(h.find_last_of(a), absl::string_view::npos); + EXPECT_EQ(g.find_last_of(a), g.size()-1); + EXPECT_EQ(a.find_last_of(b), 2); + EXPECT_EQ(a.find_last_of(c), a.size()-1); + EXPECT_EQ(f.find_last_of(i), 6); + EXPECT_EQ(a.find_last_of('a'), 0); + EXPECT_EQ(a.find_last_of('b'), 1); + EXPECT_EQ(a.find_last_of('z'), 25); + EXPECT_EQ(a.find_last_of('a', 5), 0); + EXPECT_EQ(a.find_last_of('b', 5), 1); + EXPECT_EQ(a.find_last_of('b', 0), absl::string_view::npos); + EXPECT_EQ(a.find_last_of('z', 25), 25); + EXPECT_EQ(a.find_last_of('z', 24), absl::string_view::npos); + EXPECT_EQ(f.find_last_of(i, 5), 5); + EXPECT_EQ(f.find_last_of(i, 6), 6); + EXPECT_EQ(f.find_last_of(a, 4), absl::string_view::npos); + // empty std::string nonsense + EXPECT_EQ(f.find_last_of(d), absl::string_view::npos); + EXPECT_EQ(f.find_last_of(e), absl::string_view::npos); + EXPECT_EQ(f.find_last_of(d, 4), absl::string_view::npos); + EXPECT_EQ(f.find_last_of(e, 4), absl::string_view::npos); + EXPECT_EQ(d.find_last_of(d), absl::string_view::npos); + EXPECT_EQ(d.find_last_of(e), absl::string_view::npos); + EXPECT_EQ(e.find_last_of(d), absl::string_view::npos); + EXPECT_EQ(e.find_last_of(e), absl::string_view::npos); + EXPECT_EQ(d.find_last_of(f), absl::string_view::npos); + EXPECT_EQ(e.find_last_of(f), absl::string_view::npos); + EXPECT_EQ(d.find_last_of(d, 4), absl::string_view::npos); + EXPECT_EQ(d.find_last_of(e, 4), absl::string_view::npos); + EXPECT_EQ(e.find_last_of(d, 4), absl::string_view::npos); + EXPECT_EQ(e.find_last_of(e, 4), absl::string_view::npos); + EXPECT_EQ(d.find_last_of(f, 4), absl::string_view::npos); + EXPECT_EQ(e.find_last_of(f, 4), absl::string_view::npos); + + EXPECT_EQ(a.find_last_not_of(b), a.size()-1); + EXPECT_EQ(a.find_last_not_of(c), 22); + EXPECT_EQ(b.find_last_not_of(a), absl::string_view::npos); + EXPECT_EQ(b.find_last_not_of(b), absl::string_view::npos); + EXPECT_EQ(f.find_last_not_of(i), 4); + EXPECT_EQ(a.find_last_not_of(c, 24), 22); + EXPECT_EQ(a.find_last_not_of(b, 3), 3); + EXPECT_EQ(a.find_last_not_of(b, 2), absl::string_view::npos); + // empty std::string nonsense + EXPECT_EQ(f.find_last_not_of(d), f.size()-1); + EXPECT_EQ(f.find_last_not_of(e), f.size()-1); + EXPECT_EQ(f.find_last_not_of(d, 4), 4); + EXPECT_EQ(f.find_last_not_of(e, 4), 4); + EXPECT_EQ(d.find_last_not_of(d), absl::string_view::npos); + EXPECT_EQ(d.find_last_not_of(e), absl::string_view::npos); + EXPECT_EQ(e.find_last_not_of(d), absl::string_view::npos); + EXPECT_EQ(e.find_last_not_of(e), absl::string_view::npos); + EXPECT_EQ(d.find_last_not_of(f), absl::string_view::npos); + EXPECT_EQ(e.find_last_not_of(f), absl::string_view::npos); + EXPECT_EQ(d.find_last_not_of(d, 4), absl::string_view::npos); + EXPECT_EQ(d.find_last_not_of(e, 4), absl::string_view::npos); + EXPECT_EQ(e.find_last_not_of(d, 4), absl::string_view::npos); + EXPECT_EQ(e.find_last_not_of(e, 4), absl::string_view::npos); + EXPECT_EQ(d.find_last_not_of(f, 4), absl::string_view::npos); + EXPECT_EQ(e.find_last_not_of(f, 4), absl::string_view::npos); + + EXPECT_EQ(h.find_last_not_of('x'), h.size() - 1); + EXPECT_EQ(h.find_last_not_of('='), absl::string_view::npos); + EXPECT_EQ(b.find_last_not_of('c'), 1); + EXPECT_EQ(h.find_last_not_of('x', 2), 2); + EXPECT_EQ(h.find_last_not_of('=', 2), absl::string_view::npos); + EXPECT_EQ(b.find_last_not_of('b', 1), 0); + // empty std::string nonsense + EXPECT_EQ(d.find_last_not_of('x'), absl::string_view::npos); + EXPECT_EQ(e.find_last_not_of('x'), absl::string_view::npos); + EXPECT_EQ(d.find_last_not_of('\0'), absl::string_view::npos); + EXPECT_EQ(e.find_last_not_of('\0'), absl::string_view::npos); +} + +// Continued from STL2 +TEST(StringViewTest, STL2Substr) { + const absl::string_view a("abcdefghijklmnopqrstuvwxyz"); + const absl::string_view b("abc"); + const absl::string_view c("xyz"); + absl::string_view d("foobar"); + const absl::string_view e; + + d = absl::string_view(); + EXPECT_EQ(a.substr(0, 3), b); + EXPECT_EQ(a.substr(23), c); + EXPECT_EQ(a.substr(23, 3), c); + EXPECT_EQ(a.substr(23, 99), c); + EXPECT_EQ(a.substr(0), a); + EXPECT_EQ(a.substr(3, 2), "de"); + // empty std::string nonsense + EXPECT_EQ(d.substr(0, 99), e); + // use of npos + EXPECT_EQ(a.substr(0, absl::string_view::npos), a); + EXPECT_EQ(a.substr(23, absl::string_view::npos), c); + // throw exception +#ifdef ABSL_HAVE_EXCEPTIONS + EXPECT_THROW(a.substr(99, 2), std::out_of_range); +#else + EXPECT_DEATH(a.substr(99, 2), "absl::string_view::substr"); +#endif +} + +TEST(StringViewTest, TruncSubstr) { + const absl::string_view hi("hi"); + EXPECT_EQ("", absl::ClippedSubstr(hi, 0, 0)); + EXPECT_EQ("h", absl::ClippedSubstr(hi, 0, 1)); + EXPECT_EQ("hi", absl::ClippedSubstr(hi, 0)); + EXPECT_EQ("i", absl::ClippedSubstr(hi, 1)); + EXPECT_EQ("", absl::ClippedSubstr(hi, 2)); + EXPECT_EQ("", absl::ClippedSubstr(hi, 3)); // truncation + EXPECT_EQ("", absl::ClippedSubstr(hi, 3, 2)); // truncation +} + +TEST(StringViewTest, UTF8) { + EXPECT_EQ(strlen("á"), absl::string_view("á á").find_first_of(" ")); + EXPECT_EQ(strlen("á"), absl::string_view("á á").find_first_of(" \t")); +} + +TEST(StringViewTest, FindConformance) { + struct { + std::string haystack; + std::string needle; + } specs[] = { + {"", ""}, + {"", "a"}, + {"a", ""}, + {"a", "a"}, + {"a", "b"}, + {"aa", ""}, + {"aa", "a"}, + {"aa", "b"}, + {"ab", "a"}, + {"ab", "b"}, + {"abcd", ""}, + {"abcd", "a"}, + {"abcd", "d"}, + {"abcd", "ab"}, + {"abcd", "bc"}, + {"abcd", "cd"}, + {"abcd", "abcd"}, + }; + for (const auto& s : specs) { + SCOPED_TRACE(s.haystack); + SCOPED_TRACE(s.needle); + std::string st = s.haystack; + absl::string_view sp = s.haystack; + for (size_t i = 0; i <= sp.size(); ++i) { + size_t pos = (i == sp.size()) ? absl::string_view::npos : i; + SCOPED_TRACE(pos); + EXPECT_EQ(sp.find(s.needle, pos), + st.find(s.needle, pos)); + EXPECT_EQ(sp.rfind(s.needle, pos), + st.rfind(s.needle, pos)); + EXPECT_EQ(sp.find_first_of(s.needle, pos), + st.find_first_of(s.needle, pos)); + EXPECT_EQ(sp.find_first_not_of(s.needle, pos), + st.find_first_not_of(s.needle, pos)); + EXPECT_EQ(sp.find_last_of(s.needle, pos), + st.find_last_of(s.needle, pos)); + EXPECT_EQ(sp.find_last_not_of(s.needle, pos), + st.find_last_not_of(s.needle, pos)); + } + } +} + +TEST(StringViewTest, Remove) { + absl::string_view a("foobar"); + std::string s1("123"); + s1 += '\0'; + s1 += "456"; + absl::string_view b(s1); + absl::string_view e; + std::string s2; + + // remove_prefix + absl::string_view c(a); + c.remove_prefix(3); + EXPECT_EQ(c, "bar"); + c = a; + c.remove_prefix(0); + EXPECT_EQ(c, a); + c.remove_prefix(c.size()); + EXPECT_EQ(c, e); + + // remove_suffix + c = a; + c.remove_suffix(3); + EXPECT_EQ(c, "foo"); + c = a; + c.remove_suffix(0); + EXPECT_EQ(c, a); + c.remove_suffix(c.size()); + EXPECT_EQ(c, e); +} + +TEST(StringViewTest, Set) { + absl::string_view a("foobar"); + absl::string_view empty; + absl::string_view b; + + // set + b = absl::string_view("foobar", 6); + EXPECT_EQ(b, a); + b = absl::string_view("foobar", 0); + EXPECT_EQ(b, empty); + b = absl::string_view("foobar", 7); + EXPECT_NE(b, a); + + b = absl::string_view("foobar"); + EXPECT_EQ(b, a); +} + +TEST(StringViewTest, FrontBack) { + static const char arr[] = "abcd"; + const absl::string_view csp(arr, 4); + EXPECT_EQ(&arr[0], &csp.front()); + EXPECT_EQ(&arr[3], &csp.back()); +} + +TEST(StringViewTest, FrontBackSingleChar) { + static const char c = 'a'; + const absl::string_view csp(&c, 1); + EXPECT_EQ(&c, &csp.front()); + EXPECT_EQ(&c, &csp.back()); +} + +TEST(StringViewTest, NULLInput) { + absl::string_view s; + EXPECT_EQ(s.data(), nullptr); + EXPECT_EQ(s.size(), 0); + + s = absl::string_view(nullptr); + EXPECT_EQ(s.data(), nullptr); + EXPECT_EQ(s.size(), 0); + + // .ToString() on a absl::string_view with nullptr should produce the empty + // std::string. + EXPECT_EQ("", std::string(s)); +} + +TEST(StringViewTest, Comparisons2) { + // The `compare` member has 6 overloads (v: string_view, s: const char*): + // (1) compare(v) + // (2) compare(pos1, count1, v) + // (3) compare(pos1, count1, v, pos2, count2) + // (4) compare(s) + // (5) compare(pos1, count1, s) + // (6) compare(pos1, count1, s, count2) + + absl::string_view abc("abcdefghijklmnopqrstuvwxyz"); + + // check comparison operations on strings longer than 4 bytes. + EXPECT_EQ(abc, absl::string_view("abcdefghijklmnopqrstuvwxyz")); + EXPECT_EQ(abc.compare(absl::string_view("abcdefghijklmnopqrstuvwxyz")), 0); + + EXPECT_LT(abc, absl::string_view("abcdefghijklmnopqrstuvwxzz")); + EXPECT_LT(abc.compare(absl::string_view("abcdefghijklmnopqrstuvwxzz")), 0); + + EXPECT_GT(abc, absl::string_view("abcdefghijklmnopqrstuvwxyy")); + EXPECT_GT(abc.compare(absl::string_view("abcdefghijklmnopqrstuvwxyy")), 0); + + // The "substr" variants of `compare`. + absl::string_view digits("0123456789"); + auto npos = absl::string_view::npos; + + // Taking string_view + EXPECT_EQ(digits.compare(3, npos, absl::string_view("3456789")), 0); // 2 + EXPECT_EQ(digits.compare(3, 4, absl::string_view("3456")), 0); // 2 + EXPECT_EQ(digits.compare(10, 0, absl::string_view()), 0); // 2 + EXPECT_EQ(digits.compare(3, 4, absl::string_view("0123456789"), 3, 4), + 0); // 3 + EXPECT_LT(digits.compare(3, 4, absl::string_view("0123456789"), 3, 5), + 0); // 3 + EXPECT_LT(digits.compare(0, npos, absl::string_view("0123456789"), 3, 5), + 0); // 3 + // Taking const char* + EXPECT_EQ(digits.compare(3, 4, "3456"), 0); // 5 + EXPECT_EQ(digits.compare(3, npos, "3456789"), 0); // 5 + EXPECT_EQ(digits.compare(10, 0, ""), 0); // 5 + EXPECT_EQ(digits.compare(3, 4, "0123456789", 3, 4), 0); // 6 + EXPECT_LT(digits.compare(3, 4, "0123456789", 3, 5), 0); // 6 + EXPECT_LT(digits.compare(0, npos, "0123456789", 3, 5), 0); // 6 +} + +struct MyCharAlloc : std::allocator {}; + +TEST(StringViewTest, ExplicitConversionOperator) { + absl::string_view sp = "hi"; + EXPECT_EQ(sp, std::string(sp)); +} + +TEST(StringViewTest, NullSafeStringView) { + { + absl::string_view s = absl::NullSafeStringView(nullptr); + EXPECT_EQ(nullptr, s.data()); + EXPECT_EQ(0, s.size()); + EXPECT_EQ(absl::string_view(), s); + } + { + static const char kHi[] = "hi"; + absl::string_view s = absl::NullSafeStringView(kHi); + EXPECT_EQ(kHi, s.data()); + EXPECT_EQ(strlen(kHi), s.size()); + EXPECT_EQ(absl::string_view("hi"), s); + } +} + +TEST(StringViewTest, ConstexprCompiles) { + constexpr absl::string_view sp; + constexpr absl::string_view cstr(nullptr); + constexpr absl::string_view cstr_len("cstr", 4); + +#if defined(ABSL_HAVE_STD_STRING_VIEW) + // In libstdc++ (as of 7.2), `std::string_view::string_view(const char*)` + // calls `std::char_traits::length(const char*)` to get the std::string + // length, but it is not marked constexpr yet. See GCC bug: + // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78156 + // Also, there is a LWG issue that adds constexpr to length() which was just + // resolved 2017-06-02. See + // http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2232 + // TODO(zhangxy): Update the condition when libstdc++ adopts the constexpr + // length(). +#if !defined(__GLIBCXX__) +#define ABSL_HAVE_CONSTEXPR_STRING_VIEW_FROM_CSTR 1 +#endif // !__GLIBCXX__ + +#else // ABSL_HAVE_STD_STRING_VIEW + +// This duplicates the check for __builtin_strlen in the header. +#if ABSL_HAVE_BUILTIN(__builtin_strlen) || \ + (defined(__GNUC__) && !defined(__clang__)) +#define ABSL_HAVE_CONSTEXPR_STRING_VIEW_FROM_CSTR 1 +#elif defined(__GNUC__) // GCC or clang +#error GCC/clang should have constexpr string_view. +#endif + +#endif // ABSL_HAVE_STD_STRING_VIEW + +#ifdef ABSL_HAVE_CONSTEXPR_STRING_VIEW_FROM_CSTR + constexpr absl::string_view cstr_strlen("foo"); + EXPECT_EQ(cstr_strlen.length(), 3); + constexpr absl::string_view cstr_strlen2 = "bar"; + EXPECT_EQ(cstr_strlen2, "bar"); +#endif + +#if !defined(__clang__) || 3 < __clang_major__ || \ + (3 == __clang_major__ && 4 < __clang_minor__) + // older clang versions (< 3.5) complain that: + // "cannot perform pointer arithmetic on null pointer" + constexpr absl::string_view::iterator const_begin_empty = sp.begin(); + constexpr absl::string_view::iterator const_end_empty = sp.end(); + EXPECT_EQ(const_begin_empty, const_end_empty); + + constexpr absl::string_view::iterator const_begin_nullptr = cstr.begin(); + constexpr absl::string_view::iterator const_end_nullptr = cstr.end(); + EXPECT_EQ(const_begin_nullptr, const_end_nullptr); +#endif + + constexpr absl::string_view::iterator const_begin = cstr_len.begin(); + constexpr absl::string_view::iterator const_end = cstr_len.end(); + constexpr absl::string_view::size_type const_size = cstr_len.size(); + constexpr absl::string_view::size_type const_length = cstr_len.length(); + EXPECT_EQ(const_begin + const_size, const_end); + EXPECT_EQ(const_begin + const_length, const_end); + + constexpr bool isempty = sp.empty(); + EXPECT_TRUE(isempty); + + constexpr const char c = cstr_len[2]; + EXPECT_EQ(c, 't'); + + constexpr const char cfront = cstr_len.front(); + constexpr const char cback = cstr_len.back(); + EXPECT_EQ(cfront, 'c'); + EXPECT_EQ(cback, 'r'); + + constexpr const char* np = sp.data(); + constexpr const char* cstr_ptr = cstr_len.data(); + EXPECT_EQ(np, nullptr); + EXPECT_NE(cstr_ptr, nullptr); + + constexpr size_t sp_npos = sp.npos; + EXPECT_EQ(sp_npos, -1); +} + +TEST(StringViewTest, Noexcept) { + EXPECT_TRUE((std::is_nothrow_constructible::value)); + EXPECT_TRUE( + (std::is_nothrow_constructible::value)); + EXPECT_TRUE(std::is_nothrow_constructible::value); + constexpr absl::string_view sp; + EXPECT_TRUE(noexcept(sp.begin())); + EXPECT_TRUE(noexcept(sp.end())); + EXPECT_TRUE(noexcept(sp.cbegin())); + EXPECT_TRUE(noexcept(sp.cend())); + EXPECT_TRUE(noexcept(sp.rbegin())); + EXPECT_TRUE(noexcept(sp.rend())); + EXPECT_TRUE(noexcept(sp.crbegin())); + EXPECT_TRUE(noexcept(sp.crend())); + EXPECT_TRUE(noexcept(sp.size())); + EXPECT_TRUE(noexcept(sp.length())); + EXPECT_TRUE(noexcept(sp.empty())); + EXPECT_TRUE(noexcept(sp.data())); + EXPECT_TRUE(noexcept(sp.compare(sp))); + EXPECT_TRUE(noexcept(sp.find(sp))); + EXPECT_TRUE(noexcept(sp.find('f'))); + EXPECT_TRUE(noexcept(sp.rfind(sp))); + EXPECT_TRUE(noexcept(sp.rfind('f'))); + EXPECT_TRUE(noexcept(sp.find_first_of(sp))); + EXPECT_TRUE(noexcept(sp.find_first_of('f'))); + EXPECT_TRUE(noexcept(sp.find_last_of(sp))); + EXPECT_TRUE(noexcept(sp.find_last_of('f'))); + EXPECT_TRUE(noexcept(sp.find_first_not_of(sp))); + EXPECT_TRUE(noexcept(sp.find_first_not_of('f'))); + EXPECT_TRUE(noexcept(sp.find_last_not_of(sp))); + EXPECT_TRUE(noexcept(sp.find_last_not_of('f'))); +} + +TEST(ComparisonOpsTest, StringCompareNotAmbiguous) { + EXPECT_EQ("hello", std::string("hello")); + EXPECT_LT("hello", std::string("world")); +} + +TEST(ComparisonOpsTest, HeterogenousStringViewEquals) { + EXPECT_EQ(absl::string_view("hello"), std::string("hello")); + EXPECT_EQ("hello", absl::string_view("hello")); +} + +TEST(FindOneCharTest, EdgeCases) { + absl::string_view a("xxyyyxx"); + + // Set a = "xyyyx". + a.remove_prefix(1); + a.remove_suffix(1); + + EXPECT_EQ(0, a.find('x')); + EXPECT_EQ(0, a.find('x', 0)); + EXPECT_EQ(4, a.find('x', 1)); + EXPECT_EQ(4, a.find('x', 4)); + EXPECT_EQ(absl::string_view::npos, a.find('x', 5)); + + EXPECT_EQ(4, a.rfind('x')); + EXPECT_EQ(4, a.rfind('x', 5)); + EXPECT_EQ(4, a.rfind('x', 4)); + EXPECT_EQ(0, a.rfind('x', 3)); + EXPECT_EQ(0, a.rfind('x', 0)); + + // Set a = "yyy". + a.remove_prefix(1); + a.remove_suffix(1); + + EXPECT_EQ(absl::string_view::npos, a.find('x')); + EXPECT_EQ(absl::string_view::npos, a.rfind('x')); +} + +#ifndef THREAD_SANITIZER // Allocates too much memory for tsan. +TEST(HugeStringView, TwoPointTwoGB) { + if (sizeof(size_t) <= 4 || RunningOnValgrind()) + return; + // Try a huge std::string piece. + const size_t size = size_t{2200} * 1000 * 1000; + std::string s(size, 'a'); + absl::string_view sp(s); + EXPECT_EQ(size, sp.length()); + sp.remove_prefix(1); + EXPECT_EQ(size - 1, sp.length()); + sp.remove_suffix(2); + EXPECT_EQ(size - 1 - 2, sp.length()); +} +#endif // THREAD_SANITIZER + +#ifndef NDEBUG +TEST(NonNegativeLenTest, NonNegativeLen) { + EXPECT_DEATH_IF_SUPPORTED(absl::string_view("xyz", -1), "len <= kMaxSize"); +} +#endif // NDEBUG + +class StringViewStreamTest : public ::testing::Test { + public: + // Set negative 'width' for right justification. + template + std::string Pad(const T& s, int width, char fill = 0) { + std::ostringstream oss; + if (fill != 0) { + oss << std::setfill(fill); + } + if (width < 0) { + width = -width; + oss << std::right; + } + oss << std::setw(width) << s; + return oss.str(); + } +}; + +TEST_F(StringViewStreamTest, Padding) { + std::string s("hello"); + absl::string_view sp(s); + for (int w = -64; w < 64; ++w) { + SCOPED_TRACE(w); + EXPECT_EQ(Pad(s, w), Pad(sp, w)); + } + for (int w = -64; w < 64; ++w) { + SCOPED_TRACE(w); + EXPECT_EQ(Pad(s, w, '#'), Pad(sp, w, '#')); + } +} + +TEST_F(StringViewStreamTest, ResetsWidth) { + // Width should reset after one formatted write. + // If we weren't resetting width after formatting the string_view, + // we'd have width=5 carrying over to the printing of the "]", + // creating "[###hi####]". + std::string s = "hi"; + absl::string_view sp = s; + { + std::ostringstream oss; + oss << "[" << std::setfill('#') << std::setw(5) << s << "]"; + ASSERT_EQ("[###hi]", oss.str()); + } + { + std::ostringstream oss; + oss << "[" << std::setfill('#') << std::setw(5) << sp << "]"; + EXPECT_EQ("[###hi]", oss.str()); + } +} + +} // namespace -- cgit v1.2.3 From 82810a84ff6fa60abe4ca8a1732c94450e834f84 Mon Sep 17 00:00:00 2001 From: Marek Gilbert Date: Wed, 6 Dec 2017 09:24:31 -0800 Subject: Add abseil-cpp to the superbuild --- CMakeLists.txt | 1 + cmake/external/abseil-cpp.cmake | 36 ++++++++++++++++++++++++++++++++++++ cmake/external/firestore.cmake | 2 +- 3 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 cmake/external/abseil-cpp.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index f9e7527..efea997 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,4 +27,5 @@ set(FIREBASE_DOWNLOAD_DIR "${PROJECT_SOURCE_DIR}/.downloads") enable_testing() include(external/googletest) +include(external/abseil-cpp) include(external/firestore) diff --git a/cmake/external/abseil-cpp.cmake b/cmake/external/abseil-cpp.cmake new file mode 100644 index 0000000..e3deec3 --- /dev/null +++ b/cmake/external/abseil-cpp.cmake @@ -0,0 +1,36 @@ +# 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. + +include(ExternalProject) + +set(source_dir ${PROJECT_SOURCE_DIR}/Firestore/third_party/abseil-cpp) +set(binary_dir ${PROJECT_BINARY_DIR}/Firestore/third_party/abseil-cpp) + +ExternalProject_Add( + abseil-cpp + DEPENDS googletest + + PREFIX "${binary_dir}" + SOURCE_DIR "${source_dir}" + BINARY_DIR "${binary_dir}" + + INSTALL_DIR "${FIREBASE_INSTALL_DIR}" + INSTALL_COMMAND "" + TEST_BEFORE_INSTALL ON + + CMAKE_ARGS + -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE} + -DCMAKE_INSTALL_PREFIX:PATH= +) + diff --git a/cmake/external/firestore.cmake b/cmake/external/firestore.cmake index 5316873..dd37b51 100644 --- a/cmake/external/firestore.cmake +++ b/cmake/external/firestore.cmake @@ -19,7 +19,7 @@ set(binary_dir ${PROJECT_BINARY_DIR}/Firestore) ExternalProject_Add( Firestore - DEPENDS googletest + DEPENDS googletest abseil-cpp # Lay the binary directory out as if this were a subproject. This makes it # possible to build and test in it directly. -- cgit v1.2.3 From 73869c741fd9619dfc03937de5b97ce599db87c8 Mon Sep 17 00:00:00 2001 From: Paul Beusterien Date: Thu, 7 Dec 2017 14:30:46 -0800 Subject: Fix warnings in FirebaseCore Unit Tests (#544) --- Example/Core/Tests/FIRAppTest.m | 13 ++++++++++++- Example/Core/Tests/FIRLoggerTest.m | 4 ++++ Example/Core/Tests/FIROptionsTest.m | 6 ++++++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/Example/Core/Tests/FIRAppTest.m b/Example/Core/Tests/FIRAppTest.m index 9b3554d..432c593 100644 --- a/Example/Core/Tests/FIRAppTest.m +++ b/Example/Core/Tests/FIRAppTest.m @@ -96,7 +96,10 @@ NSString *const kFIRTestAppName2 = @"test-app-name-2"; - (void)testConfigureWithOptions { // nil options +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wnonnull" XCTAssertThrows([FIRApp configureWithOptions:nil]); +#pragma clang diagnostic pop XCTAssertTrue([FIRApp allApps].count == 0); NSDictionary *expectedUserInfo = @@ -117,6 +120,8 @@ NSString *const kFIRTestAppName2 = @"test-app-name-2"; - (void)testConfigureWithCustomizedOptions { // valid customized options +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wnonnull" FIROptions *options = [[FIROptions alloc] initWithGoogleAppID:kGoogleAppID bundleID:kBundleID GCMSenderID:kGCMSenderID @@ -127,7 +132,7 @@ NSString *const kFIRTestAppName2 = @"test-app-name-2"; databaseURL:nil storageBucket:nil deepLinkURLScheme:nil]; - +#pragma clang diagnostic pop NSDictionary *expectedUserInfo = [self expectedUserInfoWithAppName:kFIRDefaultAppName isDefaultApp:YES]; OCMExpect([self.notificationCenterMock postNotificationName:kFIRAppReadyToConfigureSDKNotification @@ -146,8 +151,11 @@ NSString *const kFIRTestAppName2 = @"test-app-name-2"; } - (void)testConfigureWithNameAndOptions { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wnonnull" XCTAssertThrows([FIRApp configureWithName:nil options:[FIROptions defaultOptions]]); XCTAssertThrows([FIRApp configureWithName:kFIRTestAppName1 options:nil]); +#pragma clang diagnostic pop XCTAssertThrows([FIRApp configureWithName:@"" options:[FIROptions defaultOptions]]); XCTAssertThrows( [FIRApp configureWithName:kFIRDefaultAppName options:[FIROptions defaultOptions]]); @@ -186,6 +194,8 @@ NSString *const kFIRTestAppName2 = @"test-app-name-2"; self.app = [FIRApp appNamed:kFIRTestAppName1]; // Configure a different app with valid customized options +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wnonnull" FIROptions *customizedOptions = [[FIROptions alloc] initWithGoogleAppID:kGoogleAppID bundleID:kBundleID GCMSenderID:kGCMSenderID @@ -196,6 +206,7 @@ NSString *const kFIRTestAppName2 = @"test-app-name-2"; databaseURL:nil storageBucket:nil deepLinkURLScheme:nil]; +#pragma clang diagnostic pop NSDictionary *expectedUserInfo2 = [self expectedUserInfoWithAppName:kFIRTestAppName2 isDefaultApp:NO]; diff --git a/Example/Core/Tests/FIRLoggerTest.m b/Example/Core/Tests/FIRLoggerTest.m index 7740527..eab2e1e 100644 --- a/Example/Core/Tests/FIRLoggerTest.m +++ b/Example/Core/Tests/FIRLoggerTest.m @@ -149,7 +149,11 @@ static NSString *const kMessageCode = @"I-COR000001"; XCTAssertThrows(FIRLogError(kFIRLoggerCore, @"I-app000001", @"Message.")); // nil or empty message code should fail. +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wnonnull" XCTAssertThrows(FIRLogError(kFIRLoggerCore, nil, @"Message.")); +#pragma clang diagnostic pop + XCTAssertThrows(FIRLogError(kFIRLoggerCore, @"", @"Message.")); // Android message code should fail. diff --git a/Example/Core/Tests/FIROptionsTest.m b/Example/Core/Tests/FIROptionsTest.m index d01eec5..1423d0a 100644 --- a/Example/Core/Tests/FIROptionsTest.m +++ b/Example/Core/Tests/FIROptionsTest.m @@ -110,6 +110,8 @@ extern NSString *const kFIRLibraryVersionID; XCTAssertFalse(options.usingOptionsFromDefaultPlist); // nil GoogleAppID should throw an exception +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wnonnull" XCTAssertThrows([[FIROptions alloc] initWithGoogleAppID:nil bundleID:kBundleID GCMSenderID:kGCMSenderID @@ -120,6 +122,7 @@ extern NSString *const kFIRLibraryVersionID; databaseURL:nil storageBucket:nil deepLinkURLScheme:nil]); +#pragma clang diagnostic pop } - (void)testinitWithContentsOfFile { @@ -130,7 +133,10 @@ extern NSString *const kFIRLibraryVersionID; XCTAssertNil(options.deepLinkURLScheme); XCTAssertFalse(options.usingOptionsFromDefaultPlist); +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wnonnull" FIROptions *emptyOptions = [[FIROptions alloc] initWithContentsOfFile:nil]; +#pragma clang diagnostic pop XCTAssertNil(emptyOptions); FIROptions *invalidOptions = [[FIROptions alloc] initWithContentsOfFile:@"invalid.plist"]; -- cgit v1.2.3 From e00d46e8c94a2703d2bd58493e4bb45d0d581005 Mon Sep 17 00:00:00 2001 From: Marek Gilbert Date: Thu, 7 Dec 2017 17:33:57 -0800 Subject: Remove commented out code --- Firestore/third_party/abseil-cpp/CMakeLists.txt | 11 - .../third_party/abseil-cpp/absl/CMakeLists.txt | 9 - .../abseil-cpp/absl/base/CMakeLists.txt | 228 +-------------------- .../abseil-cpp/absl/base/config_test.cc | 19 -- .../abseil-cpp/absl/strings/CMakeLists.txt | 171 ---------------- 5 files changed, 1 insertion(+), 437 deletions(-) diff --git a/Firestore/third_party/abseil-cpp/CMakeLists.txt b/Firestore/third_party/abseil-cpp/CMakeLists.txt index 0da6c42..1c53a72 100644 --- a/Firestore/third_party/abseil-cpp/CMakeLists.txt +++ b/Firestore/third_party/abseil-cpp/CMakeLists.txt @@ -55,16 +55,6 @@ find_package(Threads REQUIRED) find_package(GTest REQUIRED) -# commented: used only for standalone test -#add_subdirectory(cctz) -#add_subdirectory(googletest) - -## check targets -#check_target(cctz) -#check_target(gtest) -#check_target(gtest_main) -#check_target(gmock) - # -fexceptions set(ABSL_EXCEPTIONS_FLAG "${CMAKE_CXX_EXCEPTIONS}") @@ -74,7 +64,6 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FIX_MSVC} ${CMAKE_CXX_FLAGS}") list(APPEND ABSL_TEST_COMMON_LIBRARIES GTest::Main GTest::GTest - #GMock::GMock ${CMAKE_THREAD_LIBS_INIT} ) diff --git a/Firestore/third_party/abseil-cpp/absl/CMakeLists.txt b/Firestore/third_party/abseil-cpp/absl/CMakeLists.txt index c909ba0..fb158fa 100644 --- a/Firestore/third_party/abseil-cpp/absl/CMakeLists.txt +++ b/Firestore/third_party/abseil-cpp/absl/CMakeLists.txt @@ -17,14 +17,5 @@ add_subdirectory(base) -#add_subdirectory(algorithm) -#add_subdirectory(container) -#add_subdirectory(debugging) -#add_subdirectory(memory) add_subdirectory(meta) -#add_subdirectory(numeric) add_subdirectory(strings) -#add_subdirectory(synchronization) -#add_subdirectory(time) -#add_subdirectory(types) -#add_subdirectory(utility) diff --git a/Firestore/third_party/abseil-cpp/absl/base/CMakeLists.txt b/Firestore/third_party/abseil-cpp/absl/base/CMakeLists.txt index 1adc249..842bb47 100644 --- a/Firestore/third_party/abseil-cpp/absl/base/CMakeLists.txt +++ b/Firestore/third_party/abseil-cpp/absl/base/CMakeLists.txt @@ -16,57 +16,26 @@ list(APPEND BASE_PUBLIC_HEADERS "attributes.h" -# "call_once.h" -# "casts.h" "config.h" "dynamic_annotations.h" "macros.h" "optimization.h" "policy_checks.h" "port.h" -# "thread_annotations.h" ) list(APPEND BASE_INTERNAL_HEADERS "internal/atomic_hook.h" -# "internal/cycleclock.h" -# "internal/endian.h" -# "internal/exception_testing.h" -# "internal/identity.h" -# "internal/invoke.h" "internal/log_severity.h" -# "internal/low_level_alloc.h" -# "internal/low_level_scheduling.h" -# "internal/malloc_extension_c.h" -# "internal/malloc_extension.h" -# "internal/malloc_hook_c.h" -# "internal/malloc_hook.h" -# "internal/malloc_hook_invoke.h" -# "internal/per_thread_tls.h" "internal/raw_logging.h" -# "internal/scheduling_mode.h" -# "internal/spinlock.h" -# "internal/spinlock_wait.h" -# "internal/sysinfo.h" -# "internal/thread_identity.h" "internal/throw_delegate.h" -# "internal/tsan_mutex_interface.h" -# "internal/unaligned_access.h" -# "internal/unscaledcycleclock.h" ) # absl_base main library list(APPEND BASE_SRC -# "internal/cycleclock.cc" "internal/raw_logging.cc" -# "internal/spinlock.cc" -# "internal/sysinfo.cc" -# "internal/thread_identity.cc" -# "internal/unscaledcycleclock.cc" -# "internal/low_level_alloc.cc" -# "internal/malloc_hook.cc" ${BASE_PUBLIC_HEADERS} ${BASE_INTERNAL_HEADERS} ) @@ -78,25 +47,10 @@ absl_library( ${BASE_SRC} PUBLIC_LIBRARIES absl_dynamic_annotations -# absl_spinlock_wait EXPORT_NAME base ) -## malloc extension library -#set(MALLOC_EXTENSION_SRC "internal/malloc_extension.cc") -#set(MALLOC_EXTENSION_PUBLIC_LIBRARIES absl::base) -# -#absl_library( -# TARGET -# absl_malloc_extension -# SOURCES -# ${MALLOC_EXTENSION_SRC} -# PUBLIC_LIBRARIES -# ${MALLOC_EXTENSION_PUBLIC_LIBRARIES} -# EXPORT_NAME -# malloc_extension -#) # throw delegate library set(THROW_DELEGATE_SRC "internal/throw_delegate.cc") @@ -126,130 +80,9 @@ absl_library( ) -## spinlock_wait library -#set(SPINLOCK_WAIT_SRC "internal/spinlock_wait.cc") -# -#absl_library( -# TARGET -# absl_spinlock_wait -# SOURCES -# ${SPINLOCK_WAIT_SRC} -#) -# -# -## malloc_internal library -#list(APPEND MALLOC_INTERNAL_SRC -# "internal/low_level_alloc.cc" -# "internal/malloc_hook.cc" -# "internal/malloc_hook_mmap_linux.inc" -#) -# -#absl_library( -# TARGET -# absl_malloc_internal -# SOURCES -# ${MALLOC_INTERNAL_SRC} -# PUBLIC_LIBRARIES -# absl_dynamic_annotations -#) -# -# -# -## -### TESTS -## -# -## call once test -#set(CALL_ONCE_TEST_SRC "call_once_test.cc") -#set(CALL_ONCE_TEST_PUBLIC_LIBRARIES absl::base absl::synchronization) -# -#absl_test( -# TARGET -# call_once_test -# SOURCES -# ${CALL_ONCE_TEST_SRC} -# PUBLIC_LIBRARIES -# ${CALL_ONCE_TEST_PUBLIC_LIBRARIES} -#) -# -# -## test bit_cast_test -#set(BIT_CAST_TEST_SRC "bit_cast_test.cc") -# -#absl_test( -# TARGET -# bit_cast_test -# SOURCES -# ${BIT_CAST_TEST_SRC} -#) -# -# -## test absl_throw_delegate_test -#set(THROW_DELEGATE_TEST_SRC "throw_delegate_test.cc") -#set(THROW_DELEGATE_TEST_PUBLIC_LIBRARIES absl::base absl_throw_delegate) -# -#absl_test( -# TARGET -# throw_delegate_test -# SOURCES -# ${THROW_DELEGATE_TEST_SRC} -# PUBLIC_LIBRARIES -# ${THROW_DELEGATE_TEST_PUBLIC_LIBRARIES} -#) -# -# -## test invoke_test -#set(INVOKE_TEST_SRC "invoke_test.cc") -#set(INVOKE_TEST_PUBLIC_LIBRARIES absl::strings) -# -#absl_test( -# TARGET -# invoke_test -# SOURCES -# ${INVOKE_TEST_SRC} -# PUBLIC_LIBRARIES -# ${INVOKE_TEST_PUBLIC_LIBRARIES} -#) -# # -## test spinlock_test_common -#set(SPINLOCK_TEST_COMMON_SRC "spinlock_test_common.cc") -#set(SPINLOCK_TEST_COMMON_PUBLIC_LIBRARIES absl::base absl::synchronization) +## TESTS # -#absl_test( -# TARGET -# spinlock_test_common -# SOURCES -# ${SPINLOCK_TEST_COMMON_SRC} -# PUBLIC_LIBRARIES -# ${SPINLOCK_TEST_COMMON_PUBLIC_LIBRARIES} -#) -# -# -## test spinlock_test -#set(SPINLOCK_TEST_SRC "spinlock_test_common.cc") -#set(SPINLOCK_TEST_PUBLIC_LIBRARIES absl::base absl::synchronization) -# -#absl_test( -# TARGET -# spinlock_test -# SOURCES -# ${SPINLOCK_TEST_SRC} -# PUBLIC_LIBRARIES -# ${SPINLOCK_TEST_PUBLIC_LIBRARIES} -#) -# -# -## test endian_test -#set(ENDIAN_TEST_SRC "internal/endian_test.cc") -# -#absl_test( -# TARGET -# endian_test -# SOURCES -# ${ENDIAN_TEST_SRC} -#) - # test config_test set(CONFIG_TEST_SRC "config_test.cc") @@ -276,62 +109,3 @@ absl_test( PUBLIC_LIBRARIES ${RAW_LOGGING_TEST_PUBLIC_LIBRARIES} ) - - -## test sysinfo_test -#set(SYSINFO_TEST_SRC "internal/sysinfo_test.cc") -#set(SYSINFO_TEST_PUBLIC_LIBRARIES absl::base absl::synchronization) -# -#absl_test( -# TARGET -# sysinfo_test -# SOURCES -# ${SYSINFO_TEST_SRC} -# PUBLIC_LIBRARIES -# ${SYSINFO_TEST_PUBLIC_LIBRARIES} -#) -# -# -## test low_level_alloc_test -#set(LOW_LEVEL_ALLOC_TEST_SRC "internal/low_level_alloc_test.cc") -#set(LOW_LEVEL_ALLOC_TEST_PUBLIC_LIBRARIES absl::base) -# -#absl_test( -# TARGET -# low_level_alloc_test -# SOURCES -# ${LOW_LEVEL_ALLOC_TEST_SRC} -# PUBLIC_LIBRARIES -# ${LOW_LEVEL_ALLOC_TEST_PUBLIC_LIBRARIES} -#) -# -# -## test thread_identity_test -#set(THREAD_IDENTITY_TEST_SRC "internal/thread_identity_test.cc") -#set(THREAD_IDENTITY_TEST_PUBLIC_LIBRARIES absl::base absl::synchronization) -# -#absl_test( -# TARGET -# thread_identity_test -# SOURCES -# ${THREAD_IDENTITY_TEST_SRC} -# PUBLIC_LIBRARIES -# ${THREAD_IDENTITY_TEST_PUBLIC_LIBRARIES} -#) -# -# -## test absl_malloc_extension_system_malloc_test -#set(MALLOC_EXTENSION_SYSTEM_MALLOC_TEST_SRC "internal/malloc_extension_test.cc") -#set(MALLOC_EXTENSION_SYSTEM_MALLOC_TEST_PUBLIC_LIBRARIES absl::base absl_malloc_extension) -#set(MALLOC_EXTENSION_SYSTEM_MALLOC_TEST_PRIVATE_COMPILE_FLAGS "-DABSL_MALLOC_EXTENSION_TEST_ALLOW_MISSING_EXTENSION=1") -# -#absl_test( -# TARGET -# absl_malloc_extension_system_malloc_test -# SOURCES -# ${MALLOC_EXTENSION_SYSTEM_MALLOC_TEST_SRC} -# PUBLIC_LIBRARIES -# ${MALLOC_EXTENSION_SYSTEM_MALLOC_TEST_PUBLIC_LIBRARIES} -# PRIVATE_COMPILE_FLAGS -# ${MALLOC_EXTENSION_SYSTEM_MALLOC_TEST_PRIVATE_COMPILE_FLAGS} -#) diff --git a/Firestore/third_party/abseil-cpp/absl/base/config_test.cc b/Firestore/third_party/abseil-cpp/absl/base/config_test.cc index 83d45b7..4e6dd6a 100644 --- a/Firestore/third_party/abseil-cpp/absl/base/config_test.cc +++ b/Firestore/third_party/abseil-cpp/absl/base/config_test.cc @@ -17,7 +17,6 @@ #include #include "gtest/gtest.h" -// #include "absl/synchronization/internal/thread_pool.h" namespace { @@ -41,22 +40,4 @@ TEST(ConfigTest, Endianness) { #endif } -#if 0 -#if defined(ABSL_HAVE_THREAD_LOCAL) -TEST(ConfigTest, ThreadLocal) { - static thread_local int mine_mine_mine = 16; - EXPECT_EQ(16, mine_mine_mine); - { - absl::synchronization_internal::ThreadPool pool(1); - pool.Schedule([&] { - EXPECT_EQ(16, mine_mine_mine); - mine_mine_mine = 32; - EXPECT_EQ(32, mine_mine_mine); - }); - } - EXPECT_EQ(16, mine_mine_mine); -} -#endif -#endif // 0 - } // namespace diff --git a/Firestore/third_party/abseil-cpp/absl/strings/CMakeLists.txt b/Firestore/third_party/abseil-cpp/absl/strings/CMakeLists.txt index 2babc9f..070bf4f 100644 --- a/Firestore/third_party/abseil-cpp/absl/strings/CMakeLists.txt +++ b/Firestore/third_party/abseil-cpp/absl/strings/CMakeLists.txt @@ -17,27 +17,14 @@ list(APPEND STRINGS_PUBLIC_HEADERS "ascii.h" -# "escaping.h" "match.h" -# "numbers.h" -# "str_cat.h" "string_view.h" -# "strip.h" -# "str_join.h" -# "str_replace.h" -# "str_split.h" -# "substitute.h" ) list(APPEND STRINGS_INTERNAL_HEADERS -# "internal/char_map.h" "internal/memutil.h" -# "internal/ostringstream.h" "internal/resize_uninitialized.h" -# "internal/str_join_internal.h" -# "internal/str_split_internal.h" -# "internal/utf8.h" ) @@ -45,16 +32,9 @@ list(APPEND STRINGS_INTERNAL_HEADERS # add string library list(APPEND STRINGS_SRC "ascii.cc" -# "escaping.cc" "internal/memutil.cc" -# "internal/utf8.cc" "match.cc" -# "numbers.cc" -# "str_cat.cc" -# "str_replace.cc" -# "str_split.cc" "string_view.cc" -# "substitute.cc" ${STRINGS_PUBLIC_HEADERS} ${STRINGS_INTERNAL_HEADERS} ) @@ -90,20 +70,6 @@ absl_test( ) -## test escaping_test -#set(ESCAPING_TEST_SRC "escaping_test.cc") -#set(ESCAPING_TEST_PUBLIC_LIBRARIES absl::strings absl::base) -# -#absl_test( -# TARGET -# escaping_test -# SOURCES -# ${ESCAPING_TEST_SRC} -# PUBLIC_LIBRARIES -# ${ESCAPING_TEST_PUBLIC_LIBRARIES} -#) - - # test ascii_test set(ASCII_TEST_SRC "ascii_test.cc") set(ASCII_TEST_PUBLIC_LIBRARIES absl::strings) @@ -132,20 +98,6 @@ absl_test( ) -## test utf8_test -#set(UTF8_TEST_SRC "internal/utf8_test.cc") -#set(UTF8_TEST_PUBLIC_LIBRARIES absl::strings absl::base) -# -#absl_test( -# TARGET -# utf8_test -# SOURCES -# ${UTF8_TEST_SRC} -# PUBLIC_LIBRARIES -# ${UTF8_TEST_PUBLIC_LIBRARIES} -#) -# -# # test string_view_test set(STRING_VIEW_TEST_SRC "string_view_test.cc") set(STRING_VIEW_TEST_PUBLIC_LIBRARIES absl::strings absl_throw_delegate absl::base) @@ -160,59 +112,6 @@ absl_test( ) -## test substitute_test -#set(SUBSTITUTE_TEST_SRC "substitute_test.cc") -#set(SUBSTITUTE_TEST_PUBLIC_LIBRARIES absl::strings absl::base) -# -#absl_test( -# TARGET -# substitute_test -# SOURCES -# ${SUBSTITUTE_TEST_SRC} -# PUBLIC_LIBRARIES -# ${SUBSTITUTE_TEST_PUBLIC_LIBRARIES} -#) -# -# -## test str_replace_test -#set(STR_REPLACE_TEST_SRC "str_replace_test.cc") -#set(STR_REPLACE_TEST_PUBLIC_LIBRARIES absl::strings absl::base absl_throw_delegate) -# -#absl_test( -# TARGET -# str_replace_test -# SOURCES -# ${STR_REPLACE_TEST_SRC} -# PUBLIC_LIBRARIES -# ${STR_REPLACE_TEST_PUBLIC_LIBRARIES} -#) -# -# -## test str_split_test -#set(STR_SPLIT_TEST_SRC "str_split_test.cc") -#set(STR_SPLIT_TEST_PUBLIC_LIBRARIES absl::strings absl::base absl_throw_delegate) -# -#absl_test( -# TARGET -# str_split_test -# SOURCES -# ${STR_SPLIT_TEST_SRC} -# PUBLIC_LIBRARIES -# ${STR_SPLIT_TEST_PUBLIC_LIBRARIES} -#) -# -# -## test ostringstream_test -#set(OSTRINGSTREAM_TEST_SRC "internal/ostringstream_test.cc") -# -#absl_test( -# TARGET -# ostringstream_test -# SOURCES -# ${OSTRINGSTREAM_TEST_SRC} -#) - - # test resize_uninitialized_test set(RESIZE_UNINITIALIZED_TEST_SRC "internal/resize_uninitialized_test.cc") @@ -222,73 +121,3 @@ absl_test( SOURCES ${RESIZE_UNINITIALIZED_TEST_SRC} ) - - -## test str_join_test -#set(STR_JOIN_TEST_SRC "str_join_test.cc") -#set(STR_JOIN_TEST_PUBLIC_LIBRARIES absl::strings) -# -#absl_test( -# TARGET -# str_join_test -# SOURCES -# ${STR_JOIN_TEST_SRC} -# PUBLIC_LIBRARIES -# ${STR_JOIN_TEST_PUBLIC_LIBRARIES} -#) -# -# -## test str_cat_test -#set(STR_CAT_TEST_SRC "str_cat_test.cc") -#set(STR_CAT_TEST_PUBLIC_LIBRARIES absl::strings) -# -#absl_test( -# TARGET -# str_cat_test -# SOURCES -# ${STR_CAT_TEST_SRC} -# PUBLIC_LIBRARIES -# ${STR_CAT_TEST_PUBLIC_LIBRARIES} -#) -# -# -## test numbers_test -#set(NUMBERS_TEST_SRC "numbers_test.cc") -#set(NUMBERS_TEST_PUBLIC_LIBRARIES absl::strings) -# -#absl_test( -# TARGET -# numbers_test -# SOURCES -# ${NUMBERS_TEST_SRC} -# PUBLIC_LIBRARIES -# ${NUMBERS_TEST_PUBLIC_LIBRARIES} -#) -# -# -## test strip_test -#set(STRIP_TEST_SRC "strip_test.cc") -#set(STRIP_TEST_PUBLIC_LIBRARIES absl::strings) -# -#absl_test( -# TARGET -# strip_test -# SOURCES -# ${STRIP_TEST_SRC} -# PUBLIC_LIBRARIES -# ${STRIP_TEST_PUBLIC_LIBRARIES} -#) -# -# -## test char_map_test -#set(CHAR_MAP_TEST_SRC "internal/char_map_test.cc") -#set(CHAR_MAP_TEST_PUBLIC_LIBRARIES absl::strings) -# -#absl_test( -# TARGET -# char_map_test -# SOURCES -# ${CHAR_MAP_TEST_SRC} -# PUBLIC_LIBRARIES -# ${CHAR_MAP_TEST_PUBLIC_LIBRARIES} -#) -- cgit v1.2.3 From 440014eb37be95491232ee6e519073bc2299eb90 Mon Sep 17 00:00:00 2001 From: zxu Date: Fri, 8 Dec 2017 09:22:56 -0500 Subject: make FIRDocumentListenOptions.includeMetadataChanges private (#540) * make FIRDocumentListenOptions.includeMetadataChanges private as discussed in Firestore API discussion, the name clashes creates confusion. Android SDK already not exposing the property; here change iOS SDK to match it. * update CHANGELOG --- Firestore/CHANGELOG.md | 2 ++ Firestore/Source/API/FIRDocumentReference.m | 2 ++ Firestore/Source/Public/FIRDocumentReference.h | 2 -- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Firestore/CHANGELOG.md b/Firestore/CHANGELOG.md index e6ecf11..32cbbfc 100644 --- a/Firestore/CHANGELOG.md +++ b/Firestore/CHANGELOG.md @@ -1,5 +1,7 @@ # Unreleased - [changed] Firestore no longer has a direct dependency on FirebaseAuth. +- [changed] Removed the includeMetadataChanges property in FIRDocumentListenOptions + to avoid confusion with the factory method of the same name. - [fixed] Fixed a crash when using path names with international characters with persistence enabled. diff --git a/Firestore/Source/API/FIRDocumentReference.m b/Firestore/Source/API/FIRDocumentReference.m index 1c80ea9..6279b7c 100644 --- a/Firestore/Source/API/FIRDocumentReference.m +++ b/Firestore/Source/API/FIRDocumentReference.m @@ -48,6 +48,8 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)initWithIncludeMetadataChanges:(BOOL)includeMetadataChanges NS_DESIGNATED_INITIALIZER; +@property(nonatomic, assign, readonly) BOOL includeMetadataChanges; + @end @implementation FIRDocumentListenOptions diff --git a/Firestore/Source/Public/FIRDocumentReference.h b/Firestore/Source/Public/FIRDocumentReference.h index 439e727..7fcc7a8 100644 --- a/Firestore/Source/Public/FIRDocumentReference.h +++ b/Firestore/Source/Public/FIRDocumentReference.h @@ -36,8 +36,6 @@ NS_SWIFT_NAME(DocumentListenOptions) - (instancetype)init; -@property(nonatomic, assign, readonly) BOOL includeMetadataChanges; - /** * Sets the includeMetadataChanges option which controls whether metadata-only changes (i.e. only * `FIRDocumentSnapshot.metadata` changed) should trigger snapshot events. Default is NO. -- cgit v1.2.3 From 3418244cd52ca4e4131ca106bf66cba754ec886c Mon Sep 17 00:00:00 2001 From: Paul Beusterien Date: Fri, 8 Dec 2017 07:31:31 -0800 Subject: Disable FirebaseCore Test deprecation warnings (#545) --- Example/Core/Tests/FIRAppTest.m | 2 ++ Example/Core/Tests/FIRLoggerTest.m | 3 +++ Example/Core/Tests/FIROptionsTest.m | 3 +++ 3 files changed, 8 insertions(+) diff --git a/Example/Core/Tests/FIRAppTest.m b/Example/Core/Tests/FIRAppTest.m index 432c593..ac7985a 100644 --- a/Example/Core/Tests/FIRAppTest.m +++ b/Example/Core/Tests/FIRAppTest.m @@ -122,6 +122,7 @@ NSString *const kFIRTestAppName2 = @"test-app-name-2"; // valid customized options #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wnonnull" +#pragma clang diagnostic ignored "-Wdeprecated-declarations" FIROptions *options = [[FIROptions alloc] initWithGoogleAppID:kGoogleAppID bundleID:kBundleID GCMSenderID:kGCMSenderID @@ -196,6 +197,7 @@ NSString *const kFIRTestAppName2 = @"test-app-name-2"; // Configure a different app with valid customized options #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wnonnull" +#pragma clang diagnostic ignored "-Wdeprecated-declarations" FIROptions *customizedOptions = [[FIROptions alloc] initWithGoogleAppID:kGoogleAppID bundleID:kBundleID GCMSenderID:kGCMSenderID diff --git a/Example/Core/Tests/FIRLoggerTest.m b/Example/Core/Tests/FIRLoggerTest.m index eab2e1e..0894fd6 100644 --- a/Example/Core/Tests/FIRLoggerTest.m +++ b/Example/Core/Tests/FIRLoggerTest.m @@ -245,6 +245,8 @@ static NSString *const kMessageCode = @"I-COR000001"; } - (BOOL)messageWasLogged:(NSString *)message { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" aslmsg query = asl_new(ASL_TYPE_QUERY); asl_set_query(query, ASL_KEY_FACILITY, kFIRLoggerASLClientFacilityName, ASL_QUERY_OP_EQUAL); aslresponse r = asl_search(getFIRLoggerClient(), query); @@ -261,6 +263,7 @@ static NSString *const kMessageCode = @"I-COR000001"; asl_free(m); asl_release(r); return [allMsg containsObject:message]; +#pragma clang pop } @end diff --git a/Example/Core/Tests/FIROptionsTest.m b/Example/Core/Tests/FIROptionsTest.m index 1423d0a..a1e5fae 100644 --- a/Example/Core/Tests/FIROptionsTest.m +++ b/Example/Core/Tests/FIROptionsTest.m @@ -80,6 +80,7 @@ extern NSString *const kFIRLibraryVersionID; } - (void)testInitCustomizedOptions { +#pragma clang diagnostic ignored "-Wdeprecated-declarations" FIROptions *options = [[FIROptions alloc] initWithGoogleAppID:kGoogleAppID bundleID:kBundleID GCMSenderID:kGCMSenderID @@ -90,6 +91,7 @@ extern NSString *const kFIRLibraryVersionID; databaseURL:kDatabaseURL storageBucket:kStorageBucket deepLinkURLScheme:kDeepLinkURLScheme]; +#pragma clang pop [self assertOptionsMatchDefaults:options andProjectID:NO]; XCTAssertEqualObjects(options.deepLinkURLScheme, kDeepLinkURLScheme); XCTAssertFalse(options.usingOptionsFromDefaultPlist); @@ -112,6 +114,7 @@ extern NSString *const kFIRLibraryVersionID; // nil GoogleAppID should throw an exception #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wnonnull" +#pragma clang diagnostic ignored "-Wdeprecated-declarations" XCTAssertThrows([[FIROptions alloc] initWithGoogleAppID:nil bundleID:kBundleID GCMSenderID:kGCMSenderID -- cgit v1.2.3 From 56c8c06594787ab778915447f552769dcb4e915a Mon Sep 17 00:00:00 2001 From: Marek Gilbert Date: Fri, 8 Dec 2017 09:43:13 -0800 Subject: Fix whitespace --- Firestore/third_party/abseil-cpp/absl/base/CMakeLists.txt | 2 +- Firestore/third_party/abseil-cpp/absl/meta/CMakeLists.txt | 3 --- cmake/external/abseil-cpp.cmake | 1 - 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/Firestore/third_party/abseil-cpp/absl/base/CMakeLists.txt b/Firestore/third_party/abseil-cpp/absl/base/CMakeLists.txt index 842bb47..a6cd1ff 100644 --- a/Firestore/third_party/abseil-cpp/absl/base/CMakeLists.txt +++ b/Firestore/third_party/abseil-cpp/absl/base/CMakeLists.txt @@ -34,7 +34,7 @@ list(APPEND BASE_INTERNAL_HEADERS # absl_base main library -list(APPEND BASE_SRC +list(APPEND BASE_SRC "internal/raw_logging.cc" ${BASE_PUBLIC_HEADERS} ${BASE_INTERNAL_HEADERS} diff --git a/Firestore/third_party/abseil-cpp/absl/meta/CMakeLists.txt b/Firestore/third_party/abseil-cpp/absl/meta/CMakeLists.txt index d56fced..a25dd61 100644 --- a/Firestore/third_party/abseil-cpp/absl/meta/CMakeLists.txt +++ b/Firestore/third_party/abseil-cpp/absl/meta/CMakeLists.txt @@ -44,6 +44,3 @@ absl_test( PUBLIC_LIBRARIES ${TYPE_TRAITS_TEST_PUBLIC_LIBRARIES} absl::meta ) - - - diff --git a/cmake/external/abseil-cpp.cmake b/cmake/external/abseil-cpp.cmake index e3deec3..d29b7d5 100644 --- a/cmake/external/abseil-cpp.cmake +++ b/cmake/external/abseil-cpp.cmake @@ -33,4 +33,3 @@ ExternalProject_Add( -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX:PATH= ) - -- cgit v1.2.3 From 49a7ed7fc9befb753a920ead5c31b80d3f7338c3 Mon Sep 17 00:00:00 2001 From: Paul Beusterien Date: Fri, 8 Dec 2017 10:12:15 -0800 Subject: Fix FCM build warning introduced in Xcode 9 (#546) --- Firebase/Messaging/FIRMessaging.m | 5 ++--- Firebase/Messaging/FIRMessagingContextManagerService.m | 2 +- Firebase/Messaging/FIRMessagingRmq2PersistentStore.m | 10 +++++++--- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/Firebase/Messaging/FIRMessaging.m b/Firebase/Messaging/FIRMessaging.m index 782b779..23feee9 100644 --- a/Firebase/Messaging/FIRMessaging.m +++ b/Firebase/Messaging/FIRMessaging.m @@ -384,7 +384,6 @@ NSString * const FIRMessagingRegistrationTokenRefreshedNotification = id appDelegate = application.delegate; SEL continueUserActivitySelector = @selector(application:continueUserActivity:restorationHandler:); - SEL openURLWithOptionsSelector = @selector(application:openURL:options:); SEL openURLWithSourceApplicationSelector = @selector(application:openURL:sourceApplication:annotation:); SEL handleOpenURLSelector = @selector(application:handleOpenURL:); @@ -403,7 +402,7 @@ NSString * const FIRMessagingRegistrationTokenRefreshedNotification = // Do nothing, as we don't support the app calling this block }]; - } else if ([appDelegate respondsToSelector:openURLWithOptionsSelector]) { + } else if (@available(iOS 9.0, *)) { [appDelegate application:application openURL:url options:@{}]; // Similarly, |application:openURL:sourceApplication:annotation:| will also always be called, due @@ -727,7 +726,7 @@ NSString * const FIRMessagingRegistrationTokenRefreshedNotification = - (void)receiver:(FIRMessagingReceiver *)receiver receivedRemoteMessage:(FIRMessagingRemoteMessage *)remoteMessage { - if ([self.delegate respondsToSelector:@selector(messaging:didReceiveMessage:)]) { + if (@available(iOS 10.0, *)) { [self.delegate messaging:self didReceiveMessage:remoteMessage]; } else if ([self.delegate respondsToSelector:@selector(applicationReceivedRemoteMessage:)]) { #pragma clang diagnostic push diff --git a/Firebase/Messaging/FIRMessagingContextManagerService.m b/Firebase/Messaging/FIRMessagingContextManagerService.m index 1c9f653..dffd6ae 100644 --- a/Firebase/Messaging/FIRMessagingContextManagerService.m +++ b/Firebase/Messaging/FIRMessagingContextManagerService.m @@ -143,7 +143,7 @@ typedef NS_ENUM(NSUInteger, FIRMessagingContextManagerMessageType) { } if ([apsDictionary[kFIRMessagingContextManagerTitleKey] length]) { // |alertTitle| is iOS 8.2+, so check if we can set it - if ([notification respondsToSelector:@selector(setAlertTitle:)]) { + if (@available(iOS 8.2, *)) { notification.alertTitle = apsDictionary[kFIRMessagingContextManagerTitleKey]; } } diff --git a/Firebase/Messaging/FIRMessagingRmq2PersistentStore.m b/Firebase/Messaging/FIRMessagingRmq2PersistentStore.m index a85298c..e468333 100644 --- a/Firebase/Messaging/FIRMessagingRmq2PersistentStore.m +++ b/Firebase/Messaging/FIRMessagingRmq2PersistentStore.m @@ -104,9 +104,13 @@ typedef void(^FCMOutgoingRmqMessagesTableHandler)(int64_t rmqId, int8_t tag, NSD // Utility to create an NSString from a sqlite3 result code NSString * _Nonnull FIRMessagingStringFromSQLiteResult(int result) { - const char *errorStr = sqlite3_errstr(result); - NSString *errorString = [NSString stringWithFormat:@"%d - %s", result, errorStr]; - return errorString; + const char *errorStr; + if (@available(iOS 8.2, *)) { + errorStr = sqlite3_errstr(result); + } else { + errorStr = "pre iOS 8.2"; + } + return [NSString stringWithFormat:@"%d - %s", result, errorStr]; } @interface FIRMessagingRmq2PersistentStore () { -- cgit v1.2.3 From 31917f566c0e5d5e1e2f4361cbc2a9f280c6aa5d Mon Sep 17 00:00:00 2001 From: Paul Beusterien Date: Fri, 8 Dec 2017 11:27:49 -0800 Subject: Double auth unit test timeout to address travis flakiness (#548) --- Example/Auth/Tests/FIRAuthAPNSTokenManagerTests.m | 2 +- Example/Auth/Tests/FIRAuthDispatcherTests.m | 2 +- Example/Auth/Tests/FIRAuthTests.m | 2 +- Example/Auth/Tests/FIRAuthURLPresenterTests.m | 2 +- Example/Auth/Tests/FIRPhoneAuthProviderTests.m | 2 +- Example/Auth/Tests/FIRUserTests.m | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Example/Auth/Tests/FIRAuthAPNSTokenManagerTests.m b/Example/Auth/Tests/FIRAuthAPNSTokenManagerTests.m index 68e8bcf..79ffb7a 100644 --- a/Example/Auth/Tests/FIRAuthAPNSTokenManagerTests.m +++ b/Example/Auth/Tests/FIRAuthAPNSTokenManagerTests.m @@ -31,7 +31,7 @@ static const NSTimeInterval kRegistrationTimeout = .5; @brief The test expectation timeout. @remarks This must be considerably greater than @c kVerificationTimeout . */ -static const NSTimeInterval kExpectationTimeout = 1; +static const NSTimeInterval kExpectationTimeout = 2; /** @class FIRAuthLegacyUIApplication @brief A fake legacy (< iOS 7) UIApplication class. diff --git a/Example/Auth/Tests/FIRAuthDispatcherTests.m b/Example/Auth/Tests/FIRAuthDispatcherTests.m index fc8cab1..193be4c 100644 --- a/Example/Auth/Tests/FIRAuthDispatcherTests.m +++ b/Example/Auth/Tests/FIRAuthDispatcherTests.m @@ -32,7 +32,7 @@ NSTimeInterval kTestDelay = 0.1; /** @var kExpectationTimeout @brief The maximum time waiting for expectations to fulfill. */ -static const NSTimeInterval kExpectationTimeout = 1; +static const NSTimeInterval kExpectationTimeout = 2; id testWorkQueue; diff --git a/Example/Auth/Tests/FIRAuthTests.m b/Example/Auth/Tests/FIRAuthTests.m index 80a9ae9..6391b08 100644 --- a/Example/Auth/Tests/FIRAuthTests.m +++ b/Example/Auth/Tests/FIRAuthTests.m @@ -170,7 +170,7 @@ static NSString *const kVerificationID = @"55432"; /** @var kExpectationTimeout @brief The maximum time waiting for expectations to fulfill. */ -static const NSTimeInterval kExpectationTimeout = 1; +static const NSTimeInterval kExpectationTimeout = 2; /** @var kWaitInterval @brief The time waiting for background tasks to finish before continue when necessary. diff --git a/Example/Auth/Tests/FIRAuthURLPresenterTests.m b/Example/Auth/Tests/FIRAuthURLPresenterTests.m index fcc64e9..a4e6c53 100644 --- a/Example/Auth/Tests/FIRAuthURLPresenterTests.m +++ b/Example/Auth/Tests/FIRAuthURLPresenterTests.m @@ -26,7 +26,7 @@ /** @var kExpectationTimeout @brief The maximum time waiting for expectations to fulfill. */ -static NSTimeInterval kExpectationTimeout = 1; +static NSTimeInterval kExpectationTimeout = 2; @interface FIRAuthDefaultUIDelegate : NSObject /** @fn defaultUIDelegate diff --git a/Example/Auth/Tests/FIRPhoneAuthProviderTests.m b/Example/Auth/Tests/FIRPhoneAuthProviderTests.m index c5f4ec7..0dc0b44 100644 --- a/Example/Auth/Tests/FIRPhoneAuthProviderTests.m +++ b/Example/Auth/Tests/FIRPhoneAuthProviderTests.m @@ -180,7 +180,7 @@ static const NSTimeInterval kTestTimeout = 5; /** @var kExpectationTimeout @brief The maximum time waiting for expectations to fulfill. */ -static const NSTimeInterval kExpectationTimeout = 1; +static const NSTimeInterval kExpectationTimeout = 2; /** @class FIRPhoneAuthProviderTests @brief Tests for @c FIRPhoneAuthProvider diff --git a/Example/Auth/Tests/FIRUserTests.m b/Example/Auth/Tests/FIRUserTests.m index c044e83..68ee265 100644 --- a/Example/Auth/Tests/FIRUserTests.m +++ b/Example/Auth/Tests/FIRUserTests.m @@ -231,7 +231,7 @@ static NSTimeInterval const kLastSignInDateTimeIntervalInSeconds = 1505858583; /** @var kExpectationTimeout @brief The maximum time waiting for expectations to fulfill. */ -static const NSTimeInterval kExpectationTimeout = 1; +static const NSTimeInterval kExpectationTimeout = 2; /** @class FIRUserTests @brief Tests for @c FIRUser . -- cgit v1.2.3 From e5b2146326b673b2037a73a839f4a70bf6c8c40e Mon Sep 17 00:00:00 2001 From: Ryan Wilson Date: Fri, 8 Dec 2017 14:51:49 -0500 Subject: Add an Info.plist flag to disable App Store Sandbox check. (#547) * Add an Info.plist flag to disable TestFlight check. This can save a small amount of memory during startup time. * Change the flag name to the intended usage. * Explicitly check for NSNumber. --- Firebase/Core/third_party/FIRAppEnvironmentUtil.m | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/Firebase/Core/third_party/FIRAppEnvironmentUtil.m b/Firebase/Core/third_party/FIRAppEnvironmentUtil.m index 3a08cfa..337f082 100644 --- a/Firebase/Core/third_party/FIRAppEnvironmentUtil.m +++ b/Firebase/Core/third_party/FIRAppEnvironmentUtil.m @@ -36,6 +36,10 @@ struct encryption_info_command { @implementation FIRAppEnvironmentUtil +/// A key for the Info.plist to enable or disable checking if the App Store is running in a sandbox, +/// which would be true while running on TestFlight. +static NSString *const kFIRAppStoreSandboxCheckEnabledKey = @"FirebaseAppStoreSandboxCheckEnabled"; + /// The file name of the sandbox receipt. This is available on iOS >= 8.0 static NSString *const kFIRAIdentitySandboxReceiptFileName = @"sandboxReceipt"; @@ -152,6 +156,16 @@ static BOOL isAppEncrypted() { } + (BOOL)isAppStoreReceiptSandbox { + // Since checking the App Store's receipt URL can be memory intensive, check the option in the + // Info.plist if developers opted out of this check. + id enableSandboxCheck = + [[NSBundle mainBundle] objectForInfoDictionaryKey:kFIRAppStoreSandboxCheckEnabledKey]; + if (enableSandboxCheck && + [enableSandboxCheck isKindOfClass:[NSNumber class]] && + ![enableSandboxCheck boolValue]) { + return NO; + } + NSURL *appStoreReceiptURL = [NSBundle mainBundle].appStoreReceiptURL; NSString *appStoreReceiptFileName = appStoreReceiptURL.lastPathComponent; return [appStoreReceiptFileName isEqualToString:kFIRAIdentitySandboxReceiptFileName]; -- cgit v1.2.3 From cd17b85587d1a827389ea1e18d0ce5622606cd5f Mon Sep 17 00:00:00 2001 From: Marek Gilbert Date: Sat, 9 Dec 2017 17:06:10 -0800 Subject: Import absl/base/internal/endian.h --- .../abseil-cpp/absl/base/internal/endian.h | 267 ++++++++++++++++++++ .../abseil-cpp/absl/base/internal/endian_test.cc | 279 +++++++++++++++++++++ .../absl/base/internal/unaligned_access.h | 256 +++++++++++++++++++ 3 files changed, 802 insertions(+) create mode 100644 Firestore/third_party/abseil-cpp/absl/base/internal/endian.h create mode 100644 Firestore/third_party/abseil-cpp/absl/base/internal/endian_test.cc create mode 100644 Firestore/third_party/abseil-cpp/absl/base/internal/unaligned_access.h diff --git a/Firestore/third_party/abseil-cpp/absl/base/internal/endian.h b/Firestore/third_party/abseil-cpp/absl/base/internal/endian.h new file mode 100644 index 0000000..602129e --- /dev/null +++ b/Firestore/third_party/abseil-cpp/absl/base/internal/endian.h @@ -0,0 +1,267 @@ +// Copyright 2017 The Abseil Authors. +// +// 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. +// + +#ifndef ABSL_BASE_INTERNAL_ENDIAN_H_ +#define ABSL_BASE_INTERNAL_ENDIAN_H_ + +// The following guarantees declaration of the byte swap functions +#ifdef _MSC_VER +#include // NOLINT(build/include) +#elif defined(__APPLE__) +// Mac OS X / Darwin features +#include +#elif defined(__GLIBC__) +#include // IWYU pragma: export +#endif + +#include +#include "absl/base/config.h" +#include "absl/base/internal/unaligned_access.h" +#include "absl/base/port.h" + +namespace absl { + +// Use compiler byte-swapping intrinsics if they are available. 32-bit +// and 64-bit versions are available in Clang and GCC as of GCC 4.3.0. +// The 16-bit version is available in Clang and GCC only as of GCC 4.8.0. +// For simplicity, we enable them all only for GCC 4.8.0 or later. +#if defined(__clang__) || \ + (defined(__GNUC__) && \ + ((__GNUC__ == 4 && __GNUC_MINOR__ >= 8) || __GNUC__ >= 5)) +inline uint64_t gbswap_64(uint64_t host_int) { + return __builtin_bswap64(host_int); +} +inline uint32_t gbswap_32(uint32_t host_int) { + return __builtin_bswap32(host_int); +} +inline uint16_t gbswap_16(uint16_t host_int) { + return __builtin_bswap16(host_int); +} + +#elif defined(_MSC_VER) +inline uint64_t gbswap_64(uint64_t host_int) { + return _byteswap_uint64(host_int); +} +inline uint32_t gbswap_32(uint32_t host_int) { + return _byteswap_ulong(host_int); +} +inline uint16_t gbswap_16(uint16_t host_int) { + return _byteswap_ushort(host_int); +} + +#elif defined(__APPLE__) +inline uint64_t gbswap_64(uint64_t host_int) { return OSSwapInt16(host_int); } +inline uint32_t gbswap_32(uint32_t host_int) { return OSSwapInt32(host_int); } +inline uint16_t gbswap_16(uint16_t host_int) { return OSSwapInt64(host_int); } + +#else +inline uint64_t gbswap_64(uint64_t host_int) { +#if defined(__GNUC__) && defined(__x86_64__) && !defined(__APPLE__) + // Adapted from /usr/include/byteswap.h. Not available on Mac. + if (__builtin_constant_p(host_int)) { + return __bswap_constant_64(host_int); + } else { + register uint64_t result; + __asm__("bswap %0" : "=r"(result) : "0"(host_int)); + return result; + } +#elif defined(__GLIBC__) + return bswap_64(host_int); +#else + return (((x & uint64_t{(0xFF}) << 56) | + ((x & uint64_t{(0xFF00}) << 40) | + ((x & uint64_t{(0xFF0000}) << 24) | + ((x & uint64_t{(0xFF000000}) << 8) | + ((x & uint64_t{(0xFF00000000}) >> 8) | + ((x & uint64_t{(0xFF0000000000}) >> 24) | + ((x & uint64_t{(0xFF000000000000}) >> 40) | + ((x & uint64_t{(0xFF00000000000000}) >> 56)); +#endif // bswap_64 +} + +inline uint32_t gbswap_32(uint32_t host_int) { +#if defined(__GLIBC__) + return bswap_32(host_int); +#else + return (((x & 0xFF) << 24) | ((x & 0xFF00) << 8) | ((x & 0xFF0000) >> 8) | + ((x & 0xFF000000) >> 24)); +#endif +} + +inline uint16_t gbswap_16(uint16_t host_int) { +#if defined(__GLIBC__) + return bswap_16(host_int); +#else + return uint16_t{((x & 0xFF) << 8) | ((x & 0xFF00) >> 8)}; +#endif +} + +#endif // intrinics available + +#ifdef ABSL_IS_LITTLE_ENDIAN + +// Definitions for ntohl etc. that don't require us to include +// netinet/in.h. We wrap gbswap_32 and gbswap_16 in functions rather +// than just #defining them because in debug mode, gcc doesn't +// correctly handle the (rather involved) definitions of bswap_32. +// gcc guarantees that inline functions are as fast as macros, so +// this isn't a performance hit. +inline uint16_t ghtons(uint16_t x) { return gbswap_16(x); } +inline uint32_t ghtonl(uint32_t x) { return gbswap_32(x); } +inline uint64_t ghtonll(uint64_t x) { return gbswap_64(x); } + +#elif defined ABSL_IS_BIG_ENDIAN + +// These definitions are simpler on big-endian machines +// These are functions instead of macros to avoid self-assignment warnings +// on calls such as "i = ghtnol(i);". This also provides type checking. +inline uint16_t ghtons(uint16_t x) { return x; } +inline uint32_t ghtonl(uint32_t x) { return x; } +inline uint64_t ghtonll(uint64_t x) { return x; } + +#else +#error \ + "Unsupported byte order: Either ABSL_IS_BIG_ENDIAN or " \ + "ABSL_IS_LITTLE_ENDIAN must be defined" +#endif // byte order + +inline uint16_t gntohs(uint16_t x) { return ghtons(x); } +inline uint32_t gntohl(uint32_t x) { return ghtonl(x); } +inline uint64_t gntohll(uint64_t x) { return ghtonll(x); } + +// Utilities to convert numbers between the current hosts's native byte +// order and little-endian byte order +// +// Load/Store methods are alignment safe +namespace little_endian { +// Conversion functions. +#ifdef ABSL_IS_LITTLE_ENDIAN + +inline uint16_t FromHost16(uint16_t x) { return x; } +inline uint16_t ToHost16(uint16_t x) { return x; } + +inline uint32_t FromHost32(uint32_t x) { return x; } +inline uint32_t ToHost32(uint32_t x) { return x; } + +inline uint64_t FromHost64(uint64_t x) { return x; } +inline uint64_t ToHost64(uint64_t x) { return x; } + +inline constexpr bool IsLittleEndian() { return true; } + +#elif defined ABSL_IS_BIG_ENDIAN + +inline uint16_t FromHost16(uint16_t x) { return gbswap_16(x); } +inline uint16_t ToHost16(uint16_t x) { return gbswap_16(x); } + +inline uint32_t FromHost32(uint32_t x) { return gbswap_32(x); } +inline uint32_t ToHost32(uint32_t x) { return gbswap_32(x); } + +inline uint64_t FromHost64(uint64_t x) { return gbswap_64(x); } +inline uint64_t ToHost64(uint64_t x) { return gbswap_64(x); } + +inline constexpr bool IsLittleEndian() { return false; } + +#endif /* ENDIAN */ + +// Functions to do unaligned loads and stores in little-endian order. +inline uint16_t Load16(const void *p) { + return ToHost16(ABSL_INTERNAL_UNALIGNED_LOAD16(p)); +} + +inline void Store16(void *p, uint16_t v) { + ABSL_INTERNAL_UNALIGNED_STORE16(p, FromHost16(v)); +} + +inline uint32_t Load32(const void *p) { + return ToHost32(ABSL_INTERNAL_UNALIGNED_LOAD32(p)); +} + +inline void Store32(void *p, uint32_t v) { + ABSL_INTERNAL_UNALIGNED_STORE32(p, FromHost32(v)); +} + +inline uint64_t Load64(const void *p) { + return ToHost64(ABSL_INTERNAL_UNALIGNED_LOAD64(p)); +} + +inline void Store64(void *p, uint64_t v) { + ABSL_INTERNAL_UNALIGNED_STORE64(p, FromHost64(v)); +} + +} // namespace little_endian + +// Utilities to convert numbers between the current hosts's native byte +// order and big-endian byte order (same as network byte order) +// +// Load/Store methods are alignment safe +namespace big_endian { +#ifdef ABSL_IS_LITTLE_ENDIAN + +inline uint16_t FromHost16(uint16_t x) { return gbswap_16(x); } +inline uint16_t ToHost16(uint16_t x) { return gbswap_16(x); } + +inline uint32_t FromHost32(uint32_t x) { return gbswap_32(x); } +inline uint32_t ToHost32(uint32_t x) { return gbswap_32(x); } + +inline uint64_t FromHost64(uint64_t x) { return gbswap_64(x); } +inline uint64_t ToHost64(uint64_t x) { return gbswap_64(x); } + +inline constexpr bool IsLittleEndian() { return true; } + +#elif defined ABSL_IS_BIG_ENDIAN + +inline uint16_t FromHost16(uint16_t x) { return x; } +inline uint16_t ToHost16(uint16_t x) { return x; } + +inline uint32_t FromHost32(uint32_t x) { return x; } +inline uint32_t ToHost32(uint32_t x) { return x; } + +inline uint64_t FromHost64(uint64_t x) { return x; } +inline uint64_t ToHost64(uint64_t x) { return x; } + +inline constexpr bool IsLittleEndian() { return false; } + +#endif /* ENDIAN */ + +// Functions to do unaligned loads and stores in big-endian order. +inline uint16_t Load16(const void *p) { + return ToHost16(ABSL_INTERNAL_UNALIGNED_LOAD16(p)); +} + +inline void Store16(void *p, uint16_t v) { + ABSL_INTERNAL_UNALIGNED_STORE16(p, FromHost16(v)); +} + +inline uint32_t Load32(const void *p) { + return ToHost32(ABSL_INTERNAL_UNALIGNED_LOAD32(p)); +} + +inline void Store32(void *p, uint32_t v) { + ABSL_INTERNAL_UNALIGNED_STORE32(p, FromHost32(v)); +} + +inline uint64_t Load64(const void *p) { + return ToHost64(ABSL_INTERNAL_UNALIGNED_LOAD64(p)); +} + +inline void Store64(void *p, uint64_t v) { + ABSL_INTERNAL_UNALIGNED_STORE64(p, FromHost64(v)); +} + +} // namespace big_endian + +} // namespace absl + +#endif // ABSL_BASE_INTERNAL_ENDIAN_H_ diff --git a/Firestore/third_party/abseil-cpp/absl/base/internal/endian_test.cc b/Firestore/third_party/abseil-cpp/absl/base/internal/endian_test.cc new file mode 100644 index 0000000..f3ff4b3 --- /dev/null +++ b/Firestore/third_party/abseil-cpp/absl/base/internal/endian_test.cc @@ -0,0 +1,279 @@ +// Copyright 2017 The Abseil Authors. +// +// 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. + +#include "absl/base/internal/endian.h" + +#include +#include +#include +#include +#include + +#include "gtest/gtest.h" +#include "absl/base/config.h" + +namespace absl { +namespace { + +const uint64_t kInitialNumber{0x0123456789abcdef}; +const uint64_t k64Value{kInitialNumber}; +const uint32_t k32Value{0x01234567}; +const uint16_t k16Value{0x0123}; +const int kNumValuesToTest = 1000000; +const int kRandomSeed = 12345; + +#ifdef ABSL_IS_BIG_ENDIAN +const uint64_t kInitialInNetworkOrder{kInitialNumber}; +const uint64_t k64ValueLE{0xefcdab8967452301}; +const uint32_t k32ValueLE{0x67452301}; +const uint16_t k16ValueLE{0x2301}; +const uint8_t k8ValueLE{k8Value}; +const uint64_t k64IValueLE{0xefcdab89674523a1}; +const uint32_t k32IValueLE{0x67452391}; +const uint16_t k16IValueLE{0x85ff}; +const uint8_t k8IValueLE{0xff}; +const uint64_t kDoubleValueLE{0x6e861bf0f9210940}; +const uint32_t kFloatValueLE{0xd00f4940}; +const uint8_t kBoolValueLE{0x1}; + +const uint64_t k64ValueBE{kInitialNumber}; +const uint32_t k32ValueBE{k32Value}; +const uint16_t k16ValueBE{k16Value}; +const uint8_t k8ValueBE{k8Value}; +const uint64_t k64IValueBE{0xa123456789abcdef}; +const uint32_t k32IValueBE{0x91234567}; +const uint16_t k16IValueBE{0xff85}; +const uint8_t k8IValueBE{0xff}; +const uint64_t kDoubleValueBE{0x400921f9f01b866e}; +const uint32_t kFloatValueBE{0x40490fd0}; +const uint8_t kBoolValueBE{0x1}; +#elif defined ABSL_IS_LITTLE_ENDIAN +const uint64_t kInitialInNetworkOrder{0xefcdab8967452301}; +const uint64_t k64ValueLE{kInitialNumber}; +const uint32_t k32ValueLE{k32Value}; +const uint16_t k16ValueLE{k16Value}; + +const uint64_t k64ValueBE{0xefcdab8967452301}; +const uint32_t k32ValueBE{0x67452301}; +const uint16_t k16ValueBE{0x2301}; +#endif + +template +std::vector GenerateAllValuesForType() { + std::vector result; + T next = std::numeric_limits::min(); + while (true) { + result.push_back(next); + if (next == std::numeric_limits::max()) { + return result; + } + ++next; + } +} + +template +std::vector GenerateRandomIntegers(size_t numValuesToTest) { + std::vector result; + std::mt19937_64 rng(kRandomSeed); + for (size_t i = 0; i < numValuesToTest; ++i) { + result.push_back(rng()); + } + return result; +} + +void ManualByteSwap(char* bytes, int length) { + if (length == 1) + return; + + EXPECT_EQ(0, length % 2); + for (int i = 0; i < length / 2; ++i) { + int j = (length - 1) - i; + using std::swap; + swap(bytes[i], bytes[j]); + } +} + +template +inline T UnalignedLoad(const char* p) { + static_assert( + sizeof(T) == 1 || sizeof(T) == 2 || sizeof(T) == 4 || sizeof(T) == 8, + "Unexpected type size"); + + switch (sizeof(T)) { + case 1: return *reinterpret_cast(p); + case 2: + return ABSL_INTERNAL_UNALIGNED_LOAD16(p); + case 4: + return ABSL_INTERNAL_UNALIGNED_LOAD32(p); + case 8: + return ABSL_INTERNAL_UNALIGNED_LOAD64(p); + default: + // Suppresses invalid "not all control paths return a value" on MSVC + return {}; + } +} + +template +static void GBSwapHelper(const std::vector& host_values_to_test, + const ByteSwapper& byte_swapper) { + // Test byte_swapper against a manual byte swap. + for (typename std::vector::const_iterator it = host_values_to_test.begin(); + it != host_values_to_test.end(); ++it) { + T host_value = *it; + + char actual_value[sizeof(host_value)]; + memcpy(actual_value, &host_value, sizeof(host_value)); + byte_swapper(actual_value); + + char expected_value[sizeof(host_value)]; + memcpy(expected_value, &host_value, sizeof(host_value)); + ManualByteSwap(expected_value, sizeof(host_value)); + + ASSERT_EQ(0, memcmp(actual_value, expected_value, sizeof(host_value))) + << "Swap output for 0x" << std::hex << host_value << " does not match. " + << "Expected: 0x" << UnalignedLoad(expected_value) << "; " + << "actual: 0x" << UnalignedLoad(actual_value); + } +} + +void Swap16(char* bytes) { + ABSL_INTERNAL_UNALIGNED_STORE16( + bytes, gbswap_16(ABSL_INTERNAL_UNALIGNED_LOAD16(bytes))); +} + +void Swap32(char* bytes) { + ABSL_INTERNAL_UNALIGNED_STORE32( + bytes, gbswap_32(ABSL_INTERNAL_UNALIGNED_LOAD32(bytes))); +} + +void Swap64(char* bytes) { + ABSL_INTERNAL_UNALIGNED_STORE64( + bytes, gbswap_64(ABSL_INTERNAL_UNALIGNED_LOAD64(bytes))); +} + +TEST(EndianessTest, Uint16) { + GBSwapHelper(GenerateAllValuesForType(), &Swap16); +} + +TEST(EndianessTest, Uint32) { + GBSwapHelper(GenerateRandomIntegers(kNumValuesToTest), &Swap32); +} + +TEST(EndianessTest, Uint64) { + GBSwapHelper(GenerateRandomIntegers(kNumValuesToTest), &Swap64); +} + +TEST(EndianessTest, ghtonll_gntohll) { + // Test that absl::ghtonl compiles correctly + uint32_t test = 0x01234567; + EXPECT_EQ(absl::gntohl(absl::ghtonl(test)), test); + + uint64_t comp = absl::ghtonll(kInitialNumber); + EXPECT_EQ(comp, kInitialInNetworkOrder); + comp = absl::gntohll(kInitialInNetworkOrder); + EXPECT_EQ(comp, kInitialNumber); + + // Test that htonll and ntohll are each others' inverse functions on a + // somewhat assorted batch of numbers. 37 is chosen to not be anything + // particularly nice base 2. + uint64_t value = 1; + for (int i = 0; i < 100; ++i) { + comp = absl::ghtonll(absl::gntohll(value)); + EXPECT_EQ(value, comp); + comp = absl::gntohll(absl::ghtonll(value)); + EXPECT_EQ(value, comp); + value *= 37; + } +} + +TEST(EndianessTest, little_endian) { + // Check little_endian uint16_t. + uint64_t comp = little_endian::FromHost16(k16Value); + EXPECT_EQ(comp, k16ValueLE); + comp = little_endian::ToHost16(k16ValueLE); + EXPECT_EQ(comp, k16Value); + + // Check little_endian uint32_t. + comp = little_endian::FromHost32(k32Value); + EXPECT_EQ(comp, k32ValueLE); + comp = little_endian::ToHost32(k32ValueLE); + EXPECT_EQ(comp, k32Value); + + // Check little_endian uint64_t. + comp = little_endian::FromHost64(k64Value); + EXPECT_EQ(comp, k64ValueLE); + comp = little_endian::ToHost64(k64ValueLE); + EXPECT_EQ(comp, k64Value); + + // Check little-endian Load and store functions. + uint16_t u16Buf; + uint32_t u32Buf; + uint64_t u64Buf; + + little_endian::Store16(&u16Buf, k16Value); + EXPECT_EQ(u16Buf, k16ValueLE); + comp = little_endian::Load16(&u16Buf); + EXPECT_EQ(comp, k16Value); + + little_endian::Store32(&u32Buf, k32Value); + EXPECT_EQ(u32Buf, k32ValueLE); + comp = little_endian::Load32(&u32Buf); + EXPECT_EQ(comp, k32Value); + + little_endian::Store64(&u64Buf, k64Value); + EXPECT_EQ(u64Buf, k64ValueLE); + comp = little_endian::Load64(&u64Buf); + EXPECT_EQ(comp, k64Value); +} + +TEST(EndianessTest, big_endian) { + // Check big-endian Load and store functions. + uint16_t u16Buf; + uint32_t u32Buf; + uint64_t u64Buf; + + unsigned char buffer[10]; + big_endian::Store16(&u16Buf, k16Value); + EXPECT_EQ(u16Buf, k16ValueBE); + uint64_t comp = big_endian::Load16(&u16Buf); + EXPECT_EQ(comp, k16Value); + + big_endian::Store32(&u32Buf, k32Value); + EXPECT_EQ(u32Buf, k32ValueBE); + comp = big_endian::Load32(&u32Buf); + EXPECT_EQ(comp, k32Value); + + big_endian::Store64(&u64Buf, k64Value); + EXPECT_EQ(u64Buf, k64ValueBE); + comp = big_endian::Load64(&u64Buf); + EXPECT_EQ(comp, k64Value); + + big_endian::Store16(buffer + 1, k16Value); + EXPECT_EQ(u16Buf, k16ValueBE); + comp = big_endian::Load16(buffer + 1); + EXPECT_EQ(comp, k16Value); + + big_endian::Store32(buffer + 1, k32Value); + EXPECT_EQ(u32Buf, k32ValueBE); + comp = big_endian::Load32(buffer + 1); + EXPECT_EQ(comp, k32Value); + + big_endian::Store64(buffer + 1, k64Value); + EXPECT_EQ(u64Buf, k64ValueBE); + comp = big_endian::Load64(buffer + 1); + EXPECT_EQ(comp, k64Value); +} + +} // namespace +} // namespace absl diff --git a/Firestore/third_party/abseil-cpp/absl/base/internal/unaligned_access.h b/Firestore/third_party/abseil-cpp/absl/base/internal/unaligned_access.h new file mode 100644 index 0000000..ea30829 --- /dev/null +++ b/Firestore/third_party/abseil-cpp/absl/base/internal/unaligned_access.h @@ -0,0 +1,256 @@ +// +// Copyright 2017 The Abseil Authors. +// +// 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. +// + +#ifndef ABSL_BASE_INTERNAL_UNALIGNED_ACCESS_H_ +#define ABSL_BASE_INTERNAL_UNALIGNED_ACCESS_H_ + +#include +#include + +#include "absl/base/attributes.h" + +// unaligned APIs + +// Portable handling of unaligned loads, stores, and copies. +// On some platforms, like ARM, the copy functions can be more efficient +// then a load and a store. +// +// It is possible to implement all of these these using constant-length memcpy +// calls, which is portable and will usually be inlined into simple loads and +// stores if the architecture supports it. However, such inlining usually +// happens in a pass that's quite late in compilation, which means the resulting +// loads and stores cannot participate in many other optimizations, leading to +// overall worse code. + +// The unaligned API is C++ only. The declarations use C++ features +// (namespaces, inline) which are absent or incompatible in C. +#if defined(__cplusplus) + +#if defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER) ||\ + defined(MEMORY_SANITIZER) +// Consider we have an unaligned load/store of 4 bytes from address 0x...05. +// AddressSanitizer will treat it as a 3-byte access to the range 05:07 and +// will miss a bug if 08 is the first unaddressable byte. +// ThreadSanitizer will also treat this as a 3-byte access to 05:07 and will +// miss a race between this access and some other accesses to 08. +// MemorySanitizer will correctly propagate the shadow on unaligned stores +// and correctly report bugs on unaligned loads, but it may not properly +// update and report the origin of the uninitialized memory. +// For all three tools, replacing an unaligned access with a tool-specific +// callback solves the problem. + +// Make sure uint16_t/uint32_t/uint64_t are defined. +#include + +extern "C" { +uint16_t __sanitizer_unaligned_load16(const void *p); +uint32_t __sanitizer_unaligned_load32(const void *p); +uint64_t __sanitizer_unaligned_load64(const void *p); +void __sanitizer_unaligned_store16(void *p, uint16_t v); +void __sanitizer_unaligned_store32(void *p, uint32_t v); +void __sanitizer_unaligned_store64(void *p, uint64_t v); +} // extern "C" + +namespace absl { + +inline uint16_t UnalignedLoad16(const void *p) { + return __sanitizer_unaligned_load16(p); +} + +inline uint32_t UnalignedLoad32(const void *p) { + return __sanitizer_unaligned_load32(p); +} + +inline uint64_t UnalignedLoad64(const void *p) { + return __sanitizer_unaligned_load64(p); +} + +inline void UnalignedStore16(void *p, uint16_t v) { + __sanitizer_unaligned_store16(p, v); +} + +inline void UnalignedStore32(void *p, uint32_t v) { + __sanitizer_unaligned_store32(p, v); +} + +inline void UnalignedStore64(void *p, uint64_t v) { + __sanitizer_unaligned_store64(p, v); +} + +} // namespace absl + +#define ABSL_INTERNAL_UNALIGNED_LOAD16(_p) (absl::UnalignedLoad16(_p)) +#define ABSL_INTERNAL_UNALIGNED_LOAD32(_p) (absl::UnalignedLoad32(_p)) +#define ABSL_INTERNAL_UNALIGNED_LOAD64(_p) (absl::UnalignedLoad64(_p)) + +#define ABSL_INTERNAL_UNALIGNED_STORE16(_p, _val) \ + (absl::UnalignedStore16(_p, _val)) +#define ABSL_INTERNAL_UNALIGNED_STORE32(_p, _val) \ + (absl::UnalignedStore32(_p, _val)) +#define ABSL_INTERNAL_UNALIGNED_STORE64(_p, _val) \ + (absl::UnalignedStore64(_p, _val)) + +#elif defined(__x86_64__) || defined(_M_X64) || defined(__i386) || \ + defined(_M_IX86) || defined(__ppc__) || defined(__PPC__) || \ + defined(__ppc64__) || defined(__PPC64__) + +// x86 and x86-64 can perform unaligned loads/stores directly; +// modern PowerPC hardware can also do unaligned integer loads and stores; +// but note: the FPU still sends unaligned loads and stores to a trap handler! + +#define ABSL_INTERNAL_UNALIGNED_LOAD16(_p) \ + (*reinterpret_cast(_p)) +#define ABSL_INTERNAL_UNALIGNED_LOAD32(_p) \ + (*reinterpret_cast(_p)) +#define ABSL_INTERNAL_UNALIGNED_LOAD64(_p) \ + (*reinterpret_cast(_p)) + +#define ABSL_INTERNAL_UNALIGNED_STORE16(_p, _val) \ + (*reinterpret_cast(_p) = (_val)) +#define ABSL_INTERNAL_UNALIGNED_STORE32(_p, _val) \ + (*reinterpret_cast(_p) = (_val)) +#define ABSL_INTERNAL_UNALIGNED_STORE64(_p, _val) \ + (*reinterpret_cast(_p) = (_val)) + +#elif defined(__arm__) && \ + !defined(__ARM_ARCH_5__) && \ + !defined(__ARM_ARCH_5T__) && \ + !defined(__ARM_ARCH_5TE__) && \ + !defined(__ARM_ARCH_5TEJ__) && \ + !defined(__ARM_ARCH_6__) && \ + !defined(__ARM_ARCH_6J__) && \ + !defined(__ARM_ARCH_6K__) && \ + !defined(__ARM_ARCH_6Z__) && \ + !defined(__ARM_ARCH_6ZK__) && \ + !defined(__ARM_ARCH_6T2__) + + +// ARMv7 and newer support native unaligned accesses, but only of 16-bit +// and 32-bit values (not 64-bit); older versions either raise a fatal signal, +// do an unaligned read and rotate the words around a bit, or do the reads very +// slowly (trip through kernel mode). There's no simple #define that says just +// “ARMv7 or higher”, so we have to filter away all ARMv5 and ARMv6 +// sub-architectures. Newer gcc (>= 4.6) set an __ARM_FEATURE_ALIGNED #define, +// so in time, maybe we can move on to that. +// +// This is a mess, but there's not much we can do about it. +// +// To further complicate matters, only LDR instructions (single reads) are +// allowed to be unaligned, not LDRD (two reads) or LDM (many reads). Unless we +// explicitly tell the compiler that these accesses can be unaligned, it can and +// will combine accesses. On armcc, the way to signal this is done by accessing +// through the type (uint32_t __packed *), but GCC has no such attribute +// (it ignores __attribute__((packed)) on individual variables). However, +// we can tell it that a _struct_ is unaligned, which has the same effect, +// so we do that. + +namespace absl { +namespace internal { + +struct Unaligned16Struct { + uint16_t value; + uint8_t dummy; // To make the size non-power-of-two. +} ABSL_ATTRIBUTE_PACKED; + +struct Unaligned32Struct { + uint32_t value; + uint8_t dummy; // To make the size non-power-of-two. +} ABSL_ATTRIBUTE_PACKED; + +} // namespace internal +} // namespace absl + +#define ABSL_INTERNAL_UNALIGNED_LOAD16(_p) \ + ((reinterpret_cast(_p))->value) +#define ABSL_INTERNAL_UNALIGNED_LOAD32(_p) \ + ((reinterpret_cast(_p))->value) + +#define ABSL_INTERNAL_UNALIGNED_STORE16(_p, _val) \ + ((reinterpret_cast< ::absl::internal::Unaligned16Struct *>(_p))->value = \ + (_val)) +#define ABSL_INTERNAL_UNALIGNED_STORE32(_p, _val) \ + ((reinterpret_cast< ::absl::internal::Unaligned32Struct *>(_p))->value = \ + (_val)) + +namespace absl { + +inline uint64_t UnalignedLoad64(const void *p) { + uint64_t t; + memcpy(&t, p, sizeof t); + return t; +} + +inline void UnalignedStore64(void *p, uint64_t v) { memcpy(p, &v, sizeof v); } + +} // namespace absl + +#define ABSL_INTERNAL_UNALIGNED_LOAD64(_p) (absl::UnalignedLoad64(_p)) +#define ABSL_INTERNAL_UNALIGNED_STORE64(_p, _val) \ + (absl::UnalignedStore64(_p, _val)) + +#else + +// ABSL_INTERNAL_NEED_ALIGNED_LOADS is defined when the underlying platform +// doesn't support unaligned access. +#define ABSL_INTERNAL_NEED_ALIGNED_LOADS + +// These functions are provided for architectures that don't support +// unaligned loads and stores. + +namespace absl { + +inline uint16_t UnalignedLoad16(const void *p) { + uint16_t t; + memcpy(&t, p, sizeof t); + return t; +} + +inline uint32_t UnalignedLoad32(const void *p) { + uint32_t t; + memcpy(&t, p, sizeof t); + return t; +} + +inline uint64_t UnalignedLoad64(const void *p) { + uint64_t t; + memcpy(&t, p, sizeof t); + return t; +} + +inline void UnalignedStore16(void *p, uint16_t v) { memcpy(p, &v, sizeof v); } + +inline void UnalignedStore32(void *p, uint32_t v) { memcpy(p, &v, sizeof v); } + +inline void UnalignedStore64(void *p, uint64_t v) { memcpy(p, &v, sizeof v); } + +} // namespace absl + +#define ABSL_INTERNAL_UNALIGNED_LOAD16(_p) (absl::UnalignedLoad16(_p)) +#define ABSL_INTERNAL_UNALIGNED_LOAD32(_p) (absl::UnalignedLoad32(_p)) +#define ABSL_INTERNAL_UNALIGNED_LOAD64(_p) (absl::UnalignedLoad64(_p)) + +#define ABSL_INTERNAL_UNALIGNED_STORE16(_p, _val) \ + (absl::UnalignedStore16(_p, _val)) +#define ABSL_INTERNAL_UNALIGNED_STORE32(_p, _val) \ + (absl::UnalignedStore32(_p, _val)) +#define ABSL_INTERNAL_UNALIGNED_STORE64(_p, _val) \ + (absl::UnalignedStore64(_p, _val)) + +#endif + +#endif // defined(__cplusplus), end of unaligned API + +#endif // ABSL_BASE_INTERNAL_UNALIGNED_ACCESS_H_ -- cgit v1.2.3 From 3bc5488644b8a5042079ffcf91e852bedc24d572 Mon Sep 17 00:00:00 2001 From: Marek Gilbert Date: Sat, 9 Dec 2017 17:35:52 -0800 Subject: Add absl/base/internal/endian.h back into the build --- Firestore/third_party/abseil-cpp/absl/base/CMakeLists.txt | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Firestore/third_party/abseil-cpp/absl/base/CMakeLists.txt b/Firestore/third_party/abseil-cpp/absl/base/CMakeLists.txt index a6cd1ff..08659c4 100644 --- a/Firestore/third_party/abseil-cpp/absl/base/CMakeLists.txt +++ b/Firestore/third_party/abseil-cpp/absl/base/CMakeLists.txt @@ -27,9 +27,11 @@ list(APPEND BASE_PUBLIC_HEADERS list(APPEND BASE_INTERNAL_HEADERS "internal/atomic_hook.h" + "internal/endian.h" "internal/log_severity.h" "internal/raw_logging.h" "internal/throw_delegate.h" + "internal/unaligned_access.h" ) @@ -84,6 +86,17 @@ absl_library( ## TESTS # +# test endian_test +set(ENDIAN_TEST_SRC "internal/endian_test.cc") + +absl_test( + TARGET + endian_test + SOURCES + ${ENDIAN_TEST_SRC} +) + + # test config_test set(CONFIG_TEST_SRC "config_test.cc") set(CONFIG_TEST_PUBLIC_LIBRARIES absl::base) -- cgit v1.2.3 From 03ab86499febe481177f3d11f6ffc983843f97be Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Sun, 10 Dec 2017 22:58:23 -0800 Subject: Running scripts/style.sh --- Example/Core/Tests/FIRAppTest.m | 6 +++--- Example/Core/Tests/FIRLoggerTest.m | 2 +- Example/Core/Tests/FIROptionsTest.m | 2 +- Firebase/Core/FIRApp.m | 3 ++- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/Example/Core/Tests/FIRAppTest.m b/Example/Core/Tests/FIRAppTest.m index ac7985a..8466488 100644 --- a/Example/Core/Tests/FIRAppTest.m +++ b/Example/Core/Tests/FIRAppTest.m @@ -95,7 +95,7 @@ NSString *const kFIRTestAppName2 = @"test-app-name-2"; } - (void)testConfigureWithOptions { - // nil options +// nil options #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wnonnull" XCTAssertThrows([FIRApp configureWithOptions:nil]); @@ -119,7 +119,7 @@ NSString *const kFIRTestAppName2 = @"test-app-name-2"; } - (void)testConfigureWithCustomizedOptions { - // valid customized options +// valid customized options #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wnonnull" #pragma clang diagnostic ignored "-Wdeprecated-declarations" @@ -194,7 +194,7 @@ NSString *const kFIRTestAppName2 = @"test-app-name-2"; XCTAssertTrue([FIRApp allApps].count == 1); self.app = [FIRApp appNamed:kFIRTestAppName1]; - // Configure a different app with valid customized options +// Configure a different app with valid customized options #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wnonnull" #pragma clang diagnostic ignored "-Wdeprecated-declarations" diff --git a/Example/Core/Tests/FIRLoggerTest.m b/Example/Core/Tests/FIRLoggerTest.m index 0894fd6..70b688a 100644 --- a/Example/Core/Tests/FIRLoggerTest.m +++ b/Example/Core/Tests/FIRLoggerTest.m @@ -148,7 +148,7 @@ static NSString *const kMessageCode = @"I-COR000001"; // Lowercase should fail. XCTAssertThrows(FIRLogError(kFIRLoggerCore, @"I-app000001", @"Message.")); - // nil or empty message code should fail. +// nil or empty message code should fail. #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wnonnull" XCTAssertThrows(FIRLogError(kFIRLoggerCore, nil, @"Message.")); diff --git a/Example/Core/Tests/FIROptionsTest.m b/Example/Core/Tests/FIROptionsTest.m index a1e5fae..2ebad15 100644 --- a/Example/Core/Tests/FIROptionsTest.m +++ b/Example/Core/Tests/FIROptionsTest.m @@ -111,7 +111,7 @@ extern NSString *const kFIRLibraryVersionID; XCTAssertEqualObjects(options2.deepLinkURLScheme, kDeepLinkURLScheme); XCTAssertFalse(options.usingOptionsFromDefaultPlist); - // nil GoogleAppID should throw an exception +// nil GoogleAppID should throw an exception #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wnonnull" #pragma clang diagnostic ignored "-Wdeprecated-declarations" diff --git a/Firebase/Core/FIRApp.m b/Firebase/Core/FIRApp.m index 242fd79..800d180 100644 --- a/Firebase/Core/FIRApp.m +++ b/Firebase/Core/FIRApp.m @@ -142,7 +142,8 @@ static FIRApp *sDefaultApp; NSString *minVersion = info[@"MinimumOSVersion"]; if ([minVersion hasPrefix:@"7."]) { - FIRLogNotice(kFIRLoggerCore, @"I-COR000026", @"Support for iOS 7 is deprecated and will " + FIRLogNotice(kFIRLoggerCore, @"I-COR000026", + @"Support for iOS 7 is deprecated and will " @"stop working in the future. Please upgrade your app to target iOS 8 or " @"above."); } -- cgit v1.2.3 From e23236bd389d73beccb3a2e5b823873ba25b1b62 Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Sun, 10 Dec 2017 23:07:53 -0800 Subject: Running scripts/style.sh --- Firestore/Example/Tests/API/FIRQueryTests.m | 37 +++++++++++---------- Firestore/Source/API/FIRQuery.m | 50 ++++++++++++++++------------- 2 files changed, 45 insertions(+), 42 deletions(-) diff --git a/Firestore/Example/Tests/API/FIRQueryTests.m b/Firestore/Example/Tests/API/FIRQueryTests.m index bd0d860..366a6bf 100644 --- a/Firestore/Example/Tests/API/FIRQueryTests.m +++ b/Firestore/Example/Tests/API/FIRQueryTests.m @@ -42,26 +42,25 @@ NS_ASSUME_NONNULL_BEGIN workerDispatchQueue:nil firebaseApp:nil]; FSTResourcePath *path = [FSTResourcePath pathWithString:@"foo"]; - FIRQuery *query = [FIRQuery referenceWithQuery:[FSTQuery queryWithPath:path] - firestore:firestore]; + FIRQuery *query = [FIRQuery referenceWithQuery:[FSTQuery queryWithPath:path] firestore:firestore]; FIRQuery *query1 = [query queryWhereField:@"f" isLessThanOrEqualTo:@1]; - FIRQuery *query2 = [query queryFilteredUsingPredicate: - [NSPredicate predicateWithFormat:@"f<=1"]]; - FIRQuery *query3 = [[query queryWhereField:@"f1" isLessThan:@2] - queryWhereField:@"f2" isEqualTo:@3]; - FIRQuery *query4 = [query queryFilteredUsingPredicate: - [NSPredicate predicateWithFormat:@"f1<2 && f2==3"]]; - FIRQuery *query5 = [[[[[query queryWhereField:@"f1" isLessThan:@2] - queryWhereField:@"f2" isEqualTo:@3] - queryWhereField:@"f1" isLessThanOrEqualTo:@"four"] - queryWhereField:@"f1" isGreaterThanOrEqualTo:@"five"] - queryWhereField:@"f1" isGreaterThan:@6]; - FIRQuery *query6 = [query queryFilteredUsingPredicate: - [NSPredicate predicateWithFormat: - @"f1<2 && f2==3 && f1<='four' && f1>='five' && f1>6"]]; - FIRQuery *query7 = [query queryFilteredUsingPredicate: - [NSPredicate predicateWithFormat: - @"2>f1 && 3==f2 && 'four'>=f1 && 'five'<=f1 && 6='five' && f1>6"]]; + FIRQuery *query7 = [query + queryFilteredUsingPredicate: + [NSPredicate predicateWithFormat:@"2>f1 && 3==f2 && 'four'>=f1 && 'five'<=f1 && 6 Date: Mon, 11 Dec 2017 12:25:49 -0500 Subject: Modified FirebaseAppStoreURLCheckEnabled Key. (#554) --- Firebase/Core/third_party/FIRAppEnvironmentUtil.m | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Firebase/Core/third_party/FIRAppEnvironmentUtil.m b/Firebase/Core/third_party/FIRAppEnvironmentUtil.m index 337f082..fe4e23d 100644 --- a/Firebase/Core/third_party/FIRAppEnvironmentUtil.m +++ b/Firebase/Core/third_party/FIRAppEnvironmentUtil.m @@ -36,9 +36,11 @@ struct encryption_info_command { @implementation FIRAppEnvironmentUtil -/// A key for the Info.plist to enable or disable checking if the App Store is running in a sandbox, -/// which would be true while running on TestFlight. -static NSString *const kFIRAppStoreSandboxCheckEnabledKey = @"FirebaseAppStoreSandboxCheckEnabled"; +/// A key for the Info.plist to enable or disable checking if the App Store is running in a sandbox. +/// This will affect your data integrity when using Firebase Analytics, as it will disable some +/// necessary checks. +static NSString *const kFIRAppStoreReceiptURLCheckEnabledKey = + @"FirebaseAppStoreReceiptURLCheckEnabled"; /// The file name of the sandbox receipt. This is available on iOS >= 8.0 static NSString *const kFIRAIdentitySandboxReceiptFileName = @"sandboxReceipt"; @@ -159,7 +161,7 @@ static BOOL isAppEncrypted() { // Since checking the App Store's receipt URL can be memory intensive, check the option in the // Info.plist if developers opted out of this check. id enableSandboxCheck = - [[NSBundle mainBundle] objectForInfoDictionaryKey:kFIRAppStoreSandboxCheckEnabledKey]; + [[NSBundle mainBundle] objectForInfoDictionaryKey:kFIRAppStoreReceiptURLCheckEnabledKey]; if (enableSandboxCheck && [enableSandboxCheck isKindOfClass:[NSNumber class]] && ![enableSandboxCheck boolValue]) { -- cgit v1.2.3 From 54ba423c87d6e0a409e4fa3dc95cd81ca16b97f7 Mon Sep 17 00:00:00 2001 From: zxu Date: Mon, 11 Dec 2017 15:37:01 -0500 Subject: Revisit commit method in FIRWriteBatch (#541) * revisit FIRWriteBatch commit * make commitWithCompletion completion nullable; * add commit; * add unit test; * add swift build test for commit; * update CHANGELOG. --- Firestore/CHANGELOG.md | 1 + Firestore/Example/SwiftBuildTest/main.swift | 26 ++++++++++++++++++++++ .../Tests/Integration/API/FIRWriteBatchTests.m | 17 ++++++++++++++ Firestore/Source/API/FIRWriteBatch.m | 6 ++++- Firestore/Source/Public/FIRWriteBatch.h | 7 +++++- 5 files changed, 55 insertions(+), 2 deletions(-) diff --git a/Firestore/CHANGELOG.md b/Firestore/CHANGELOG.md index 32cbbfc..1a8eb07 100644 --- a/Firestore/CHANGELOG.md +++ b/Firestore/CHANGELOG.md @@ -2,6 +2,7 @@ - [changed] Firestore no longer has a direct dependency on FirebaseAuth. - [changed] Removed the includeMetadataChanges property in FIRDocumentListenOptions to avoid confusion with the factory method of the same name. +- [changed] Added a commit method that takes no completion handler to FIRWriteBatch. - [fixed] Fixed a crash when using path names with international characters with persistence enabled. diff --git a/Firestore/Example/SwiftBuildTest/main.swift b/Firestore/Example/SwiftBuildTest/main.swift index bea8b56..475c1b2 100644 --- a/Firestore/Example/SwiftBuildTest/main.swift +++ b/Firestore/Example/SwiftBuildTest/main.swift @@ -27,6 +27,8 @@ func main() { writeDocument(at: documentRef); + writeDocuments(at: documentRef, database: db); + addDocument(to: collectionRef); readDocument(at: documentRef); @@ -129,6 +131,30 @@ func writeDocument(at docRef: DocumentReference) { } } +func writeDocuments(at docRef: DocumentReference, database db: Firestore) { + var batch: WriteBatch; + + batch = db.batch(); + batch.setData(["a" : "b"], forDocument:docRef); + batch.setData(["c" : "d"], forDocument:docRef); + // commit without completion callback. + batch.commit(); + print("Batch write without completion complete!"); + + batch = db.batch(); + batch.setData(["a" : "b"], forDocument:docRef); + batch.setData(["c" : "d"], forDocument:docRef); + // commit with completion callback via trailing closure syntax. + batch.commit() { error in + if let error = error { + print("Uh oh! \(error)"); + return; + } + print("Batch write callback complete!"); + } + print("Batch write with completion complete!"); +} + func addDocument(to collectionRef: CollectionReference) { collectionRef.addDocument(data: ["foo": 42]); diff --git a/Firestore/Example/Tests/Integration/API/FIRWriteBatchTests.m b/Firestore/Example/Tests/Integration/API/FIRWriteBatchTests.m index 562c29f..23ae7bc 100644 --- a/Firestore/Example/Tests/Integration/API/FIRWriteBatchTests.m +++ b/Firestore/Example/Tests/Integration/API/FIRWriteBatchTests.m @@ -35,6 +35,23 @@ [self awaitExpectations]; } +- (void)testCommitWithoutCompletionHandler { + FIRDocumentReference *doc = [self documentRef]; + FIRWriteBatch *batch1 = [doc.firestore batch]; + [batch1 setData:@{@"aa" : @"bb"} forDocument:doc]; + [batch1 commitWithCompletion:nil]; + FIRDocumentSnapshot *snapshot1 = [self readDocumentForRef:doc]; + XCTAssertTrue(snapshot1.exists); + XCTAssertEqualObjects(snapshot1.data, @{@"aa" : @"bb"}); + + FIRWriteBatch *batch2 = [doc.firestore batch]; + [batch2 setData:@{@"cc" : @"dd"} forDocument:doc]; + [batch2 commit]; + FIRDocumentSnapshot *snapshot2 = [self readDocumentForRef:doc]; + XCTAssertTrue(snapshot2.exists); + XCTAssertEqualObjects(snapshot2.data, @{@"cc" : @"dd"}); +} + - (void)testSetDocuments { FIRDocumentReference *doc = [self documentRef]; XCTestExpectation *batchExpectation = [self expectationWithDescription:@"batch written"]; diff --git a/Firestore/Source/API/FIRWriteBatch.m b/Firestore/Source/API/FIRWriteBatch.m index b918a9a..b1cfa09 100644 --- a/Firestore/Source/API/FIRWriteBatch.m +++ b/Firestore/Source/API/FIRWriteBatch.m @@ -93,7 +93,11 @@ NS_ASSUME_NONNULL_BEGIN return self; } -- (void)commitWithCompletion:(void (^)(NSError *_Nullable error))completion { +- (void)commit { + [self commitWithCompletion:nil]; +} + +- (void)commitWithCompletion:(nullable void (^)(NSError *_Nullable error))completion { [self verifyNotCommitted]; self.committed = TRUE; [self.firestore.client writeMutations:self.mutations completion:completion]; diff --git a/Firestore/Source/Public/FIRWriteBatch.h b/Firestore/Source/Public/FIRWriteBatch.h index 5f0034c..8ff1bec 100644 --- a/Firestore/Source/Public/FIRWriteBatch.h +++ b/Firestore/Source/Public/FIRWriteBatch.h @@ -92,6 +92,11 @@ NS_SWIFT_NAME(WriteBatch) - (FIRWriteBatch *)deleteDocument:(FIRDocumentReference *)document NS_SWIFT_NAME(deleteDocument(_:)); +/** + * Commits all of the writes in this write batch as a single atomic unit. + */ +- (void)commit; + /** * Commits all of the writes in this write batch as a single atomic unit. * @@ -101,7 +106,7 @@ NS_SWIFT_NAME(WriteBatch) * completion handler will not be called when the device is offline, though local * changes will be visible immediately. */ -- (void)commitWithCompletion:(void (^)(NSError *_Nullable error))completion; +- (void)commitWithCompletion:(nullable void (^)(NSError *_Nullable error))completion; @end -- cgit v1.2.3 From 43774fec33adda895609ccd61d7c00e71d2396bb Mon Sep 17 00:00:00 2001 From: Gil Date: Mon, 11 Dec 2017 14:14:05 -0800 Subject: Update CHANGELOG for Firestore v0.9.4 (#556) --- Firestore/CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Firestore/CHANGELOG.md b/Firestore/CHANGELOG.md index 0c5bcdc..ae9f994 100644 --- a/Firestore/CHANGELOG.md +++ b/Firestore/CHANGELOG.md @@ -1,8 +1,9 @@ # Unreleased + +# v0.9.4 - [changed] Firestore no longer has a direct dependency on FirebaseAuth. - [fixed] Fixed a crash when using path names with international characters with persistence enabled. - - [fixed] Addressed race condition during the teardown of idle streams (#490). # v0.9.3 -- cgit v1.2.3