added iOS source code
[wl-app.git] / iOS / Pods / Realm / include / core / realm / timestamp.hpp
diff --git a/iOS/Pods/Realm/include/core/realm/timestamp.hpp b/iOS/Pods/Realm/include/core/realm/timestamp.hpp
new file mode 100644 (file)
index 0000000..1e847e4
--- /dev/null
@@ -0,0 +1,167 @@
+/*************************************************************************
+ *
+ * Copyright 2016 Realm Inc.
+ *
+ * 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 REALM_TIMESTAMP_HPP
+#define REALM_TIMESTAMP_HPP
+
+#include <cstdint>
+#include <ostream>
+#include <realm/util/assert.hpp>
+#include <realm/null.hpp>
+
+namespace realm {
+
+class Timestamp {
+public:
+    // Construct from the number of seconds and nanoseconds since the UNIX epoch: 00:00:00 UTC on 1 January 1970
+    //
+    // To split a native nanosecond representation, only division and modulo are necessary:
+    //
+    //     s = native_nano / nanoseconds_per_second
+    //     n = native_nano % nanoseconds_per_second
+    //     Timestamp ts(s, n);
+    //
+    // To convert back into native nanosecond representation, simple multiply and add:
+    //
+    //     native_nano = ts.s * nanoseconds_per_second + ts.n
+    //
+    // Specifically this allows the nanosecond part to become negative (only) for Timestamps before the UNIX epoch.
+    // Usually this will not need special attention, but for reference, valid Timestamps will have one of the
+    // following sign combinations:
+    //
+    //     s | n
+    //     -----
+    //     + | +
+    //     + | 0
+    //     0 | +
+    //     0 | 0
+    //     0 | -
+    //     - | 0
+    //     - | -
+    //
+    // Examples:
+    //     The UNIX epoch is constructed by Timestamp(0, 0)
+    //     Relative times are constructed as follows:
+    //       +1 second is constructed by Timestamp(1, 0)
+    //       +1 nanosecond is constructed by Timestamp(0, 1)
+    //       +1.1 seconds (1100 milliseconds after the epoch) is constructed by Timestamp(1, 100000000)
+    //       -1.1 seconds (1100 milliseconds before the epoch) is constructed by Timestamp(-1, -100000000)
+    //
+    Timestamp(int64_t seconds, int32_t nanoseconds)
+        : m_seconds(seconds)
+        , m_nanoseconds(nanoseconds)
+        , m_is_null(false)
+    {
+        REALM_ASSERT_EX(-nanoseconds_per_second < nanoseconds && nanoseconds < nanoseconds_per_second, nanoseconds);
+        const bool both_non_negative = seconds >= 0 && nanoseconds >= 0;
+        const bool both_non_positive = seconds <= 0 && nanoseconds <= 0;
+        REALM_ASSERT_EX(both_non_negative || both_non_positive, both_non_negative, both_non_positive);
+    }
+    Timestamp(realm::null)
+        : m_is_null(true)
+    {
+    }
+    Timestamp()
+        : Timestamp(null{})
+    {
+    }
+
+    bool is_null() const
+    {
+        return m_is_null;
+    }
+
+    int64_t get_seconds() const noexcept
+    {
+        REALM_ASSERT(!m_is_null);
+        return m_seconds;
+    }
+
+    int32_t get_nanoseconds() const noexcept
+    {
+        REALM_ASSERT(!m_is_null);
+        return m_nanoseconds;
+    }
+
+    // Note that only == and != operators work if one of the Timestamps are null! Else use realm::Greater,
+    // realm::Less, etc, instead. This is in order to collect all treatment of null behaviour in a single place for all
+    // types (query_conditions.hpp) to ensure that all types sort and compare null vs. non-null in the same manner,
+    // especially for int/float where we cannot override operators. This design is open for discussion, though,
+    // because it has usability drawbacks
+    bool operator==(const Timestamp& rhs) const
+    {
+        if (is_null() && rhs.is_null())
+            return true;
+
+        if (is_null() != rhs.is_null())
+            return false;
+
+        return m_seconds == rhs.m_seconds && m_nanoseconds == rhs.m_nanoseconds;
+    }
+    bool operator!=(const Timestamp& rhs) const
+    {
+        return !(*this == rhs);
+    }
+    bool operator>(const Timestamp& rhs) const
+    {
+        REALM_ASSERT(!is_null());
+        REALM_ASSERT(!rhs.is_null());
+        return (m_seconds > rhs.m_seconds) || (m_seconds == rhs.m_seconds && m_nanoseconds > rhs.m_nanoseconds);
+    }
+    bool operator<(const Timestamp& rhs) const
+    {
+        REALM_ASSERT(!is_null());
+        REALM_ASSERT(!rhs.is_null());
+        return (m_seconds < rhs.m_seconds) || (m_seconds == rhs.m_seconds && m_nanoseconds < rhs.m_nanoseconds);
+    }
+    bool operator<=(const Timestamp& rhs) const
+    {
+        REALM_ASSERT(!is_null());
+        REALM_ASSERT(!rhs.is_null());
+        return *this < rhs || *this == rhs;
+    }
+    bool operator>=(const Timestamp& rhs) const
+    {
+        REALM_ASSERT(!is_null());
+        REALM_ASSERT(!rhs.is_null());
+        return *this > rhs || *this == rhs;
+    }
+    Timestamp& operator=(const Timestamp& rhs) = default;
+
+    template <class Ch, class Tr>
+    friend std::basic_ostream<Ch, Tr>& operator<<(std::basic_ostream<Ch, Tr>& out, const Timestamp&);
+    static constexpr int32_t nanoseconds_per_second = 1000000000;
+
+private:
+    int64_t m_seconds;
+    int32_t m_nanoseconds;
+    bool m_is_null;
+};
+
+// LCOV_EXCL_START
+template <class C, class T>
+inline std::basic_ostream<C, T>& operator<<(std::basic_ostream<C, T>& out, const Timestamp& d)
+{
+    out << "Timestamp(" << d.m_seconds << ", " << d.m_nanoseconds << ")";
+    return out;
+}
+// LCOV_EXCL_STOP
+
+} // namespace realm
+
+#endif // REALM_TIMESTAMP_HPP