added iOS source code
[wl-app.git] / iOS / Pods / Realm / include / core / realm / lang_bind_helper.hpp
diff --git a/iOS/Pods/Realm/include/core/realm/lang_bind_helper.hpp b/iOS/Pods/Realm/include/core/realm/lang_bind_helper.hpp
new file mode 100644 (file)
index 0000000..de287bf
--- /dev/null
@@ -0,0 +1,378 @@
+/*************************************************************************
+ *
+ * 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_LANG_BIND_HELPER_HPP
+#define REALM_LANG_BIND_HELPER_HPP
+
+#include <cstddef>
+
+#include <realm/table.hpp>
+#include <realm/table_view.hpp>
+#include <realm/link_view.hpp>
+#include <realm/group.hpp>
+#include <realm/group_shared.hpp>
+
+#include <realm/replication.hpp>
+
+namespace realm {
+
+
+/// These functions are only to be used by language bindings to gain
+/// access to certain memebers that are othewise private.
+///
+/// \note Applications are not supposed to call any of these functions
+/// directly.
+///
+/// All of the get_subtable_ptr() functions bind the table accessor pointer
+/// before it is returned (bind_table_ptr()). The caller is then responsible for
+/// making the corresponding call to unbind_table_ptr().
+class LangBindHelper {
+public:
+    /// Increment the reference counter of the specified table accessor. This is
+    /// done automatically by all of the functions in this class that return
+    /// table accessor pointers, but if the binding/application makes a copy of
+    /// such a pointer, and the copy needs to have an "independent life", then
+    /// the binding/application must bind that copy using this function.
+    static void bind_table_ptr(const Table*) noexcept;
+
+    /// Decrement the reference counter of the specified table accessor. The
+    /// binding/application must call this function for every bound table
+    /// accessor pointer object, when that pointer object ends its life.
+    static void unbind_table_ptr(const Table*) noexcept;
+
+    /// Construct a new freestanding table. The table accessor pointer is bound
+    /// by the callee before it is returned (bind_table_ptr()).
+    static Table* new_table();
+
+    /// Construct a new freestanding table as a copy of the specified one. The
+    /// table accessor pointer is bound by the callee before it is returned
+    /// (bind_table_ptr()).
+    static Table* copy_table(const Table&);
+
+    //@{
+
+    /// These functions are like their namesakes in Group, but these bypass the
+    /// construction of a smart-pointer object (TableRef). The table accessor
+    /// pointer is bound by the callee before it is returned (bind_table_ptr()).
+
+    static Table* get_table(Group&, size_t index_in_group);
+    static const Table* get_table(const Group&, size_t index_in_group);
+
+    static Table* get_table(Group&, StringData name);
+    static const Table* get_table(const Group&, StringData name);
+
+    static Table* add_table(Group&, StringData name, bool require_unique_name = true);
+    static Table* get_or_add_table(Group&, StringData name, bool* was_added = nullptr);
+
+    //@}
+
+    static Table* get_subtable_ptr(Table*, size_t column_ndx, size_t row_ndx);
+    static const Table* get_subtable_ptr(const Table*, size_t column_ndx, size_t row_ndx);
+
+    // FIXME: This is an 'oddball', do we really need it? If we do,
+    // please provide a comment that explains why it is needed!
+    static Table* get_subtable_ptr_during_insert(Table*, size_t col_ndx, size_t row_ndx);
+
+    static Table* get_subtable_ptr(TableView*, size_t column_ndx, size_t row_ndx);
+    static const Table* get_subtable_ptr(const TableView*, size_t column_ndx, size_t row_ndx);
+    static const Table* get_subtable_ptr(const ConstTableView*, size_t column_ndx, size_t row_ndx);
+
+    /// Calls parent.set_mixed_subtable(col_ndx, row_ndx, &source). Note
+    /// that the source table must have a descriptor that is
+    /// compatible with the target subtable column.
+    static void set_mixed_subtable(Table& parent, size_t col_ndx, size_t row_ndx, const Table& source);
+
+    static const LinkViewRef& get_linklist_ptr(Row&, size_t col_ndx);
+    static void unbind_linklist_ptr(const LinkViewRef&);
+
+    using VersionID = SharedGroup::VersionID;
+
+    /// \defgroup lang_bind_helper_transactions Continuous Transactions
+    ///
+    /// advance_read() is equivalent to terminating the current read transaction
+    /// (SharedGroup::end_read()), and initiating a new one
+    /// (SharedGroup::begin_read()), except that all subordinate accessors
+    /// (Table, Row, Descriptor) will remain attached to the underlying objects,
+    /// unless those objects were removed in the target snapshot. By default,
+    /// the read transaction is advanced to the latest available snapshot, but
+    /// see SharedGroup::begin_read() for information about \a version.
+    ///
+    /// promote_to_write() is equivalent to terminating the current read
+    /// transaction (SharedGroup::end_read()), and initiating a new write
+    /// transaction (SharedGroup::begin_write()), except that all subordinate
+    /// accessors (Table, Row, Descriptor) will remain attached to the
+    /// underlying objects, unless those objects were removed in the target
+    /// snapshot.
+    ///
+    /// commit_and_continue_as_read() is equivalent to committing the current
+    /// write transaction (SharedGroup::commit()) and initiating a new read
+    /// transaction, which is bound to the snapshot produced by the write
+    /// transaction (SharedGroup::begin_read()), except that all subordinate
+    /// accessors (Table, Row, Descriptor) will remain attached to the
+    /// underlying objects. commit_and_continue_as_read() returns the version
+    /// produced by the committed transaction.
+    ///
+    /// rollback_and_continue_as_read() is equivalent to rolling back the
+    /// current write transaction (SharedGroup::rollback()) and initiating a new
+    /// read transaction, which is bound to the snapshot, that the write
+    /// transaction was based on (SharedGroup::begin_read()), except that all
+    /// subordinate accessors (Table, Row, Descriptor) will remain attached to
+    /// the underlying objects, unless they were attached to object that were
+    /// added during the rolled back transaction.
+    ///
+    /// If advance_read(), promote_to_write(), commit_and_continue_as_read(), or
+    /// rollback_and_continue_as_read() throws, the associated group accessor
+    /// and all of its subordinate accessors are left in a state that may not be
+    /// fully consistent. Only minimal consistency is guaranteed (see
+    /// AccessorConsistencyLevels). In this case, the application is required to
+    /// either destroy the SharedGroup object, forcing all associated accessors
+    /// to become detached, or take some other equivalent action that involves a
+    /// complete accessor detachment, such as terminating the transaction in
+    /// progress. Until then it is an error, and unsafe if the application
+    /// attempts to access any of those accessors.
+    ///
+    /// The application must use SharedGroup::end_read() if it wants to
+    /// terminate the transaction after advance_read() or promote_to_write() has
+    /// thrown an exception. Likewise, it must use SharedGroup::rollback() if it
+    /// wants to terminate the transaction after commit_and_continue_as_read()
+    /// or rollback_and_continue_as_read() has thrown an exception.
+    ///
+    /// \param observer An optional custom replication instruction handler. The
+    /// application may pass such a handler to observe the sequence of
+    /// modifications that advances (or rolls back) the state of the Realm.
+    ///
+    /// \throw SharedGroup::BadVersion Thrown by advance_read() if the specified
+    /// version does not correspond to a bound (or tethered) snapshot.
+    ///
+    //@{
+
+    static void advance_read(SharedGroup&, VersionID = VersionID());
+    template <class O>
+    static void advance_read(SharedGroup&, O&& observer, VersionID = VersionID());
+    static void promote_to_write(SharedGroup&);
+    template <class O>
+    static void promote_to_write(SharedGroup&, O&& observer);
+    static SharedGroup::version_type commit_and_continue_as_read(SharedGroup&);
+    static void rollback_and_continue_as_read(SharedGroup&);
+    template <class O>
+    static void rollback_and_continue_as_read(SharedGroup&, O&& observer);
+
+    //@}
+
+    /// Returns the name of the specified data type. Examples:
+    ///
+    /// <pre>
+    ///
+    ///   type_Int          ->  "int"
+    ///   type_Bool         ->  "bool"
+    ///   type_Float        ->  "float"
+    ///   ...
+    ///
+    /// </pre>
+    static const char* get_data_type_name(DataType) noexcept;
+
+    static SharedGroup::version_type get_version_of_latest_snapshot(SharedGroup&);
+};
+
+
+// Implementation:
+
+inline Table* LangBindHelper::new_table()
+{
+    typedef _impl::TableFriend tf;
+    Allocator& alloc = Allocator::get_default();
+    size_t ref = tf::create_empty_table(alloc); // Throws
+    Table::Parent* parent = nullptr;
+    size_t ndx_in_parent = 0;
+    Table* table = tf::create_accessor(alloc, ref, parent, ndx_in_parent); // Throws
+    bind_table_ptr(table);
+    return table;
+}
+
+inline Table* LangBindHelper::copy_table(const Table& table)
+{
+    typedef _impl::TableFriend tf;
+    Allocator& alloc = Allocator::get_default();
+    size_t ref = tf::clone(table, alloc); // Throws
+    Table::Parent* parent = nullptr;
+    size_t ndx_in_parent = 0;
+    Table* copy_of_table = tf::create_accessor(alloc, ref, parent, ndx_in_parent); // Throws
+    bind_table_ptr(copy_of_table);
+    return copy_of_table;
+}
+
+inline Table* LangBindHelper::get_subtable_ptr(Table* t, size_t column_ndx, size_t row_ndx)
+{
+    TableRef subtab = t->get_subtable_tableref(column_ndx, row_ndx); // Throws
+    return subtab.release();
+}
+
+inline const Table* LangBindHelper::get_subtable_ptr(const Table* t, size_t column_ndx, size_t row_ndx)
+{
+    ConstTableRef subtab = t->get_subtable_tableref(column_ndx, row_ndx); // Throws
+    return subtab.release();
+}
+
+inline Table* LangBindHelper::get_subtable_ptr(TableView* tv, size_t column_ndx, size_t row_ndx)
+{
+    return get_subtable_ptr(&tv->get_parent(), column_ndx, tv->get_source_ndx(row_ndx));
+}
+
+inline const Table* LangBindHelper::get_subtable_ptr(const TableView* tv, size_t column_ndx, size_t row_ndx)
+{
+    return get_subtable_ptr(&tv->get_parent(), column_ndx, tv->get_source_ndx(row_ndx));
+}
+
+inline const Table* LangBindHelper::get_subtable_ptr(const ConstTableView* tv, size_t column_ndx, size_t row_ndx)
+{
+    return get_subtable_ptr(&tv->get_parent(), column_ndx, tv->get_source_ndx(row_ndx));
+}
+
+inline Table* LangBindHelper::get_table(Group& group, size_t index_in_group)
+{
+    typedef _impl::GroupFriend gf;
+    Table* table = &gf::get_table(group, index_in_group); // Throws
+    table->bind_ptr();
+    return table;
+}
+
+inline const Table* LangBindHelper::get_table(const Group& group, size_t index_in_group)
+{
+    typedef _impl::GroupFriend gf;
+    const Table* table = &gf::get_table(group, index_in_group); // Throws
+    table->bind_ptr();
+    return table;
+}
+
+inline Table* LangBindHelper::get_table(Group& group, StringData name)
+{
+    typedef _impl::GroupFriend gf;
+    Table* table = gf::get_table(group, name); // Throws
+    if (table)
+        table->bind_ptr();
+    return table;
+}
+
+inline const Table* LangBindHelper::get_table(const Group& group, StringData name)
+{
+    typedef _impl::GroupFriend gf;
+    const Table* table = gf::get_table(group, name); // Throws
+    if (table)
+        table->bind_ptr();
+    return table;
+}
+
+inline Table* LangBindHelper::add_table(Group& group, StringData name, bool require_unique_name)
+{
+    typedef _impl::GroupFriend gf;
+    Table* table = &gf::add_table(group, name, require_unique_name); // Throws
+    table->bind_ptr();
+    return table;
+}
+
+inline Table* LangBindHelper::get_or_add_table(Group& group, StringData name, bool* was_added)
+{
+    typedef _impl::GroupFriend gf;
+    Table* table = &gf::get_or_add_table(group, name, was_added); // Throws
+    table->bind_ptr();
+    return table;
+}
+
+inline void LangBindHelper::unbind_table_ptr(const Table* t) noexcept
+{
+    t->unbind_ptr();
+}
+
+inline void LangBindHelper::bind_table_ptr(const Table* t) noexcept
+{
+    t->bind_ptr();
+}
+
+inline void LangBindHelper::set_mixed_subtable(Table& parent, size_t col_ndx, size_t row_ndx, const Table& source)
+{
+    parent.set_mixed_subtable(col_ndx, row_ndx, &source);
+}
+
+inline const LinkViewRef& LangBindHelper::get_linklist_ptr(Row& row, size_t col_ndx)
+{
+    LinkViewRef* link_view = new LinkViewRef(row.get_linklist(col_ndx));
+    return *link_view;
+}
+
+inline void LangBindHelper::unbind_linklist_ptr(const LinkViewRef& link_view)
+{
+    delete (&link_view);
+}
+
+inline void LangBindHelper::advance_read(SharedGroup& sg, VersionID version)
+{
+    using sgf = _impl::SharedGroupFriend;
+    _impl::NullInstructionObserver* observer = nullptr;
+    sgf::advance_read(sg, observer, version); // Throws
+}
+
+template <class O>
+inline void LangBindHelper::advance_read(SharedGroup& sg, O&& observer, VersionID version)
+{
+    using sgf = _impl::SharedGroupFriend;
+    sgf::advance_read(sg, &observer, version); // Throws
+}
+
+inline void LangBindHelper::promote_to_write(SharedGroup& sg)
+{
+    using sgf = _impl::SharedGroupFriend;
+    _impl::NullInstructionObserver* observer = nullptr;
+    sgf::promote_to_write(sg, observer); // Throws
+}
+
+template <class O>
+inline void LangBindHelper::promote_to_write(SharedGroup& sg, O&& observer)
+{
+    using sgf = _impl::SharedGroupFriend;
+    sgf::promote_to_write(sg, &observer); // Throws
+}
+
+inline SharedGroup::version_type LangBindHelper::commit_and_continue_as_read(SharedGroup& sg)
+{
+    using sgf = _impl::SharedGroupFriend;
+    return sgf::commit_and_continue_as_read(sg); // Throws
+}
+
+inline void LangBindHelper::rollback_and_continue_as_read(SharedGroup& sg)
+{
+    using sgf = _impl::SharedGroupFriend;
+    _impl::NullInstructionObserver* observer = nullptr;
+    sgf::rollback_and_continue_as_read(sg, observer); // Throws
+}
+
+template <class O>
+inline void LangBindHelper::rollback_and_continue_as_read(SharedGroup& sg, O&& observer)
+{
+    using sgf = _impl::SharedGroupFriend;
+    sgf::rollback_and_continue_as_read(sg, &observer); // Throws
+}
+
+inline SharedGroup::version_type LangBindHelper::get_version_of_latest_snapshot(SharedGroup& sg)
+{
+    using sgf = _impl::SharedGroupFriend;
+    return sgf::get_version_of_latest_snapshot(sg); // Throws
+}
+
+} // namespace realm
+
+#endif // REALM_LANG_BIND_HELPER_HPP