🛠️🐜 Antkeeper superbuild with dependencies included https://antkeeper.com
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

107 lines
3.5 KiB

  1. #ifndef AL_SPAN_H
  2. #define AL_SPAN_H
  3. #include <cstddef>
  4. #include <array>
  5. #include <type_traits>
  6. #include <initializer_list>
  7. namespace al {
  8. template<typename T>
  9. constexpr auto size(T &cont) -> decltype(cont.size())
  10. { return cont.size(); }
  11. template<typename T>
  12. constexpr auto size(const T &cont) -> decltype(cont.size())
  13. { return cont.size(); }
  14. template<typename T, size_t N>
  15. constexpr size_t size(T (&)[N]) noexcept
  16. { return N; }
  17. template<typename T>
  18. constexpr size_t size(std::initializer_list<T> list) noexcept
  19. { return list.size(); }
  20. template<typename T>
  21. constexpr auto data(T &cont) -> decltype(cont.data())
  22. { return cont.data(); }
  23. template<typename T>
  24. constexpr auto data(const T &cont) -> decltype(cont.data())
  25. { return cont.data(); }
  26. template<typename T, size_t N>
  27. constexpr T* data(T (&arr)[N]) noexcept
  28. { return arr; }
  29. template<typename T>
  30. constexpr const T* data(std::initializer_list<T> list) noexcept
  31. { return list.begin(); }
  32. template<typename T>
  33. class span {
  34. public:
  35. using element_type = T;
  36. using value_type = typename std::remove_cv<T>::type;
  37. using index_type = size_t;
  38. using difference_type = ptrdiff_t;
  39. using pointer = T*;
  40. using const_pointer = const T*;
  41. using reference = T&;
  42. using const_reference = const T&;
  43. using iterator = pointer;
  44. using const_iterator = const_pointer;
  45. using reverse_iterator = std::reverse_iterator<iterator>;
  46. using const_reverse_iterator = std::reverse_iterator<const_iterator>;
  47. constexpr span() noexcept = default;
  48. constexpr span(pointer ptr, index_type count) : mData{ptr}, mCount{count} { }
  49. constexpr span(pointer first, pointer last) : mData{first}, mCount{std::distance(first, last)} { }
  50. template<size_t N>
  51. constexpr span(element_type (&arr)[N]) noexcept : span{al::data(arr), al::size(arr)} { }
  52. template<size_t N>
  53. constexpr span(std::array<value_type,N> &arr) noexcept : span{al::data(arr), al::size(arr)} { }
  54. template<size_t N>
  55. constexpr span(const std::array<value_type,N> &arr) noexcept : span{al::data(arr), al::size(arr)} { }
  56. template<typename U>
  57. constexpr span(U &cont) : span{al::data(cont), al::size(cont)} { }
  58. template<typename U>
  59. constexpr span(const U &cont) : span{al::data(cont), al::size(cont)} { }
  60. constexpr span(const span&) noexcept = default;
  61. span& operator=(const span &rhs) noexcept = default;
  62. constexpr reference front() const { return mData[0]; }
  63. constexpr reference back() const { return mData[mCount-1]; }
  64. constexpr reference operator[](index_type idx) const { return mData[idx]; }
  65. constexpr pointer data() const noexcept { return mData; }
  66. constexpr index_type size() const noexcept { return mCount; }
  67. constexpr index_type size_bytes() const noexcept { return mCount * sizeof(value_type); }
  68. constexpr bool empty() const noexcept { return mCount == 0; }
  69. constexpr iterator begin() const noexcept { return mData; }
  70. constexpr iterator end() const noexcept { return mData + mCount; }
  71. constexpr const_iterator cbegin() const noexcept { return mData; }
  72. constexpr const_iterator cend() const noexcept { return mData + mCount; }
  73. constexpr reverse_iterator rbegin() const noexcept { return end(); }
  74. constexpr reverse_iterator rend() const noexcept { return begin(); }
  75. constexpr const_reverse_iterator crbegin() const noexcept { return cend(); }
  76. constexpr const_reverse_iterator crend() const noexcept { return cbegin(); }
  77. private:
  78. pointer mData{nullptr};
  79. index_type mCount{0u};
  80. };
  81. } // namespace al
  82. #endif /* AL_SPAN_H */