MCPcopy Create free account
hub / github.com/ashvardanian/less_slow.cpp / strided_ptr

Class strided_ptr

less_slow.cpp:2815–2859  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

2813 */
2814template <typename value_type_>
2815class strided_ptr {
2816 std::byte *data_;
2817 std::size_t stride_;
2818
2819 public:
2820 using value_type = value_type_;
2821 using pointer = value_type_ *;
2822 using reference = value_type_ &;
2823 using difference_type = std::ptrdiff_t;
2824 using iterator_category = std::random_access_iterator_tag;
2825
2826 strided_ptr(std::byte *data, std::size_t stride_bytes) : data_(data), stride_(stride_bytes) {
2827 assert(data_ && "Pointer must not be null, as NULL arithmetic is undefined");
2828 }
2829#if defined(__cpp_lib_assume_aligned) // Not available in Apple Clang
2830 reference operator*() const noexcept {
2831 return *std::launder(std::assume_aligned<1>(reinterpret_cast<pointer>(data_)));
2832 }
2833 reference operator[](difference_type i) const noexcept {
2834 return *std::launder(std::assume_aligned<1>(reinterpret_cast<pointer>(data_ + i * stride_)));
2835 }
2836#else
2837 reference operator*() const noexcept { return *reinterpret_cast<pointer>(data_); }
2838 reference operator[](difference_type i) const noexcept { return *reinterpret_cast<pointer>(data_ + i * stride_); }
2839#endif // defined(__cpp_lib_assume_aligned)
2840
2841 // clang-format off
2842 pointer operator->() const noexcept { return &operator*(); }
2843 strided_ptr &operator++() noexcept { data_ += stride_; return *this; }
2844 strided_ptr operator++(int) noexcept { strided_ptr temp = *this; ++(*this); return temp; }
2845 strided_ptr &operator--() noexcept { data_ -= stride_; return *this; }
2846 strided_ptr operator--(int) noexcept { strided_ptr temp = *this; --(*this); return temp; }
2847 strided_ptr &operator+=(difference_type offset) noexcept { data_ += offset * stride_; return *this; }
2848 strided_ptr &operator-=(difference_type offset) noexcept { data_ -= offset * stride_; return *this; }
2849 strided_ptr operator+(difference_type offset) const noexcept { strided_ptr temp = *this; return temp += offset; }
2850 strided_ptr operator-(difference_type offset) const noexcept { strided_ptr temp = *this; return temp -= offset; }
2851 friend difference_type operator-(strided_ptr const &a, strided_ptr const &b) noexcept { assert(a.stride_ == b.stride_); return (a.data_ - b.data_) / static_cast<difference_type>(a.stride_); }
2852 friend bool operator==(strided_ptr const &a, strided_ptr const &b) noexcept { return a.data_ == b.data_; }
2853 friend bool operator<(strided_ptr const &a, strided_ptr const &b) noexcept { return a.data_ < b.data_; }
2854 friend bool operator!=(strided_ptr const &a, strided_ptr const &b) noexcept { return !(a == b); }
2855 friend bool operator>(strided_ptr const &a, strided_ptr const &b) noexcept { return b < a; }
2856 friend bool operator<=(strided_ptr const &a, strided_ptr const &b) noexcept { return !(b < a); }
2857 friend bool operator>=(strided_ptr const &a, strided_ptr const &b) noexcept { return !(a < b); }
2858 // clang-format on
2859};
2860
2861#if defined(__aarch64__)
2862/**

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected