pstore2
linked_definitions_section.hpp
Go to the documentation of this file.
1 //===- include/pstore/mcrepo/linked_definitions_section.hpp *- mode: C++ -*-===//
2 //* _ _ _ _ _ __ _ _ _ _ *
3 //* | (_)_ __ | | _____ __| | __| | ___ / _(_)_ __ (_) |_(_) ___ _ __ ___ *
4 //* | | | '_ \| |/ / _ \/ _` | / _` |/ _ \ |_| | '_ \| | __| |/ _ \| '_ \/ __| *
5 //* | | | | | | < __/ (_| | | (_| | __/ _| | | | | | |_| | (_) | | | \__ \ *
6 //* |_|_|_| |_|_|\_\___|\__,_| \__,_|\___|_| |_|_| |_|_|\__|_|\___/|_| |_|___/ *
7 //* *
8 //* _ _ *
9 //* ___ ___ ___| |_(_) ___ _ __ *
10 //* / __|/ _ \/ __| __| |/ _ \| '_ \ *
11 //* \__ \ __/ (__| |_| | (_) | | | | *
12 //* |___/\___|\___|\__|_|\___/|_| |_| *
13 //* *
14 //===----------------------------------------------------------------------===//
15 //
16 // Part of the pstore project, under the Apache License v2.0 with LLVM Exceptions.
17 // See https://github.com/SNSystems/pstore/blob/master/LICENSE.txt for license
18 // information.
19 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
20 //
21 //===----------------------------------------------------------------------===//
24 
25 #ifndef PSTORE_MCREPO_LINKED_DEFINITIONS_SECTION_HPP
26 #define PSTORE_MCREPO_LINKED_DEFINITIONS_SECTION_HPP
27 
28 #include "pstore/mcrepo/compilation.hpp"
29 #include "pstore/mcrepo/section.hpp"
31 
32 namespace pstore {
33  namespace repo {
34 
35  namespace details {
36 
37  template <typename InputIt>
38  auto udistance (InputIt first, InputIt last) {
39  auto d = std::distance (first, last);
40  PSTORE_ASSERT (d >= 0);
41  return static_cast<std::make_unsigned_t<decltype (d)>> (d);
42  }
43 
44  } // end namespace details
45 
46  //* _ _ _ _ _ __ _ _ _ _ *
47  //* | (_)_ _ | |_____ __| | __| |___ / _(_)_ _ (_) |_(_)___ _ _ ___ *
48  //* | | | ' \| / / -_) _` | / _` / -_) _| | ' \| | _| / _ \ ' \(_-< *
49  //* |_|_|_||_|_\_\___\__,_| \__,_\___|_| |_|_||_|_|\__|_\___/_||_/__/ *
50  //* *
63  public:
64  struct value_type {
65  value_type () noexcept = default;
66  constexpr value_type (index::digest const compilation_, std::uint32_t const index_,
67  typed_address<definition> const pointer_) noexcept
68  : compilation{compilation_}
69  , index{index_}
70  , pointer{pointer_} {}
71 
72  bool operator== (value_type const & rhs) const noexcept;
73  bool operator!= (value_type const & rhs) const noexcept {
74  return !operator== (rhs);
75  }
76 
83  std::uint32_t index = 0;
84  std::uint32_t unused = 0;
91  };
92 
93  using iterator = value_type *;
94  using const_iterator = value_type const *;
95 
96  template <typename Iterator,
97  typename = typename std::enable_if_t<std::is_same<
98  typename std::iterator_traits<Iterator>::value_type, value_type>::value>>
99  linked_definitions (Iterator begin, Iterator end);
100 
101  linked_definitions (linked_definitions const &) = delete;
102  linked_definitions & operator= (linked_definitions const &) = delete;
103 
106 
107  value_type const & operator[] (std::size_t const i) const {
108  return index_impl (*this, i);
109  }
110  value_type & operator[] (std::size_t const i) { return index_impl (*this, i); }
112 
115 
116  iterator begin () noexcept { return definitions_; }
117  const_iterator begin () const noexcept { return definitions_; }
118  const_iterator cbegin () const noexcept { return this->begin (); }
119 
120  iterator end () noexcept { return definitions_ + size_; }
121  const_iterator end () const noexcept { return definitions_ + size_; }
122  const_iterator cend () const noexcept { return this->end (); }
124 
127 
129  bool empty () const noexcept { return size_ == 0; }
131  std::size_t size () const noexcept { return size_; }
133 
136 
139  static std::size_t size_bytes (std::uint64_t size) noexcept;
140 
142  std::size_t size_bytes () const noexcept;
144 
150  static auto load (database const & db, typed_address<linked_definitions> const ld)
151  -> std::shared_ptr<linked_definitions const>;
152 
153  private:
154  template <typename LinkedDefinitions, typename ResultType = typename inherit_const<
155  LinkedDefinitions, value_type>::type>
156  static ResultType & index_impl (LinkedDefinitions & v, std::size_t pos) {
157  PSTORE_ASSERT (pos < v.size ());
158  return v.definitions_[pos];
159  }
160 
161  std::uint64_t size_;
162  std::uint64_t unused_ = 0;
163  value_type definitions_[1];
164  };
165 
166  PSTORE_STATIC_ASSERT (std::is_standard_layout<linked_definitions::value_type>::value);
167  PSTORE_STATIC_ASSERT (sizeof (linked_definitions::value_type) == 32);
168  PSTORE_STATIC_ASSERT (alignof (linked_definitions::value_type) == 16);
169  PSTORE_STATIC_ASSERT (offsetof (linked_definitions::value_type, compilation) == 0);
170  PSTORE_STATIC_ASSERT (offsetof (linked_definitions::value_type, index) == 16);
171  PSTORE_STATIC_ASSERT (offsetof (linked_definitions::value_type, unused) == 20);
172  PSTORE_STATIC_ASSERT (offsetof (linked_definitions::value_type, pointer) == 24);
173 
174  template <typename Iterator, typename>
175  linked_definitions::linked_definitions (Iterator begin, Iterator end)
176  : size_{details::udistance (begin, end)} {
177  std::copy (begin, end, &definitions_[0]);
178 
179  unused_ = 0; // to suppress a warning about the field being unused.
180  PSTORE_STATIC_ASSERT (std::is_standard_layout<linked_definitions>::value);
181  PSTORE_STATIC_ASSERT (alignof (linked_definitions) == 16);
182  PSTORE_STATIC_ASSERT (offsetof (linked_definitions, size_) == 0);
183  PSTORE_STATIC_ASSERT (offsetof (linked_definitions, unused_) == 8);
184  PSTORE_STATIC_ASSERT (offsetof (linked_definitions, definitions_) == 16);
185  }
186 
187 
188  template <>
189  inline unsigned section_alignment<pstore::repo::linked_definitions> (
190  pstore::repo::linked_definitions const &) noexcept {
191  return 1U;
192  }
193  template <>
194  inline std::uint64_t section_size<pstore::repo::linked_definitions> (
195  pstore::repo::linked_definitions const &) noexcept {
196  return 0U;
197  }
198 
199  std::ostream & operator<< (std::ostream & os, linked_definitions::value_type const & ld);
200 
201  //* _ _ _ _ _ _ *
202  //* __ _ _ ___ __ _| |_(_)___ _ _ __| (_)____ __ __ _| |_ __| |_ ___ _ _ *
203  //* / _| '_/ -_) _` | _| / _ \ ' \ / _` | (_-< '_ \/ _` | _/ _| ' \/ -_) '_| *
204  //* \__|_| \___\__,_|\__|_\___/_||_| \__,_|_/__/ .__/\__,_|\__\__|_||_\___|_| *
205  //* |_| *
207  public:
208  using const_iterator = linked_definitions::value_type const *;
209 
210  linked_definitions_creation_dispatcher (const_iterator const begin,
211  const_iterator const end)
212  : section_creation_dispatcher (section_kind::linked_definitions)
213  , begin_ (begin)
214  , end_ (end) {
215  PSTORE_ASSERT (std::distance (begin, end) > 0 &&
216  "a linked_definitions section must hold "
217  "at least one reference to a definition");
218  }
220  linked_definitions_creation_dispatcher const &) = delete;
222  operator= (linked_definitions_creation_dispatcher const &) = delete;
223 
224  std::size_t size_bytes () const final;
225 
226  std::uint8_t * write (std::uint8_t * out) const final;
227 
229  const_iterator begin () const { return begin_; }
231  const_iterator end () const { return end_; }
232 
233  private:
234  std::uintptr_t aligned_impl (std::uintptr_t in) const final;
235 
236  const_iterator begin_;
237  const_iterator end_;
238  };
239 
240  template <>
243  };
244 
246  public:
247  explicit linked_definitions_dispatcher (linked_definitions const & d) noexcept
248  : d_{d} {}
249  ~linked_definitions_dispatcher () noexcept override;
250 
251  std::size_t size_bytes () const final { return d_.size_bytes (); }
252  unsigned align () const final { error (); }
253  std::size_t size () const final { error (); }
254  container<internal_fixup> ifixups () const final { error (); }
255  container<external_fixup> xfixups () const final { error (); }
256  container<std::uint8_t> payload () const final { error (); }
257 
258  private:
259  PSTORE_NO_RETURN void error () const;
260  linked_definitions const & d_;
261  };
262 
263 
264  template <>
267  };
268 
269  } // end namespace repo
270 } // end namespace pstore
271 
272 #endif // PSTORE_MCREPO_LINKED_DEFINITIONS_SECTION_HPP
const_iterator end() const
Returns a const_iterator for the end of definition address range.
Definition: linked_definitions_section.hpp:231
const_iterator begin() const
Returns a const_iterator for the beginning of the definition address range.
Definition: linked_definitions_section.hpp:229
Definition: uint128.hpp:85
typed_address< definition > pointer
The address of the definition given by value_type::compilation and value_type::index.
Definition: linked_definitions_section.hpp:90
index::digest compilation
The digest of the compilation containing the definition to which the owning fragment is linked...
Definition: linked_definitions_section.hpp:79
Definition: linked_definitions_section.hpp:64
std::size_t size() const noexcept
Returns the number of elements.
Definition: linked_definitions_section.hpp:131
A simple wrapper around the elements of one of the three arrays that make up a section.
Definition: section.hpp:152
Maps from the type of data that is associated with a fragment&#39;s section to a "dispatcher" subclass wh...
Definition: section.hpp:146
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
This class is used to add virtual methods to a fragment&#39;s section.
Definition: section.hpp:195
Definition: address.hpp:231
An empty class used as the base type for all sections.
Definition: section.hpp:69
Maps from the type of data that is associated with a fragment&#39;s section to a "dispatcher" subclass wh...
Definition: section.hpp:214
container< std::uint8_t > payload() const final
Return the data section stored in the object file.
Definition: linked_definitions_section.hpp:256
Definition: print.cpp:18
bool empty() const noexcept
Checks whether the container is empty.
Definition: linked_definitions_section.hpp:129
Represents the definitions linked to a fragment.
Definition: linked_definitions_section.hpp:62
A utility template intended to simplify the writing of the const- and non-const variants of member fu...
A compilation is a holder for zero or more definitions.
Definition: compilation.hpp:128
Definition: nonpod2.cpp:40
Definition: database.hpp:40
Provides a member typedef inherit_const::type, which is defined as R const if T is a const type and R...
Definition: inherit_const.hpp:108
Definition: linked_definitions_section.hpp:206
Definition: linked_definitions_section.hpp:245
A section creation dispatcher is used to instantiate and construct each of a fragment&#39;s sections in p...
Definition: section.hpp:91