added iOS source code
[wl-app.git] / iOS / Pods / Realm / include / core / realm / impl / sequential_getter.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_IMPL_SEQUENTIAL_GETTER_HPP
20 #define REALM_IMPL_SEQUENTIAL_GETTER_HPP
21
22 namespace realm {
23
24 class SequentialGetterBase {
25 public:
26     virtual ~SequentialGetterBase() noexcept
27     {
28     }
29 };
30
31 template <class ColType>
32 class SequentialGetter : public SequentialGetterBase {
33 public:
34     using T = typename ColType::value_type;
35     using ArrayType = typename ColType::LeafType;
36
37     SequentialGetter()
38     {
39     }
40
41     SequentialGetter(const Table& table, size_t column_ndx)
42     {
43         init(static_cast<const ColType*>(&table.get_column_base(column_ndx)));
44     }
45
46     SequentialGetter(const ColType* column)
47     {
48         init(column);
49     }
50
51     ~SequentialGetter() noexcept override
52     {
53     }
54
55     void init(const ColType* column)
56     {
57         REALM_ASSERT(column != nullptr);
58         m_array_ptr.reset(); // Explicitly destroy the old one first, because we're reusing the memory.
59         m_array_ptr.reset(new (&m_leaf_accessor_storage) ArrayType(column->get_alloc()));
60         m_column = column;
61         m_leaf_end = 0;
62     }
63
64     REALM_FORCEINLINE bool cache_next(size_t index)
65     {
66         // Set m_leaf_ptr to point at the leaf that contains the value at column row `index`. Return whether or not
67         // the leaf has changed (could be useful to know for caller).
68
69         // FIXME: Below line has been commented away because array leafs might relocate during the lifetime of the
70         // object that owns this SequentialGetter. Enable again when we have proper support for that.
71         //        if (index >= m_leaf_end || index < m_leaf_start)
72         {
73             typename ColType::LeafInfo leaf{&m_leaf_ptr, m_array_ptr.get()};
74             size_t ndx_in_leaf;
75             m_column->get_leaf(index, ndx_in_leaf, leaf);
76             m_leaf_start = index - ndx_in_leaf;
77             const size_t leaf_size = m_leaf_ptr->size();
78             m_leaf_end = m_leaf_start + leaf_size;
79             return true;
80         }
81         return false;
82     }
83
84
85     REALM_FORCEINLINE T get_next(size_t index)
86     {
87 #ifdef _MSC_VER
88 #pragma warning(push)
89 #pragma warning(disable : 4800) // Disable the Microsoft warning about bool performance issue.
90 #endif
91         return m_column->get(index);
92
93         // FIXME: Below optimization is skipped because array leafs might relocate during the lifetime of the
94         // object that owns this SequentialGetter. Enable again when we have proper support for that.
95 //
96 //      cache_next(index);
97 //      T av = m_leaf_ptr->get(index - m_leaf_start);
98 //      return av;
99
100 #ifdef _MSC_VER
101 #pragma warning(pop)
102 #endif
103     }
104
105     size_t local_end(size_t global_end)
106     {
107         if (global_end > m_leaf_end)
108             return m_leaf_end - m_leaf_start;
109         else
110             return global_end - m_leaf_start;
111     }
112
113     size_t m_leaf_start = 0;
114     size_t m_leaf_end = 0;
115     const ColType* m_column = nullptr;
116
117     const ArrayType* m_leaf_ptr = nullptr;
118
119 private:
120     // Leaf cache for when the root of the column is not a leaf.
121     // This dog and pony show is because Array has a reference to Allocator internally,
122     // but we need to be able to transfer queries between contexts, so init() reinitializes
123     // the leaf cache in the context of the current column.
124     typename std::aligned_storage<sizeof(ArrayType), alignof(ArrayType)>::type m_leaf_accessor_storage;
125     std::unique_ptr<ArrayType, PlacementDelete> m_array_ptr;
126 };
127
128 } // namespace realm
129
130 #endif // REALM_IMPL_SEQUENTIAL_GETTER_HPP