added iOS source code
[wl-app.git] / iOS / Pods / Realm / include / list.hpp
1 ////////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright 2015 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_OS_LIST_HPP
20 #define REALM_OS_LIST_HPP
21
22 #include "collection_notifications.hpp"
23 #include "impl/collection_notifier.hpp"
24 #include "property.hpp"
25
26 #include <realm/link_view_fwd.hpp>
27 #include <realm/row.hpp>
28 #include <realm/table_ref.hpp>
29
30 #include <functional>
31 #include <memory>
32
33 namespace realm {
34 class ObjectSchema;
35 class Query;
36 class Realm;
37 class Results;
38 class SortDescriptor;
39 template <typename T> class ThreadSafeReference;
40
41 namespace _impl {
42 class ListNotifier;
43 }
44
45 class List {
46 public:
47     List() noexcept;
48     List(std::shared_ptr<Realm> r, Table& parent_table, size_t col, size_t row);
49     List(std::shared_ptr<Realm> r, LinkViewRef l) noexcept;
50     List(std::shared_ptr<Realm> r, TableRef l) noexcept;
51     ~List();
52
53     List(const List&);
54     List& operator=(const List&);
55     List(List&&);
56     List& operator=(List&&);
57
58     const std::shared_ptr<Realm>& get_realm() const { return m_realm; }
59     Query get_query() const;
60     size_t get_origin_row_index() const;
61
62     // Get the type of the values contained in this List
63     PropertyType get_type() const;
64
65     // Get the ObjectSchema of the values in this List
66     // Only valid if get_type() returns PropertyType::Object
67     ObjectSchema const& get_object_schema() const;
68
69     bool is_valid() const;
70     void verify_attached() const;
71     void verify_in_transaction() const;
72
73     size_t size() const;
74
75     void move(size_t source_ndx, size_t dest_ndx);
76     void remove(size_t list_ndx);
77     void remove_all();
78     void swap(size_t ndx1, size_t ndx2);
79     void delete_at(size_t list_ndx);
80     void delete_all();
81
82     template<typename T = RowExpr>
83     T get(size_t row_ndx) const;
84     template<typename T>
85     size_t find(T const& value) const;
86
87     // Find the index in the List of the first row matching the query
88     size_t find(Query&& query) const;
89
90     template<typename T>
91     void add(T value);
92     template<typename T>
93     void insert(size_t list_ndx, T value);
94     template<typename T>
95     void set(size_t row_ndx, T value);
96
97     Results sort(SortDescriptor order) const;
98     Results sort(std::vector<std::pair<std::string, bool>> const& keypaths) const;
99     Results filter(Query q) const;
100
101     // Return a Results representing a live view of this List.
102     Results as_results() const;
103
104     // Return a Results representing a snapshot of this List.
105     Results snapshot() const;
106
107     // Get the min/max/average/sum of the given column
108     // All but sum() returns none when there are zero matching rows
109     // sum() returns 0,
110     // Throws UnsupportedColumnTypeException for sum/average on timestamp or non-numeric column
111     // Throws OutOfBoundsIndexException for an out-of-bounds column
112     util::Optional<Mixed> max(size_t column=0);
113     util::Optional<Mixed> min(size_t column=0);
114     util::Optional<double> average(size_t column=0);
115     Mixed sum(size_t column=0);
116
117     bool operator==(List const& rgt) const noexcept;
118
119     NotificationToken add_notification_callback(CollectionChangeCallback cb) &;
120
121     template<typename Context>
122     auto get(Context&, size_t row_ndx) const;
123     template<typename T, typename Context>
124     size_t find(Context&, T&& value) const;
125
126     template<typename T, typename Context>
127     void add(Context&, T&& value, bool update=false);
128     template<typename T, typename Context>
129     void insert(Context&, size_t list_ndx, T&& value, bool update=false);
130     template<typename T, typename Context>
131     void set(Context&, size_t row_ndx, T&& value, bool update=false);
132
133     // Replace the values in this list with the values from an enumerable object
134     template<typename T, typename Context>
135     void assign(Context&, T&& value, bool update=false);
136
137     // The List object has been invalidated (due to the Realm being invalidated,
138     // or the containing object being deleted)
139     // All non-noexcept functions can throw this
140     struct InvalidatedException : public std::logic_error {
141         InvalidatedException() : std::logic_error("Access to invalidated List object") {}
142     };
143
144     // The input index parameter was out of bounds
145     struct OutOfBoundsIndexException : public std::out_of_range {
146         OutOfBoundsIndexException(size_t r, size_t c);
147         size_t requested;
148         size_t valid_count;
149     };
150
151 private:
152     friend ThreadSafeReference<List>;
153
154     std::shared_ptr<Realm> m_realm;
155     mutable const ObjectSchema* m_object_schema = nullptr;
156     LinkViewRef m_link_view;
157     TableRef m_table;
158     _impl::CollectionNotifier::Handle<_impl::CollectionNotifier> m_notifier;
159
160     void verify_valid_row(size_t row_ndx, bool insertion = false) const;
161     void validate(RowExpr) const;
162
163     template<typename Fn>
164     auto dispatch(Fn&&) const;
165
166     size_t to_table_ndx(size_t row) const noexcept;
167
168     friend struct std::hash<List>;
169 };
170
171 template<typename Fn>
172 auto List::dispatch(Fn&& fn) const
173 {
174     return switch_on_type(get_type(), std::forward<Fn>(fn));
175 }
176
177 template<typename Context>
178 auto List::get(Context& ctx, size_t row_ndx) const
179 {
180     return dispatch([&](auto t) { return ctx.box(this->get<std::decay_t<decltype(*t)>>(row_ndx)); });
181 }
182
183 template<typename T, typename Context>
184 size_t List::find(Context& ctx, T&& value) const
185 {
186     return dispatch([&](auto t) { return this->find(ctx.template unbox<std::decay_t<decltype(*t)>>(value)); });
187 }
188
189 template<typename T, typename Context>
190 void List::add(Context& ctx, T&& value, bool update)
191 {
192     dispatch([&](auto t) { this->add(ctx.template unbox<std::decay_t<decltype(*t)>>(value, true, update)); });
193 }
194
195 template<typename T, typename Context>
196 void List::insert(Context& ctx, size_t list_ndx, T&& value, bool update)
197 {
198     dispatch([&](auto t) { this->insert(list_ndx, ctx.template unbox<std::decay_t<decltype(*t)>>(value, true, update)); });
199 }
200
201 template<typename T, typename Context>
202 void List::set(Context& ctx, size_t row_ndx, T&& value, bool update)
203 {
204     dispatch([&](auto t) { this->set(row_ndx, ctx.template unbox<std::decay_t<decltype(*t)>>(value, true, update)); });
205 }
206
207 template<typename T, typename Context>
208 void List::assign(Context& ctx, T&& values, bool update)
209 {
210     if (ctx.is_same_list(*this, values))
211         return;
212
213     remove_all();
214     if (ctx.is_null(values))
215         return;
216
217     ctx.enumerate_list(values, [&](auto&& element) {
218         this->add(ctx, element, update);
219     });
220 }
221 } // namespace realm
222
223 namespace std {
224 template<> struct hash<realm::List> {
225     size_t operator()(realm::List const&) const;
226 };
227 }
228
229 #endif // REALM_OS_LIST_HPP