aboutsummaryrefslogtreecommitdiffhomepage
path: root/Firestore/core/include
diff options
context:
space:
mode:
authorGravatar Konstantin Varlamov <var-const@users.noreply.github.com>2018-03-27 11:50:03 -0400
committerGravatar GitHub <noreply@github.com>2018-03-27 11:50:03 -0400
commit22c226af3f5570514d3d13d82a399577ecd7d280 (patch)
treefc8f3e1ca146297f2993f8391ed3dab9e0f2c153 /Firestore/core/include
parent13aa61633f5a98c8dd0a508e5a404017bc79370e (diff)
C++ migration: make Timestamp class a part of public API (#944)
* move Timestamp from model/ to the root directory; * move Timestamp to top-level firebase namespace and update all references; * add conversions to and from native date types; * add a specialization of std::hash; * add comments to public member functions; * rename nanos -> nanoseconds; * add public headers, including Timestamp, to CMake; * increase test coverage.
Diffstat (limited to 'Firestore/core/include')
-rw-r--r--Firestore/core/include/firebase/firestore/CMakeLists.txt25
-rw-r--r--Firestore/core/include/firebase/firestore/timestamp.h221
2 files changed, 246 insertions, 0 deletions
diff --git a/Firestore/core/include/firebase/firestore/CMakeLists.txt b/Firestore/core/include/firebase/firestore/CMakeLists.txt
new file mode 100644
index 0000000..e4e7acd
--- /dev/null
+++ b/Firestore/core/include/firebase/firestore/CMakeLists.txt
@@ -0,0 +1,25 @@
+# Copyright 2018 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.
+
+# Hack to make the headers show up in IDEs
+# (see https://stackoverflow.com/questions/27039019/ and open issue on CMake
+# issue tracker: https://gitlab.kitware.com/cmake/cmake/issues/15234)
+add_custom_target(firebase_firestore_types_ide SOURCES
+ document_reference.h
+ event_listener.h
+ firestore.h
+ firestore_errors.h
+ geo_point.h
+ timestamp.h
+)
diff --git a/Firestore/core/include/firebase/firestore/timestamp.h b/Firestore/core/include/firebase/firestore/timestamp.h
new file mode 100644
index 0000000..096d121
--- /dev/null
+++ b/Firestore/core/include/firebase/firestore/timestamp.h
@@ -0,0 +1,221 @@
+/*
+ * Copyright 2018 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.
+ */
+
+#ifndef FIRESTORE_CORE_INCLUDE_FIREBASE_FIRESTORE_TIMESTAMP_H_
+#define FIRESTORE_CORE_INCLUDE_FIREBASE_FIRESTORE_TIMESTAMP_H_
+
+#include <stdint.h>
+#include <time.h>
+#if !defined(_STLPORT_VERSION)
+#include <chrono> // NOLINT(build/c++11)
+#endif // !defined(_STLPORT_VERSION)
+#include <limits>
+#include <string>
+
+namespace firebase {
+
+/**
+ * A Timestamp represents a point in time independent of any time zone or
+ * calendar, represented as seconds and fractions of seconds at nanosecond
+ * resolution in UTC Epoch time. It is encoded using the Proleptic Gregorian
+ * Calendar which extends the Gregorian calendar backwards to year one. It is
+ * encoded assuming all minutes are 60 seconds long, i.e. leap seconds are
+ * "smeared" so that no leap second table is needed for interpretation. Range is
+ * from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z.
+ *
+ * @see
+ * https://github.com/google/protobuf/blob/master/src/google/protobuf/timestamp.proto
+ */
+class Timestamp {
+ public:
+ /**
+ * Creates a new timestamp representing the epoch (with seconds and
+ * nanoseconds set to 0).
+ */
+ Timestamp();
+
+ /**
+ * Creates a new timestamp.
+ *
+ * @param seconds The number of seconds of UTC time since Unix epoch
+ * 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to
+ * 9999-12-31T23:59:59Z inclusive; otherwise, assertion failure will be
+ * triggered.
+ * @param nanoseconds The non-negative fractions of a second at nanosecond
+ * resolution. Negative second values with fractions must still have
+ * non-negative nanoseconds values that count forward in time. Must be
+ * from 0 to 999,999,999 inclusive; otherwise, assertion failure will be
+ * triggered.
+ */
+ Timestamp(int64_t seconds, int32_t nanoseconds);
+
+ /**
+ * Creates a new timestamp with the current date.
+ *
+ * The precision is up to nanoseconds, depending on the system clock.
+ *
+ * @return a new timestamp representing the current date.
+ */
+ static Timestamp Now();
+
+ /**
+ * The number of seconds of UTC time since Unix epoch 1970-01-01T00:00:00Z.
+ */
+ int64_t seconds() const {
+ return seconds_;
+ }
+
+ /**
+ * The non-negative fractions of a second at nanosecond resolution. Negative
+ * second values with fractions still have non-negative nanoseconds values
+ * that count forward in time.
+ */
+ int32_t nanoseconds() const {
+ return nanoseconds_;
+ }
+
+ /**
+ * Converts `time_t` to a `Timestamp`.
+ *
+ * @param seconds_since_unix_epoch
+ * @parblock
+ * The number of seconds of UTC time since Unix epoch
+ * 1970-01-01T00:00:00Z. Can be negative to represent dates before the
+ * epoch. Must be from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59Z
+ * inclusive; otherwise, assertion failure will be triggered.
+ *
+ * Note that while the epoch of `time_t` is unspecified, it's usually Unix
+ * epoch. If this assumption is broken, this function will produce
+ * incorrect results.
+ * @endparblock
+ *
+ * @return a new timestamp with the given number of seconds and zero
+ * nanoseconds.
+ */
+ static Timestamp FromTimeT(time_t seconds_since_unix_epoch);
+
+#if !defined(_STLPORT_VERSION)
+ /**
+ * Converts `std::chrono::time_point` to a `Timestamp`.
+ *
+ * @param time_point
+ * @parblock
+ * The time point with system clock's epoch, which is
+ * presumed to be Unix epoch 1970-01-01T00:00:00Z. Can be negative to
+ * represent dates before the epoch. Must be from 0001-01-01T00:00:00Z to
+ * 9999-12-31T23:59:59Z inclusive; otherwise, assertion failure will be
+ * triggered.
+ *
+ * Note that while the epoch of `std::chrono::system_clock` is
+ * unspecified, it's usually Unix epoch. If this assumption is broken,
+ * this constructor will produce incorrect results.
+ * @endparblock
+ */
+ static Timestamp FromTimePoint(
+ std::chrono::time_point<std::chrono::system_clock> time_point);
+
+ /**
+ * Converts this `Timestamp` to a `time_point`.
+ *
+ * Important: if overflow would occur, the returned value will be the maximum
+ * or minimum value that `Duration` can hold. Note in particular that `long
+ * long` is insufficient to hold the full range of `Timestamp` values with
+ * nanosecond precision (which is why `Duration` defaults to `microseconds`).
+ */
+ template <typename Clock = std::chrono::system_clock,
+ typename Duration = std::chrono::microseconds>
+ std::chrono::time_point<Clock, Duration> ToTimePoint() const;
+#endif // !defined(_STLPORT_VERSION)
+
+ /**
+ * Returns a string representation of this `Timestamp` for logging/debugging
+ * purposes.
+ *
+ * Note: the exact string representation is unspecified and subject to change;
+ * don't rely on the format of the string.
+ */
+ std::string ToString() const;
+
+ private:
+ // Checks that the number of seconds is within the supported date range, and
+ // that nanoseconds satisfy 0 <= ns <= 1second.
+ void ValidateBounds() const;
+
+ int64_t seconds_ = 0;
+ int32_t nanoseconds_ = 0;
+};
+
+inline bool operator<(const Timestamp& lhs, const Timestamp& rhs) {
+ return lhs.seconds() < rhs.seconds() ||
+ (lhs.seconds() == rhs.seconds() &&
+ lhs.nanoseconds() < rhs.nanoseconds());
+}
+
+inline bool operator>(const Timestamp& lhs, const Timestamp& rhs) {
+ return rhs < lhs;
+}
+
+inline bool operator>=(const Timestamp& lhs, const Timestamp& rhs) {
+ return !(lhs < rhs);
+}
+
+inline bool operator<=(const Timestamp& lhs, const Timestamp& rhs) {
+ return !(lhs > rhs);
+}
+
+inline bool operator!=(const Timestamp& lhs, const Timestamp& rhs) {
+ return lhs < rhs || lhs > rhs;
+}
+
+inline bool operator==(const Timestamp& lhs, const Timestamp& rhs) {
+ return !(lhs != rhs);
+}
+
+#if !defined(_STLPORT_VERSION)
+template <typename Clock, typename Duration>
+std::chrono::time_point<Clock, Duration> Timestamp::ToTimePoint() const {
+ namespace chr = std::chrono;
+ using TimePoint = chr::time_point<Clock, Duration>;
+
+ // Saturate on overflow
+ const auto max_value = std::numeric_limits<typename Duration::rep>::max();
+ if (seconds_ > 0 && max_value / Duration::period::den <= seconds_) {
+ return TimePoint{Duration(max_value)};
+ }
+ const auto min_value = std::numeric_limits<typename Duration::rep>::min();
+ if (seconds_ < 0 && min_value / Duration::period::den >= seconds_) {
+ return TimePoint{Duration(min_value)};
+ }
+
+ const auto seconds = chr::duration_cast<Duration>(chr::seconds(seconds_));
+ const auto nanoseconds =
+ chr::duration_cast<Duration>(chr::nanoseconds(nanoseconds_));
+ return TimePoint{seconds + nanoseconds};
+}
+#endif // !defined(_STLPORT_VERSION)
+
+} // namespace firebase
+
+namespace std {
+template <>
+struct hash<firebase::Timestamp> {
+ // Note: specialization of `std::hash` is provided for convenience only. The
+ // implementation is subject to change.
+ size_t operator()(const firebase::Timestamp& timestamp) const;
+};
+} // namespace std
+
+#endif // FIRESTORE_CORE_INCLUDE_FIREBASE_FIRESTORE_TIMESTAMP_H_