added iOS source code
[wl-app.git] / iOS / Pods / Realm / include / core / realm / views.hpp
1 /*************************************************************************
2  *
3  * Copyright 2016 Realm Inc.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  **************************************************************************/
18
19 #ifndef REALM_VIEWS_HPP
20 #define REALM_VIEWS_HPP
21
22 #include <realm/column.hpp>
23 #include <realm/handover_defs.hpp>
24
25 #include <vector>
26
27 namespace realm {
28
29 const int64_t detached_ref = -1;
30
31 class RowIndexes;
32
33 // Forward declaration needed for deleted CommonDescriptor constructor
34 class SortDescriptor;
35
36 // CommonDescriptor encapsulates a reference to a set of columns (possibly over
37 // links), which is used to indicate the criteria columns for sort and distinct.
38 // Although the input is column indices, it does not rely on those indices
39 // remaining stable as long as the columns continue to exist.
40 class CommonDescriptor {
41 public:
42     CommonDescriptor() = default;
43     // Enforce type saftey to prevent automatic conversion of derived class
44     // SortDescriptor into CommonDescriptor at compile time.
45     CommonDescriptor(const SortDescriptor&) = delete;
46     virtual ~CommonDescriptor() = default;
47
48     // Create a descriptor for the given columns on the given table.
49     // Each vector in `column_indices` represents a chain of columns, where
50     // all but the last are Link columns (n.b.: LinkList and Backlink are not
51     // supported), and the final is any column type that can be sorted on.
52     // `column_indices` must be non-empty, and each vector within it must also
53     // be non-empty.
54     CommonDescriptor(Table const& table, std::vector<std::vector<size_t>> column_indices);
55     virtual std::unique_ptr<CommonDescriptor> clone() const;
56
57     // returns whether this descriptor is valid and can be used to sort
58     bool is_valid() const noexcept
59     {
60         return !m_columns.empty();
61     }
62
63     class Sorter;
64     virtual Sorter sorter(IntegerColumn const& row_indexes) const;
65
66     // handover support
67     std::vector<std::vector<size_t>> export_column_indices() const;
68     virtual std::vector<bool> export_order() const
69     {
70         return {};
71     }
72
73 protected:
74     std::vector<std::vector<const ColumnBase*>> m_columns;
75 };
76
77 class SortDescriptor : public CommonDescriptor {
78 public:
79     // Create a sort descriptor for the given columns on the given table.
80     // See CommonDescriptor for restrictions on `column_indices`.
81     // The sort order can be specified by using `ascending` which must either be
82     // empty or have one entry for each column index chain.
83     SortDescriptor(Table const& table, std::vector<std::vector<size_t>> column_indices,
84                    std::vector<bool> ascending = {});
85     SortDescriptor() = default;
86     ~SortDescriptor() = default;
87     std::unique_ptr<CommonDescriptor> clone() const override;
88
89     void merge_with(SortDescriptor&& other);
90
91     Sorter sorter(IntegerColumn const& row_indexes) const override;
92
93     // handover support
94     std::vector<bool> export_order() const override;
95
96 private:
97     std::vector<bool> m_ascending;
98 };
99
100 // Distinct uses the same syntax as sort except that the order is meaningless.
101 typedef CommonDescriptor DistinctDescriptor;
102
103 class DescriptorOrdering {
104 public:
105     DescriptorOrdering() = default;
106     DescriptorOrdering(const DescriptorOrdering&);
107     DescriptorOrdering(DescriptorOrdering&&) = default;
108     DescriptorOrdering& operator=(const DescriptorOrdering&);
109     DescriptorOrdering& operator=(DescriptorOrdering&&) = default;
110
111     void append_sort(SortDescriptor sort);
112     void append_distinct(DistinctDescriptor distinct);
113     bool descriptor_is_sort(size_t index) const;
114     bool descriptor_is_distinct(size_t index) const;
115     bool is_empty() const { return m_descriptors.empty(); }
116     size_t size() const { return m_descriptors.size(); }
117     const CommonDescriptor* operator[](size_t ndx) const;
118     bool will_apply_sort() const;
119     bool will_apply_distinct() const;
120
121     // handover support
122     using HandoverPatch = std::unique_ptr<DescriptorOrderingHandoverPatch>;
123     static void generate_patch(DescriptorOrdering const&, HandoverPatch&);
124     static DescriptorOrdering create_from_and_consume_patch(HandoverPatch&, Table const&);
125
126 private:
127     std::vector<std::unique_ptr<CommonDescriptor>> m_descriptors;
128 };
129
130 // This class is for common functionality of ListView and LinkView which inherit from it. Currently it only
131 // supports sorting and distinct.
132 class RowIndexes {
133 public:
134     RowIndexes(IntegerColumn::unattached_root_tag urt, realm::Allocator& alloc);
135     RowIndexes(IntegerColumn&& col);
136     RowIndexes(const RowIndexes& source, ConstSourcePayload mode);
137     RowIndexes(RowIndexes& source, MutableSourcePayload mode);
138
139     virtual ~RowIndexes()
140     {
141 #ifdef REALM_COOKIE_CHECK
142         m_debug_cookie = 0x7765697633333333; // 0x77656976 = 'view'; 0x33333333 = '3333' = destructed
143 #endif
144     }
145
146     // Disable copying, this is not supported.
147     RowIndexes& operator=(const RowIndexes&) = delete;
148     RowIndexes(const RowIndexes&) = delete;
149
150     // Return a column of the table that m_row_indexes are pointing at (which is the target table for LinkList and
151     // parent table for TableView)
152     virtual const ColumnBase& get_column_base(size_t index) const = 0;
153
154     virtual size_t size() const = 0;
155
156     // These two methods are overridden by TableView and LinkView.
157     virtual uint_fast64_t sync_if_needed() const = 0;
158     virtual bool is_in_sync() const
159     {
160         return true;
161     }
162
163     void check_cookie() const
164     {
165 #ifdef REALM_COOKIE_CHECK
166         REALM_ASSERT_RELEASE(m_debug_cookie == cookie_expected);
167 #endif
168     }
169
170     IntegerColumn m_row_indexes;
171
172 protected:
173     void do_sort(const DescriptorOrdering& ordering);
174
175     static const uint64_t cookie_expected = 0x7765697677777777ull; // 0x77656976 = 'view'; 0x77777777 = '7777' = alive
176     uint64_t m_debug_cookie;
177 };
178
179 } // namespace realm
180
181 #endif // REALM_VIEWS_HPP