added iOS source code
[wl-app.git] / iOS / Pods / Realm / include / core / realm / table_ref.hpp
diff --git a/iOS/Pods/Realm/include/core/realm/table_ref.hpp b/iOS/Pods/Realm/include/core/realm/table_ref.hpp
new file mode 100644 (file)
index 0000000..6e5c02b
--- /dev/null
@@ -0,0 +1,481 @@
+/*************************************************************************
+ *
+ * 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_TABLE_REF_HPP
+#define REALM_TABLE_REF_HPP
+
+#include <cstddef>
+#include <algorithm>
+
+#include <realm/util/bind_ptr.hpp>
+
+namespace realm {
+
+
+class Table;
+
+
+/// A reference-counting "smart pointer" for referring to table
+/// accessors.
+///
+/// The purpose of this smart pointer is to keep the referenced table
+/// accessor alive for as long as anybody is referring to it, however,
+/// for stack allocated table accessors, the lifetime is necessarily
+/// determined by scope (see below).
+///
+/// Please take note of the distinction between a "table" and a "table
+/// accessor" here. A table accessor is an instance of `Table`,
+/// and it may, or may not be attached to an
+/// actual table at any specific point in time, but this state of
+/// attachment of the accessor has nothing to do with the function of
+/// the smart pointer. Also, in the rest of the documentation of this
+/// class, whenever you see `Table::%foo`, you are supposed to read it
+/// as, `Table::%foo`.
+///
+///
+/// Table accessors are either created directly by an application via
+/// a call to one of the public table constructors, or they are
+/// created internally by the Realm library, such as when the
+/// application calls Group::get_table(), Table::get_subtable(), or
+/// Table::create().
+///
+/// Applications can safely assume that all table accessors, created
+/// internally by the Realm library, have a lifetime that is managed
+/// by reference counting. This means that the application can prolong
+/// the lifetime of *such* table accessors indefinitely by holding on
+/// to at least one smart pointer, but note that the guarantee of the
+/// continued existence of the accessor, does not imply that the
+/// accessor remains attached to the underlying table (see
+/// Table::is_attached() for details). Accessors whose lifetime are
+/// controlled by reference counting are destroyed exactly when the
+/// reference count drops to zero.
+///
+/// When an application creates a new table accessor by a direct call
+/// to one of the public constructors, the lifetime of that table
+/// accessor is *not*, and cannot be managed by reference
+/// counting. This is true regardless of the way the accessor is
+/// created (i.e., regardless of whether it is an automatic variable
+/// on the stack, or created on the heap using `new`). However, for
+/// convenience, but with one important caveat, it is still possible
+/// to use smart pointers to refer to such accessors. The caveat is
+/// that no smart pointers are allowed to refer to the accessor at the
+/// point in time when its destructor is called. It is entirely the
+/// responsibility of the application to ensure that this requirement
+/// is met. Failing to do so, will result in undefined
+/// behavior. Finally, please note that an application is always free
+/// to use Table::create() as an alternative to creating free-standing
+/// top-level tables on the stack, and that this is indeed neccessary
+/// when fully reference counted lifetimes are required.
+///
+/// So, at any time, and for any table accessor, an application can
+/// call Table::get_table_ref() to obtain a smart pointer that refers
+/// to that table, however, while that is always possible and safe, it
+/// is not always possible to extend the lifetime of an accessor by
+/// holding on to a smart pointer. The question of whether that is
+/// possible, depends directly on the way the accessor was created.
+///
+///
+/// Apart from keeping track of the number of references, these smart
+/// pointers behaves almost exactly like regular pointers. In
+/// particular, it is possible to dereference a TableRef and get a
+/// `Table&` out of it, however, if you are not careful, this can
+/// easily lead to dangling references:
+///
+/// \code{.cpp}
+///
+///   Table& sub_1 = *(table.get_subtable(0,0));
+///   sub_1.add_empty_row(); // Oops, sub_1 may be dangling!
+///
+/// \endcode
+///
+/// Whether `sub_1` is actually dangling in the example above will
+/// depend on whether other references to the same subtable accessor
+/// already exist, but it is never wise to rely in this. Here is a
+/// safe and proper alternative:
+///
+/// \code{.cpp}
+///
+///   TableRef sub_2 = table.get_subtable(0,0);
+///   sub_2.add_empty_row(); // Safe!
+///
+///   void do_something(Table&);
+///   do_something(*(table.get_subtable(0,0))); // Also safe!
+///
+/// \endcode
+///
+///
+/// \sa Table
+/// \sa TableRef
+template <class T>
+class BasicTableRef : util::bind_ptr<T> {
+public:
+    constexpr BasicTableRef() noexcept
+    {
+    }
+    ~BasicTableRef() noexcept
+    {
+    }
+
+    // Copy construct
+    BasicTableRef(const BasicTableRef& r) noexcept
+        : util::bind_ptr<T>(r)
+    {
+    }
+    template <class U>
+    BasicTableRef(const BasicTableRef<U>& r) noexcept
+        : util::bind_ptr<T>(r)
+    {
+    }
+
+    // Copy assign
+    BasicTableRef& operator=(const BasicTableRef&) noexcept;
+    template <class U>
+    BasicTableRef& operator=(const BasicTableRef<U>&) noexcept;
+
+    // Move construct
+    BasicTableRef(BasicTableRef&& r) noexcept
+        : util::bind_ptr<T>(std::move(r))
+    {
+    }
+    template <class U>
+    BasicTableRef(BasicTableRef<U>&& r) noexcept
+        : util::bind_ptr<T>(std::move(r))
+    {
+    }
+
+    // Move assign
+    BasicTableRef& operator=(BasicTableRef&&) noexcept;
+    template <class U>
+    BasicTableRef& operator=(BasicTableRef<U>&&) noexcept;
+
+    //@{
+    /// Comparison
+    template <class U>
+    bool operator==(const BasicTableRef<U>&) const noexcept;
+
+    template <class U>
+    bool operator==(U*) const noexcept;
+
+    template <class U>
+    bool operator!=(const BasicTableRef<U>&) const noexcept;
+
+    template <class U>
+    bool operator!=(U*) const noexcept;
+
+    template <class U>
+    bool operator<(const BasicTableRef<U>&) const noexcept;
+
+    template <class U>
+    bool operator<(U*) const noexcept;
+
+    template <class U>
+    bool operator>(const BasicTableRef<U>&) const noexcept;
+
+    template <class U>
+    bool operator>(U*) const noexcept;
+
+    template <class U>
+    bool operator<=(const BasicTableRef<U>&) const noexcept;
+
+    template <class U>
+    bool operator<=(U*) const noexcept;
+
+    template <class U>
+    bool operator>=(const BasicTableRef<U>&) const noexcept;
+
+    template <class U>
+    bool operator>=(U*) const noexcept;
+//@}
+
+// Dereference
+#ifdef __clang__
+    // Clang has a bug that causes it to effectively ignore the 'using' declaration.
+    T& operator*() const noexcept
+    {
+        return util::bind_ptr<T>::operator*();
+    }
+#else
+    using util::bind_ptr<T>::operator*;
+#endif
+    using util::bind_ptr<T>::operator->;
+
+    using util::bind_ptr<T>::operator bool;
+
+    T* get() const noexcept
+    {
+        return util::bind_ptr<T>::get();
+    }
+    void reset() noexcept
+    {
+        util::bind_ptr<T>::reset();
+    }
+    void reset(T* t) noexcept
+    {
+        util::bind_ptr<T>::reset(t);
+    }
+
+    void swap(BasicTableRef& r) noexcept
+    {
+        this->util::bind_ptr<T>::swap(r);
+    }
+    friend void swap(BasicTableRef& a, BasicTableRef& b) noexcept
+    {
+        a.swap(b);
+    }
+
+    template <class U>
+    friend BasicTableRef<U> unchecked_cast(BasicTableRef<Table>) noexcept;
+
+    template <class U>
+    friend BasicTableRef<const U> unchecked_cast(BasicTableRef<const Table>) noexcept;
+
+private:
+    template <class>
+    struct GetRowAccType {
+        typedef void type;
+    };
+
+    typedef typename GetRowAccType<T>::type RowAccessor;
+
+public:
+    /// Same as 'table[i]' where 'table' is the referenced table.
+    RowAccessor operator[](size_t i) const noexcept
+    {
+        return (*this->get())[i];
+    }
+
+    explicit BasicTableRef(T* t) noexcept
+        : util::bind_ptr<T>(t)
+    {
+    }
+
+    T* release() { return util::bind_ptr<T>::release(); }
+private:
+    friend class SubtableColumnBase;
+    friend class Table;
+    friend class Group;
+
+    template <class>
+    friend class BasicTableRef;
+
+    typedef typename util::bind_ptr<T>::casting_move_tag casting_move_tag;
+    template <class U>
+    BasicTableRef(BasicTableRef<U>* r, casting_move_tag) noexcept
+        : util::bind_ptr<T>(r, casting_move_tag())
+    {
+    }
+};
+
+
+typedef BasicTableRef<Table> TableRef;
+typedef BasicTableRef<const Table> ConstTableRef;
+
+
+template <class C, class T, class U>
+inline std::basic_ostream<C, T>& operator<<(std::basic_ostream<C, T>& out, const BasicTableRef<U>& p)
+{
+    out << static_cast<const void*>(&*p);
+    return out;
+}
+
+template <class T>
+inline BasicTableRef<T> unchecked_cast(TableRef t) noexcept
+{
+    return BasicTableRef<T>(&t, typename BasicTableRef<T>::casting_move_tag());
+}
+
+template <class T>
+inline BasicTableRef<const T> unchecked_cast(ConstTableRef t) noexcept
+{
+    return BasicTableRef<const T>(&t, typename BasicTableRef<T>::casting_move_tag());
+}
+
+
+//@{
+/// Comparison
+template <class T, class U>
+bool operator==(T*, const BasicTableRef<U>&) noexcept;
+template <class T, class U>
+bool operator!=(T*, const BasicTableRef<U>&) noexcept;
+template <class T, class U>
+bool operator<(T*, const BasicTableRef<U>&) noexcept;
+template <class T, class U>
+bool operator>(T*, const BasicTableRef<U>&) noexcept;
+template <class T, class U>
+bool operator<=(T*, const BasicTableRef<U>&) noexcept;
+template <class T, class U>
+bool operator>=(T*, const BasicTableRef<U>&) noexcept;
+//@}
+
+
+// Implementation:
+
+template <class T>
+inline BasicTableRef<T>& BasicTableRef<T>::operator=(const BasicTableRef& r) noexcept
+{
+    this->util::bind_ptr<T>::operator=(r);
+    return *this;
+}
+
+template <class T>
+template <class U>
+inline BasicTableRef<T>& BasicTableRef<T>::operator=(const BasicTableRef<U>& r) noexcept
+{
+    this->util::bind_ptr<T>::operator=(r);
+    return *this;
+}
+
+template <class T>
+inline BasicTableRef<T>& BasicTableRef<T>::operator=(BasicTableRef&& r) noexcept
+{
+    this->util::bind_ptr<T>::operator=(std::move(r));
+    return *this;
+}
+
+template <class T>
+template <class U>
+inline BasicTableRef<T>& BasicTableRef<T>::operator=(BasicTableRef<U>&& r) noexcept
+{
+    this->util::bind_ptr<T>::operator=(std::move(r));
+    return *this;
+}
+
+template <class T>
+template <class U>
+bool BasicTableRef<T>::operator==(const BasicTableRef<U>& p) const noexcept
+{
+    return get() == p.get();
+}
+
+template <class T>
+template <class U>
+bool BasicTableRef<T>::operator==(U* p) const noexcept
+{
+    return get() == p;
+}
+
+template <class T>
+template <class U>
+bool BasicTableRef<T>::operator!=(const BasicTableRef<U>& p) const noexcept
+{
+    return get() != p.get();
+}
+
+template <class T>
+template <class U>
+bool BasicTableRef<T>::operator!=(U* p) const noexcept
+{
+    return get() != p;
+}
+
+template <class T>
+template <class U>
+bool BasicTableRef<T>::operator<(const BasicTableRef<U>& p) const noexcept
+{
+    return get() < p.get();
+}
+
+template <class T>
+template <class U>
+bool BasicTableRef<T>::operator<(U* p) const noexcept
+{
+    return get() < p;
+}
+
+template <class T>
+template <class U>
+bool BasicTableRef<T>::operator>(const BasicTableRef<U>& p) const noexcept
+{
+    return get() > p.get();
+}
+
+template <class T>
+template <class U>
+bool BasicTableRef<T>::operator>(U* p) const noexcept
+{
+    return get() > p;
+}
+
+template <class T>
+template <class U>
+bool BasicTableRef<T>::operator<=(const BasicTableRef<U>& p) const noexcept
+{
+    return get() <= p.get();
+}
+
+template <class T>
+template <class U>
+bool BasicTableRef<T>::operator<=(U* p) const noexcept
+{
+    return get() <= p;
+}
+
+template <class T>
+template <class U>
+bool BasicTableRef<T>::operator>=(const BasicTableRef<U>& p) const noexcept
+{
+    return get() >= p.get();
+}
+
+template <class T>
+template <class U>
+bool BasicTableRef<T>::operator>=(U* p) const noexcept
+{
+    return get() >= p;
+}
+
+template <class T, class U>
+bool operator==(T* a, const BasicTableRef<U>& b) noexcept
+{
+    return b == a;
+}
+
+template <class T, class U>
+bool operator!=(T* a, const BasicTableRef<U>& b) noexcept
+{
+    return b != a;
+}
+
+template <class T, class U>
+bool operator<(T* a, const BasicTableRef<U>& b) noexcept
+{
+    return b > a;
+}
+
+template <class T, class U>
+bool operator>(T* a, const BasicTableRef<U>& b) noexcept
+{
+    return b < a;
+}
+
+template <class T, class U>
+bool operator<=(T* a, const BasicTableRef<U>& b) noexcept
+{
+    return b >= a;
+}
+
+template <class T, class U>
+bool operator>=(T* a, const BasicTableRef<U>& b) noexcept
+{
+    return b <= a;
+}
+
+
+} // namespace realm
+
+#endif // REALM_TABLE_REF_HPP