Blame view

Pods/Realm/include/core/realm/array_mixed.hpp 3.99 KB
75d24c15   yangbin   123
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
  /*************************************************************************
   *
   * Copyright 2018 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_ARRAY_MIXED_HPP
  #define REALM_ARRAY_MIXED_HPP
  
  #include <realm/data_type.hpp>
  #include <realm/mixed.hpp>
  #include <realm/obj.hpp>
  #include <realm/array_binary.hpp>
  #include <realm/array_string.hpp>
  #include <realm/array_timestamp.hpp>
  #include <realm/array_key.hpp>
  
  namespace realm {
  
  class ArrayMixed : public ArrayPayload, private Array {
  public:
      using value_type = Mixed;
  
      using Array::detach;
      using Array::is_attached;
      using Array::get_ref;
      using Array::set_parent;
      using Array::update_parent;
      using Array::get_parent;
  
      explicit ArrayMixed(Allocator&);
  
      static Mixed default_value(bool)
      {
          return Mixed{};
      }
  
      void create();
      void destroy()
      {
          Array::destroy_deep();
      }
  
      void init_from_mem(MemRef mem) noexcept;
  
      void init_from_ref(ref_type ref) noexcept override
      {
          init_from_mem(MemRef(m_alloc.translate(ref), ref, m_alloc));
      }
      void set_parent(ArrayParent* parent, size_t ndx_in_parent) noexcept override
      {
          Array::set_parent(parent, ndx_in_parent);
      }
      void init_from_parent()
      {
          ref_type ref = get_ref_from_parent();
          ArrayMixed::init_from_ref(ref);
      }
  
      size_t size() const
      {
          return m_composite.size();
      }
  
      void add(Mixed value);
      void set(size_t ndx, Mixed value);
      void set_null(size_t ndx);
      void insert(size_t ndx, Mixed value);
      Mixed get(size_t ndx) const;
      Mixed get_any(size_t ndx) const override
      {
          return get(ndx);
      }
      bool is_null(size_t ndx) const
      {
          return m_composite.get(ndx) == 0;
      }
  
      void clear();
      void erase(size_t ndx);
      void truncate_and_destroy_children(size_t ndx);
      void move(ArrayMixed& dst, size_t ndx);
  
      size_t find_first(Mixed value, size_t begin = 0, size_t end = realm::npos) const noexcept;
  
      void verify() const;
  
  private:
      enum { payload_idx_type, payload_idx_int, payload_idx_pair, payload_idx_str, payload_idx_size };
  
      static constexpr int64_t s_data_type_mask = 0b0001'1111;
      static constexpr int64_t s_payload_idx_mask = 0b1110'0000;
      static constexpr int64_t s_payload_idx_shift = 5;
      static constexpr int64_t s_data_shift = 8;
  
      // This primary array contains an aggregation of the actual value - which can be
      // either the value itself or an index into one of the payload arrays - the index
      // of the payload array and the data_type.
      //
      // value << s_data_shift | payload_idx << s_payload_idx_shift | data_type
      //
      // payload_idx one of PayloadIdx
      Array m_composite;
  
      // Used to store big ints, floats and doubles
      mutable Array m_ints;
      // Used to store timestamps
      mutable Array m_int_pairs;
      // Used to store String and Binary
      mutable ArrayString m_strings;
  
      DataType get_type(size_t ndx) const
      {
          return DataType((m_composite.get(ndx) & s_data_type_mask) - 1);
      }
      int64_t store(const Mixed&);
      void ensure_array_accessor(Array& arr, size_t ndx_in_parent) const;
      void ensure_int_array() const;
      void ensure_int_pair_array() const;
      void ensure_string_array() const;
      void replace_index(size_t old_ndx, size_t new_ndx, size_t payload_index);
      void erase_linked_payload(size_t ndx);
  };
  } // namespace realm
  
  #endif /* REALM_ARRAY_MIXED_HPP */