pstore2
section_sparray.hpp
Go to the documentation of this file.
1 //===- include/pstore/mcrepo/section_sparray.hpp ----------*- mode: C++ -*-===//
2 //* _ _ *
3 //* ___ ___ ___| |_(_) ___ _ __ ___ _ __ __ _ _ __ _ __ __ _ _ _ *
4 //* / __|/ _ \/ __| __| |/ _ \| '_ \ / __| '_ \ / _` | '__| '__/ _` | | | | *
5 //* \__ \ __/ (__| |_| | (_) | | | | \__ \ |_) | (_| | | | | | (_| | |_| | *
6 //* |___/\___|\___|\__|_|\___/|_| |_| |___/ .__/ \__,_|_| |_| \__,_|\__, | *
7 //* |_| |___/ *
8 //===----------------------------------------------------------------------===//
9 //
10 // Part of the pstore project, under the Apache License v2.0 with LLVM Exceptions.
11 // See https://github.com/SNSystems/pstore/blob/master/LICENSE.txt for license
12 // information.
13 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
14 //
15 //===----------------------------------------------------------------------===//
18 
19 #ifndef PSTORE_MCREPO_SECTION_SPARRAY_HPP
20 #define PSTORE_MCREPO_SECTION_SPARRAY_HPP
21 
22 #include <iterator>
23 #include <limits>
24 
26 #include "pstore/mcrepo/section.hpp"
27 
28 namespace pstore {
29  namespace repo {
30 
31  namespace details {
32 
33  template <typename CastToType, typename BaseIterator>
34  class cast_iterator {
35  public:
36  using iterator_category =
37  typename std::iterator_traits<BaseIterator>::iterator_category;
38  using value_type = CastToType;
39  using difference_type =
40  typename std::iterator_traits<BaseIterator>::difference_type;
41  using pointer = value_type const *;
42  using reference = value_type const &;
43 
44  constexpr explicit cast_iterator (BaseIterator it);
45  constexpr bool operator== (cast_iterator const & rhs) const;
46  constexpr bool operator!= (cast_iterator const & rhs) const;
47  constexpr reference operator* () const;
48  cast_iterator & operator++ (); // ++prefix
49  cast_iterator operator++ (int); // postfix++
50  cast_iterator & operator-- (); // --prefix
51  cast_iterator operator-- (int); // postfix--
52  cast_iterator operator+ (unsigned x) const { return cast_iterator{it_ + x}; }
53  cast_iterator operator- (unsigned x) const { return cast_iterator{it_ - x}; }
54 
55  private:
56  BaseIterator it_;
57  mutable value_type value_;
58  };
59  template <typename CastToType, typename BaseIterator>
61  : it_{it}
62  , value_{} {}
63  template <typename CastToType, typename BaseIterator>
64  constexpr bool
66  return it_ == rhs.it_;
67  }
68  template <typename CastToType, typename BaseIterator>
69  constexpr bool
71  return !operator== (rhs);
72  }
73  template <typename CastToType, typename BaseIterator>
75  -> reference {
76  return value_ = static_cast<CastToType> (*it_);
77  }
78  template <typename CastToType, typename BaseIterator>
80  -> cast_iterator & { // ++prefix
81  ++it_;
82  return *this;
83  }
84  template <typename CastToType, typename BaseIterator>
86  -> cast_iterator { // prefix++
87  auto prev = *this;
88  ++(*this);
89  return prev;
90  }
91  template <typename CastToType, typename BaseIterator>
93  -> cast_iterator & { // ++prefix
94  --it_;
95  return *this;
96  }
97  template <typename CastToType, typename BaseIterator>
99  -> cast_iterator { // prefix++
100  auto prev = *this;
101  --(*this);
102  return prev;
103  }
104 
105  } // end namespace details
106 
109  template <typename T>
111  private:
112  using index_type = std::underlying_type_t<section_kind>;
113  static_assert (std::is_unsigned<index_type>::value,
114  "section-kind underlying type should be unsigned");
115 
117  template <typename Iterator>
118  static constexpr bool is_section_kind_iterator () {
119  return std::is_same<typename std::remove_cv<
120  typename std::iterator_traits<Iterator>::value_type>::type,
121  section_kind>::value;
122  }
123 
124  using array_type =
126 
127  public:
128  using value_type = typename array_type::value_type;
129  using size_type = typename array_type::size_type;
130  using iterator = typename array_type::iterator;
131  using const_iterator = typename array_type::const_iterator;
132  using reference = value_type &;
133  using const_reference = value_type const &;
134 
137  template <typename IndexIterator, typename = typename std::enable_if_t<
138  is_section_kind_iterator<IndexIterator> ()>>
139  constexpr section_sparray (IndexIterator first, IndexIterator last);
140 
143  constexpr value_type & operator[] (section_kind k) noexcept;
144  constexpr value_type const & operator[] (section_kind k) const noexcept;
145 
147  constexpr reference front () noexcept;
149  constexpr const_reference front () const noexcept;
151  constexpr reference back () noexcept;
153  constexpr const_reference back () const noexcept;
155 
156 
159  static constexpr std::size_t size_bytes (std::size_t members) noexcept;
161  constexpr std::size_t size_bytes () const {
162  return section_sparray<T>::size_bytes (this->size ());
163  }
164 
167 
169  iterator begin () { return sa_.begin (); }
170  const_iterator begin () const { return sa_.begin (); }
171  const_iterator cbegin () const { return sa_.cbegin (); }
172 
174  iterator end () { return sa_.end (); }
175  const_iterator end () const { return sa_.end (); }
176  const_iterator cend () const { return sa_.cend (); }
177 
179 
180 
183  constexpr bool empty () const noexcept { return sa_.empty (); }
184  constexpr size_type size () const noexcept { return sa_.size (); }
185 
191  constexpr bool has_index (section_kind pos) const noexcept {
192  return sa_.has_index (static_cast<index_type> (pos));
193  }
195 
198  class indices {
199  public:
200  using iterator =
201  details::cast_iterator<section_kind,
202  typename array_type::indices::const_iterator>;
203  using const_iterator = iterator;
204 
205  constexpr explicit indices (typename array_type::indices const & i) noexcept
206  : i_{i} {}
207  constexpr iterator begin () const noexcept { return iterator{i_.begin ()}; }
208  constexpr iterator end () const noexcept { return iterator{i_.end ()}; }
209  constexpr bool empty () const noexcept { return i_.empty (); }
210 
211  section_kind front () const noexcept {
212  return static_cast<section_kind> (i_.front ());
213  }
214  section_kind back () const noexcept {
215  return static_cast<section_kind> (i_.back ());
216  }
217 
218  private:
219  typename array_type::indices const i_;
220  };
221 
222  indices get_indices () const noexcept { return indices{sa_.get_indices ()}; }
223 
224  private:
225  array_type sa_;
226  };
227 
228  // (ctor)
229  // ~~~~~~
230  template <typename T>
231  template <typename IndexIterator, typename>
232  constexpr section_sparray<T>::section_sparray (IndexIterator first, IndexIterator last)
235 
236  static_assert (
237  std::numeric_limits<typename array_type::bitmap_type>::radix == 2,
238  "expected numeric radix to be 2 (so that 'digits' is the number of bits)");
239  static_assert (static_cast<index_type> (section_kind::last) <=
240  std::numeric_limits<typename array_type::bitmap_type>::digits,
241  "section_kind does not fit in the member sparse array");
242  }
243 
244  // front
245  // ~~~~~
246  template <typename T>
247  constexpr auto section_sparray<T>::front () noexcept -> reference {
248  return sa_.front ();
249  }
250  template <typename T>
251  constexpr auto section_sparray<T>::front () const noexcept -> const_reference {
252  return sa_.front ();
253  }
254  // back
255  // ~~~~
256  template <typename T>
257  constexpr auto section_sparray<T>::back () noexcept -> reference {
258  return sa_.back ();
259  }
260  template <typename T>
261  constexpr auto section_sparray<T>::back () const noexcept -> const_reference {
262  return sa_.back ();
263  }
264 
265  // operator[]
266  // ~~~~~~~~~~
267  template <typename T>
268  constexpr auto section_sparray<T>::operator[] (section_kind k) noexcept -> value_type & {
269  return sa_[static_cast<index_type> (k)];
270  }
271  template <typename T>
272  constexpr auto section_sparray<T>::operator[] (section_kind k) const noexcept
273  -> value_type const & {
274  return sa_[static_cast<index_type> (k)];
275  }
276 
277  // size bytes
278  // ~~~~~~~~~~
279  template <typename T>
280  constexpr std::size_t section_sparray<T>::size_bytes (std::size_t const members) noexcept {
281  return array_type::size_bytes (members);
282  }
283 
284  } // end namespace repo
285 } // end namespace pstore
286 
287 #endif // PSTORE_MCREPO_SECTION_SPARRAY_HPP
constexpr section_sparray(IndexIterator first, IndexIterator last)
Constructs a sparse array whose available indices are defined by the iterator range from [first...
Definition: section_sparray.hpp:232
iterator begin()
Returns an iterator to the beginning of the container.
Definition: section_sparray.hpp:169
iterator end()
Returns an iterator to the end of the container.
Definition: section_sparray.hpp:174
Implements a sparse array type.
transaction< transaction_lock > begin(database &db, transaction_lock &lock)
Creates a new transaction. Every operation performed on a transaction instance can be potentially und...
Definition: transaction.hpp:311
Definition: section_sparray.hpp:34
Definition: print.cpp:18
constexpr std::size_t size_bytes() const
Returns the number of bytes of storage that are being used by this array instance.
Definition: section_sparray.hpp:161
A wrapper for the sparse_array<> type which is specialized for indices of type section_kind.
Definition: section_sparray.hpp:110
Definition: nonpod2.cpp:40
constexpr reference front() noexcept
Returns the value associated with the first section-kind index in the container.
Definition: section_sparray.hpp:247
A container which can be used to access and iterate over the available index values in the sparse arr...
Definition: section_sparray.hpp:198
constexpr bool has_index(section_kind pos) const noexcept
Returns true if the sparse array has an index pos.
Definition: section_sparray.hpp:191
constexpr reference back() noexcept
Returns the value associated with the last section-kind index in the container.
Definition: section_sparray.hpp:257