added iOS source code
[wl-app.git] / iOS / Pods / Realm / include / core / realm / column_tpl.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_COLUMN_TPL_HPP
20 #define REALM_COLUMN_TPL_HPP
21
22 #include <cstdlib>
23
24 #include <realm/util/features.h>
25 #include <realm/array.hpp>
26 #include <realm/array_basic.hpp>
27
28 namespace realm {
29
30 template <class T, class cond>
31 class FloatDoubleNode;
32 template <class ColType, class Cond>
33 class IntegerNode;
34 template <class T>
35 class SequentialGetter;
36
37 template <class cond, class T>
38 struct ColumnTypeTraits2;
39
40 template <class cond>
41 struct ColumnTypeTraits2<cond, int64_t> {
42     typedef IntegerColumn column_type;
43     typedef ArrayInteger array_type;
44 };
45 template <class cond>
46 struct ColumnTypeTraits2<cond, bool> {
47     typedef IntegerColumn column_type;
48     typedef ArrayInteger array_type;
49 };
50 template <class cond>
51 struct ColumnTypeTraits2<cond, float> {
52     typedef FloatColumn column_type;
53     typedef ArrayFloat array_type;
54 };
55 template <class cond>
56 struct ColumnTypeTraits2<cond, double> {
57     typedef DoubleColumn column_type;
58     typedef ArrayDouble array_type;
59 };
60
61
62 namespace _impl {
63
64 template <class ColType>
65 struct FindInLeaf {
66     using LeafType = typename ColType::LeafType;
67
68     template <Action action, class Condition, class T, class R>
69     static bool find(const LeafType& leaf, T target, size_t local_start, size_t local_end, size_t leaf_start,
70                      QueryState<R>& state)
71     {
72         Condition cond;
73         bool cont = true;
74         // todo, make an additional loop with hard coded `false` instead of is_null(v) for non-nullable columns
75         bool null_target = null::is_null_float(target);
76         for (size_t local_index = local_start; cont && local_index < local_end; local_index++) {
77             auto v = leaf.get(local_index);
78             if (cond(v, target, null::is_null_float(v), null_target)) {
79                 cont = state.template match<action, false>(leaf_start + local_index, 0, static_cast<R>(v));
80             }
81         }
82         return cont;
83     }
84 };
85
86 template <>
87 struct FindInLeaf<IntegerColumn> {
88     using LeafType = IntegerColumn::LeafType;
89
90     template <Action action, class Condition, class T, class R>
91     static bool find(const LeafType& leaf, T target, size_t local_start, size_t local_end, size_t leaf_start,
92                      QueryState<R>& state)
93     {
94         const int c = Condition::condition;
95         return leaf.find(c, action, target, local_start, local_end, leaf_start, &state);
96     }
97 };
98
99 template <>
100 struct FindInLeaf<IntNullColumn> {
101     using LeafType = IntNullColumn::LeafType;
102
103     template <Action action, class Condition, class T, class R>
104     static bool find(const LeafType& leaf, T target, size_t local_start, size_t local_end, size_t leaf_start,
105                      QueryState<R>& state)
106     {
107         constexpr int cond = Condition::condition;
108         return leaf.find(cond, action, target, local_start, local_end, leaf_start, &state);
109     }
110 };
111
112 } // namespace _impl
113
114 template <class T, class R, Action action, class Condition, class ColType>
115 R aggregate(const ColType& column, T target, size_t start, size_t end, size_t limit, size_t* return_ndx)
116 {
117     if (end == npos)
118         end = column.size();
119
120     QueryState<R> state;
121     state.init(action, nullptr, limit);
122     SequentialGetter<ColType> sg{&column};
123
124     bool cont = true;
125     for (size_t s = start; cont && s < end;) {
126         sg.cache_next(s);
127         size_t start2 = s - sg.m_leaf_start;
128         size_t end2 = sg.local_end(end);
129         cont = _impl::FindInLeaf<ColType>::template find<action, Condition>(*sg.m_leaf_ptr, target, start2, end2,
130                                                                             sg.m_leaf_start, state);
131         s = sg.m_leaf_start + end2;
132     }
133
134     if (return_ndx)
135         *return_ndx = action == act_Sum ? state.m_match_count : state.m_minmax_index;
136
137     return state.m_state;
138 }
139
140
141 } // namespace realm
142
143 #endif // REALM_COLUMN_TPL_HPP