16 #ifndef PSTORE_SUPPORT_GSL_HPP 17 #define PSTORE_SUPPORT_GSL_HPP 25 #include <type_traits> 44 template <
typename CharT>
45 using basic_zstring = CharT *;
47 using zstring = basic_zstring<char>;
48 using wzstring = basic_zstring<wchar_t>;
49 using czstring = basic_zstring<char const>;
50 using cwzstring = basic_zstring<wchar_t const>;
55 constexpr
const std::ptrdiff_t dynamic_extent = -1;
57 template <
typename ElementType, std::ptrdiff_t Extent = dynamic_extent>
62 template <
typename Span,
bool IsConst>
64 using element_type =
typename Span::element_type;
67 using iterator_category = std::random_access_iterator_tag;
68 using value_type =
typename std::remove_const<element_type>::type;
69 using difference_type =
typename Span::index_type;
72 typename std::conditional<IsConst, element_type const, element_type>::type &;
73 using pointer =
typename std::add_pointer<reference>::type;
79 typename Span::index_type index) noexcept
82 PSTORE_ASSERT (span ==
nullptr || (index_ >= 0 && index <= span_->length ()));
91 template <
bool OtherIsConst = IsConst,
92 typename =
typename std::enable_if<OtherIsConst>::type>
102 template <
bool OtherIsConst = IsConst,
103 typename =
typename std::enable_if<OtherIsConst>::type>
110 reference operator* ()
const {
111 PSTORE_ASSERT (span_);
112 return (*span_)[index_];
115 pointer operator-> ()
const {
116 PSTORE_ASSERT (span_);
117 return &((*span_)[index_]);
121 PSTORE_ASSERT (span_ && index_ >= 0 && index_ < span_->length ());
133 PSTORE_ASSERT (span_ && index_ > 0 && index_ <= span_->length ());
150 PSTORE_ASSERT (span_ && (index_ + n) >= 0 && (index_ + n) <= span_->length ());
155 span_iterator & operator-= (difference_type n) noexcept {
return *
this += -n; }
161 difference_type operator- (
span_iterator const & rhs)
const {
162 PSTORE_ASSERT (span_ == rhs.span_);
163 return index_ - rhs.index_;
166 constexpr reference operator[] (difference_type n)
const noexcept {
172 return lhs.span_ == rhs.span_ && lhs.index_ == rhs.index_;
177 return !(lhs == rhs);
181 PSTORE_ASSERT (lhs.span_ == rhs.span_);
182 return lhs.index_ < rhs.index_;
201 std::swap (index_, rhs.index_);
202 std::swap (span_, rhs.span_);
206 Span
const * span_ =
nullptr;
207 std::ptrdiff_t index_ = 0;
210 template <
typename Span,
bool IsConst>
212 operator+ (
typename span_iterator<Span, IsConst>::difference_type n,
217 template <
typename Span,
bool IsConst>
219 operator- (
typename span_iterator<Span, IsConst>::difference_type n,
224 template <std::ptrdiff_t Extent>
227 using index_type = std::ptrdiff_t;
229 static_assert (Extent >= 0,
"A fixed-size span must be >= 0 in size.");
233 template <index_type Other>
236 Other == Extent || Other == dynamic_extent,
237 "Mismatch between fixed-size extent and size of initializing data.");
239 PSTORE_ASSERT (ext.size () == Extent);
242 constexpr
explicit extent_type (index_type
const size) noexcept {
244 PSTORE_ASSERT (size == Extent);
247 constexpr index_type size ()
const noexcept {
return Extent; }
253 using index_type = std::ptrdiff_t;
255 template <index_type Other>
257 : size_ (ext.size ()) {}
258 constexpr
explicit extent_type (index_type
const size) noexcept
260 PSTORE_ASSERT (size >= 0);
262 constexpr index_type size ()
const noexcept {
return size_; }
271 template <
typename ElementType, std::ptrdiff_t Extent>
275 using element_type = ElementType;
276 using index_type = std::ptrdiff_t;
277 using pointer = element_type *;
278 using reference = element_type &;
282 using reverse_iterator = std::reverse_iterator<iterator>;
283 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
285 constexpr
static index_type
const extent = Extent;
288 constexpr
span () noexcept
290 constexpr
explicit span (std::nullptr_t
const) noexcept
292 constexpr
span (pointer ptr, index_type count)
293 : storage_ (ptr, count) {}
295 constexpr span (pointer first, pointer last)
296 : storage_ (first, std::distance (first, last)) {}
300 constexpr
explicit span (element_type (&arr)[N]) noexcept
303 template <
size_t N,
class ArrayElementType = element_type>
304 constexpr
explicit span (std::array<ArrayElementType, N> & arr) noexcept
307 template <
size_t N,
class ArrayElementType = element_type>
308 constexpr
explicit span (std::array<ArrayElementType, N>
const & arr) noexcept
312 template <
typename MemberType>
313 constexpr
explicit span (std::vector<MemberType> & cont)
314 : span (cont.data (),
static_cast<index_type
> (cont.size ())) {}
316 template <
typename MemberType>
317 constexpr
explicit span (std::vector<MemberType>
const & cont)
318 : span (cont.data (),
static_cast<index_type
> (cont.size ())) {}
321 template <
typename ArrayElementType = std::add_po
inter<element_type>>
322 constexpr span (std::unique_ptr<ArrayElementType>
const & ptr, index_type count)
323 : storage_ (ptr.get (), count) {}
324 constexpr
explicit span (std::unique_ptr<element_type>
const & ptr)
325 : storage_ (ptr.get (), ptr.get () ? 1 : 0) {}
326 constexpr
explicit span (std::shared_ptr<element_type>
const & ptr)
327 : storage_ (ptr.get (), ptr.get () ? 1 : 0) {}
330 template <
typename OtherElementType, std::ptrdiff_t OtherExtent>
336 constexpr span (span
const & other) noexcept =
default;
337 constexpr span (span && other) noexcept =
default;
339 ~span () noexcept =
default;
340 span & operator= (span
const & other) noexcept =
default;
341 span & operator= (span && other) noexcept =
default;
344 template <std::ptrdiff_t Count>
346 PSTORE_ASSERT (Count >= 0 && Count <= size ());
347 return {data (), Count};
351 PSTORE_ASSERT (count >= 0 && count <= size ());
352 return {data (), count};
355 template <std::ptrdiff_t Count>
357 PSTORE_ASSERT (Count >= 0 && Count <= size ());
358 return {data () + (size () - Count), Count};
362 PSTORE_ASSERT (count >= 0 && count <= size ());
363 return {data () + (size () - count), count};
366 template <std::ptrdiff_t Offset, std::ptrdiff_t Count = dynamic_extent>
369 (Offset == 0 || (Offset > 0 && Offset <= size ())) &&
370 (Count == dynamic_extent || (Count >= 0 && Offset + Count <= size ())));
371 return {data () + Offset, Count == dynamic_extent ? size () - Offset : Count};
375 subspan (index_type
const offset, index_type
const count = dynamic_extent)
const 378 (offset == 0 || (offset > 0 && offset <= size ())) &&
379 (count == dynamic_extent || (count >= 0 && offset + count <= size ())));
380 return {data () + offset, count == dynamic_extent ? size () - offset : count};
384 constexpr index_type length ()
const noexcept {
return size (); }
385 constexpr index_type size ()
const noexcept {
return storage_.size (); }
386 constexpr index_type length_bytes ()
const noexcept {
return size_bytes (); }
387 constexpr index_type size_bytes ()
const noexcept {
388 return size () *
static_cast<index_type
> (
sizeof (element_type));
390 constexpr
bool empty ()
const noexcept {
return size () == 0; }
393 reference operator[] (index_type
const idx)
const {
394 PSTORE_ASSERT (idx >= 0 && idx < storage_.size ());
398 constexpr reference at (index_type
const idx)
const {
return this->operator[] (idx); }
399 constexpr reference operator() (index_type
const idx)
const {
400 return this->operator[] (idx);
402 constexpr pointer data ()
const noexcept {
return storage_.data (); }
405 iterator
begin ()
const noexcept {
return {
this, 0}; }
406 iterator end ()
const noexcept {
return {
this, length ()}; }
408 const_iterator cbegin ()
const noexcept {
return {
this, 0}; }
409 const_iterator cend ()
const noexcept {
return {
this, length ()}; }
411 reverse_iterator rbegin ()
const noexcept {
return reverse_iterator{end ()}; }
412 reverse_iterator rend ()
const noexcept {
return reverse_iterator{
begin ()}; }
414 const_reverse_iterator crbegin ()
const noexcept {
415 return const_reverse_iterator{cend ()};
417 const_reverse_iterator crend ()
const noexcept {
418 return const_reverse_iterator{cbegin ()};
425 template <
typename ExtentType>
426 class storage_type :
public ExtentType {
428 template <
typename OtherExtentType>
429 constexpr storage_type (pointer data, OtherExtentType ext)
433 constexpr pointer data ()
const noexcept {
return data_; }
439 storage_type<details::extent_type<Extent>> storage_;
442 template <
typename ElementType, std::ptrdiff_t Extent>
448 template <
typename ElementType, std::ptrdiff_t FirstExtent, std::ptrdiff_t SecondExtent>
452 return lhs.size () == rhs.size () &&
453 std::equal (lhs.begin (), lhs.end (), rhs.begin ());
456 template <
typename ElementType, std::ptrdiff_t Extent>
459 return !(lhs == rhs);
462 template <
typename ElementType, std::ptrdiff_t Extent>
463 constexpr
bool operator< (span<ElementType, Extent>
const & lhs,
465 return std::lexicographical_compare (lhs.begin (), lhs.end (), rhs.begin (),
469 template <
typename ElementType, std::ptrdiff_t Extent>
470 constexpr
bool operator<= (span<ElementType, Extent>
const & lhs,
475 template <
typename ElementType, std::ptrdiff_t Extent>
481 template <
typename ElementType, std::ptrdiff_t Extent>
494 template <
typename ElementType, std::ptrdiff_t Extent>
496 : std::integral_constant<std::ptrdiff_t,
497 static_cast<std::ptrdiff_t> (
498 sizeof (ElementType) *
499 static_cast<std::size_t> (Extent))> {};
501 template <
typename ElementType>
503 : std::integral_constant<std::ptrdiff_t, dynamic_extent> {};
507 template <
typename ElementType, std::ptrdiff_t Extent>
510 return {
reinterpret_cast<std::uint8_t
const *
> (s.data ()), s.size_bytes ()};
513 template <
typename ElementType, std::ptrdiff_t Extent,
514 class =
typename std::enable_if<!std::is_const<ElementType>::value>::type>
517 return {
reinterpret_cast<std::uint8_t *
> (s.data ()), s.size_bytes ()};
524 template <
typename ElementType>
526 typename span<ElementType>::index_type count) {
530 template <
typename ElementType>
535 template <
typename ElementType, std::
size_t N>
541 template <
typename ValueType, std::
size_t N>
545 template <
typename ValueType, std::
size_t N>
552 template <
typename Container>
554 return {c.data (),
static_cast<std::ptrdiff_t
> (c.size ())};
556 template <
typename Container>
558 return {c.data (),
static_cast<std::ptrdiff_t
> (c.size ())};
563 template <
typename SmartPtr>
565 return {cont, count};
568 template <
typename SmartPtr>
588 template <
typename T>
590 static_assert (std::is_assignable<T &, std::nullptr_t>::value,
591 "T cannot be assigned nullptr.");
595 constexpr
not_null (T
const t) noexcept
601 not_null (std::nullptr_t) noexcept =
delete;
610 not_null & operator= (T
const & t) noexcept {
620 constexpr T
get ()
const noexcept {
return ptr_; }
623 constexpr
operator T ()
const noexcept {
return get (); }
624 constexpr T operator-> ()
const noexcept {
return get (); }
626 bool operator== (T
const & rhs)
const noexcept {
return ptr_ == rhs; }
627 bool operator!= (T
const & rhs)
const noexcept {
return !(*
this == rhs); }
645 constexpr
void ensure_invariant ()
const noexcept { PSTORE_ASSERT (ptr_ !=
nullptr); }
652 template <
typename T,
size_t N>
653 constexpr T & at (T (&arr)[N], std::ptrdiff_t
const index) {
654 PSTORE_ASSERT (index >= 0 && index < static_cast<std::ptrdiff_t> (N));
655 return arr[
static_cast<size_t> (index)];
658 template <
typename T,
size_t N>
659 constexpr T & at (std::array<T, N> & arr, std::ptrdiff_t
const index) {
660 PSTORE_ASSERT (index >= 0 && index < static_cast<std::ptrdiff_t> (N));
661 return arr[
static_cast<size_t> (index)];
664 template <
typename Cont>
665 constexpr
typename Cont::value_type & at (Cont & cont, std::ptrdiff_t
const index) {
666 PSTORE_ASSERT (index >= 0 && index < static_cast<std::ptrdiff_t> (cont.size ()));
667 return cont[
static_cast<typename Cont::size_type
> (index)];
670 template <
typename T>
671 constexpr T
const & at (std::initializer_list<T> cont, std::ptrdiff_t
const index) {
672 PSTORE_ASSERT (index >= 0 && index < static_cast<std::ptrdiff_t> (cont.size ()));
673 return *(cont.begin () + index);
679 #endif // PSTORE_SUPPORT_GSL_HPP
An extent is a contiguous area of storage reserved for a data BLOB, represented as a range...
Definition: address.hpp:441
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: nonpod2.cpp:40
An implementation of the standard assert() macro with the exception that it will, on failure...