60 #ifndef PSTORE_CORE_ADDRESS_HPP 61 #define PSTORE_CORE_ADDRESS_HPP 69 #include <type_traits> 88 using offset_type = std::uint_least32_t;
89 using segment_type = std::uint_least16_t;
90 using value_type = std::uint64_t;
98 static constexpr value_type
const segment_size = value_type{max_offset} + UINT64_C (1);
100 constexpr
address () noexcept =
default;
101 explicit constexpr
address (value_type
const absolute) noexcept
103 constexpr
address (segment_type
const segment, offset_type
const offset) noexcept
104 : a_{as_absolute (segment, offset)} {}
110 value_type{max_offset}};
113 constexpr value_type absolute ()
const noexcept {
return a_; }
115 address operator++ () noexcept {
return (*
this) += 1U; }
116 address operator++ (
int) noexcept {
117 auto const old = *
this;
121 address operator-- () noexcept {
return (*
this) -= 1U; }
122 address operator-- (
int) noexcept {
123 auto const old = *
this;
128 address operator+= (value_type
const distance) noexcept {
129 PSTORE_ASSERT (a_ <= std::numeric_limits<value_type>::max () - distance);
134 address operator-= (value_type
const distance) noexcept {
135 PSTORE_ASSERT (a_ >= distance);
140 address operator|= (value_type
const mask) noexcept {
145 address operator&= (value_type
const mask) noexcept {
150 constexpr segment_type segment ()
const noexcept {
151 return static_cast<segment_type
> ((a_ >>
offset_number_bits) & value_type{max_segment});
154 constexpr offset_type offset ()
const noexcept {
155 return static_cast<offset_type
> (a_ &
max_offset);
161 static constexpr value_type as_absolute (segment_type
const segment,
162 offset_type
const offset) noexcept {
163 PSTORE_ASSERT (value_type{segment} <= max_segment + UINT64_C (1));
164 PSTORE_ASSERT (value_type{offset} <= max_offset + UINT64_C (1));
169 static_assert (
alignof (
address) == 8,
"address should be 8 byte aligned");
170 static_assert (
sizeof (
address) == 8,
"address should be 8 bytes wide");
171 static_assert (std::is_standard_layout<address>::value,
"address is not standard layout");
175 constexpr
bool operator== (
address const & lhs,
address const & rhs) noexcept {
176 return lhs.absolute () == rhs.absolute ();
178 constexpr
bool operator!= (
address const & lhs,
address const & rhs) noexcept {
179 return !operator== (lhs, rhs);
185 constexpr
bool operator> (
address const & lhs,
address const & rhs) noexcept {
186 return lhs.absolute () > rhs.absolute ();
188 constexpr
bool operator>= (
address const & lhs,
address const & rhs) noexcept {
189 return lhs.absolute () >= rhs.absolute ();
191 constexpr
bool operator< (
address const & lhs,
address const & rhs) noexcept {
192 return lhs.absolute () < rhs.absolute ();
194 constexpr
bool operator<= (
address const & lhs,
address const & rhs) noexcept {
195 return lhs.absolute () <= rhs.absolute ();
201 inline address operator- (
address const lhs, address::value_type
const rhs) noexcept {
202 PSTORE_ASSERT (lhs.absolute () >= rhs);
203 return address{lhs.absolute () - rhs};
206 PSTORE_ASSERT (lhs.absolute () >= rhs.absolute ());
207 return address{lhs.absolute () - rhs.absolute ()};
210 constexpr
address operator+ (
address const lhs, address::value_type
const rhs) noexcept {
211 return address{lhs.absolute () + rhs};
214 return address{lhs.absolute () + rhs.absolute ()};
220 constexpr
address operator| (
address const lhs, address::value_type
const rhs) noexcept {
221 return address{lhs.absolute () | rhs};
224 std::ostream & operator<< (std::ostream & os,
address const & addr);
230 template <
typename T>
233 static constexpr
unsigned total_bits = address::total_bits;
244 template <
typename Other>
251 static constexpr
typed_address make (address::value_type
const absolute) noexcept {
258 constexpr
bool operator== (
typed_address const & rhs)
const noexcept {
261 constexpr
bool operator!= (
typed_address const & rhs)
const noexcept {
262 return !operator== (rhs);
265 typed_address operator++ () noexcept {
return (*
this) += 1U; }
267 auto const old = *
this;
271 typed_address operator-- () noexcept {
return (*
this) -= 1U; }
273 auto const old = *
this;
278 typed_address operator+= (std::uint64_t
const distance) noexcept {
279 a_ += distance *
sizeof (T);
282 typed_address operator-= (std::uint64_t
const distance) noexcept {
283 a_ -= distance *
sizeof (T);
287 constexpr
address to_address ()
const noexcept {
return a_; }
288 constexpr address::value_type absolute ()
const noexcept {
return a_.absolute (); }
296 template <
typename T>
298 return lhs.to_address () > rhs.to_address ();
300 template <
typename T>
302 return lhs.to_address () >= rhs.to_address ();
304 template <
typename T>
305 constexpr
bool operator< (typed_address<T> lhs,
typed_address<T> rhs) noexcept {
306 return lhs.to_address () < rhs.to_address ();
308 template <
typename T>
309 constexpr
bool operator<= (typed_address<T> lhs,
typed_address<T> rhs) noexcept {
310 return lhs.to_address () <= rhs.to_address ();
315 template <
typename T>
317 std::uint64_t
const rhs) noexcept {
318 auto const delta = rhs *
sizeof (T);
319 PSTORE_ASSERT (lhs.absolute () >= delta);
323 template <
typename T>
325 std::uint64_t
const rhs) noexcept {
329 template <
typename T>
330 std::ostream & operator<< (std::ostream & os, typed_address<T>
const & addr) {
331 return os << addr.to_address ();
349 using base = std::numeric_limits<pstore::address::value_type>;
353 static constexpr
const bool is_specialized = base::is_specialized;
354 static constexpr
type min () noexcept {
return pstore::address::null (); }
358 static constexpr
const int digits = base::digits;
359 static constexpr
const int digits10 = base::digits10;
360 static constexpr
const int max_digits10 = base::max_digits10;
361 static constexpr
const bool is_signed = base::is_signed;
362 static constexpr
const bool is_integer = base::is_integer;
363 static constexpr
const bool is_exact = base::is_exact;
364 static constexpr
const int radix = base::radix;
366 static constexpr
type round_error () noexcept {
370 static constexpr
const int min_exponent = base::min_exponent;
371 static constexpr
const int min_exponent10 = base::min_exponent10;
372 static constexpr
const int max_exponent = base::max_exponent;
373 static constexpr
const int max_exponent10 = base::max_exponent10;
375 static constexpr
const bool has_infinity = base::has_infinity;
376 static constexpr
const bool has_quiet_NaN = base::has_quiet_NaN;
377 static constexpr
const bool has_signaling_NaN = base::has_signaling_NaN;
378 static constexpr
const float_denorm_style has_denorm = base::has_denorm;
379 static constexpr
const bool has_denorm_loss = base::has_denorm_loss;
382 static constexpr
type quiet_NaN () noexcept {
387 static constexpr
type signaling_NaN () noexcept {
391 static constexpr
type denorm_min () noexcept {
395 static constexpr
const bool is_iec559 = base::is_iec559;
396 static constexpr
const bool is_bounded = base::is_bounded;
397 static constexpr
const bool is_modulo = base::is_modulo;
399 static constexpr
const bool traps = base::traps;
400 static constexpr
const bool tinyness_before = base::tinyness_before;
401 static constexpr
const float_round_style round_style = base::round_style;
413 using result_type = std::size_t;
415 result_type operator() (argument_type
const s)
const {
416 auto const abs = s.absolute ();
417 return std::hash<std::remove_const<decltype (abs)>::type>{}(abs);
421 template <
typename T>
424 using result_type = std::size_t;
426 result_type operator() (argument_type
const s)
const {
427 auto const addr = s.to_address ();
428 return std::hash<typename std::remove_const<decltype (addr)>::type>{}(addr);
440 template <
typename T>
442 constexpr
extent () noexcept;
450 ~
extent () noexcept =
default;
461 std::uint64_t size = UINT64_C (0);
464 template <
typename T>
469 template <
typename T>
471 PSTORE_STATIC_ASSERT (offsetof (
extent, addr) == 0);
472 PSTORE_STATIC_ASSERT (offsetof (
extent, size) == 8);
473 PSTORE_STATIC_ASSERT (
sizeof (
extent) == 16);
477 template <
typename T>
479 return lhs.addr == rhs.addr && lhs.size == rhs.size;
481 template <
typename T>
483 return !(lhs == rhs);
487 template <
typename T>
488 constexpr
bool operator< (extent<T>
const & lhs,
extent<T> const & rhs) noexcept {
489 return lhs.
addr < rhs.addr || (lhs.addr == rhs.addr && lhs.size < rhs.size);
491 template <
typename T>
495 template <
typename T>
499 template <
typename T>
500 constexpr
bool operator<= (extent<T>
const & lhs,
extent<T> const & rhs) noexcept {
505 template <
typename T>
506 inline std::ostream & operator<< (std::ostream & os, extent<T>
const & r) {
507 return os <<
"{addr:" << r.
addr <<
",size:" << r.size <<
"}";
512 #endif // PSTORE_CORE_ADDRESS_HPP typed_address< T > addr
The address of the data associated with this extent.
Definition: address.hpp:456
An extent is a contiguous area of storage reserved for a data BLOB, represented as a range...
Definition: address.hpp:441
static constexpr offset_type const max_offset
The largest legal offset value.
Definition: address.hpp:93
Definition: address.hpp:81
static constexpr segment_type const max_segment
The largest legal segment value.
Definition: address.hpp:96
Definition: chunked_sequence.hpp:607
Definition: address.hpp:231
static constexpr unsigned segment_number_bits
A segment number is 0-2^16.
Definition: address.hpp:85
constexpr extent(typed_address< T > const a, std::uint64_t const s) noexcept
Definition: address.hpp:445
static constexpr unsigned offset_number_bits
An offset is 0-2^22 (4 megabytes)
Definition: address.hpp:83
Definition: nonpod2.cpp:40
static constexpr address max() noexcept
The largest legal absolute address.
Definition: address.hpp:108
An implementation of the standard assert() macro with the exception that it will, on failure...
static constexpr value_type const segment_size
The number of bytes in a segment.
Definition: address.hpp:98