// Copyright (c) OpenMMLab. All rights reserved. #ifndef MMDEPLOY_SRC_CORE_MPL_SPAN_H_ #define MMDEPLOY_SRC_CORE_MPL_SPAN_H_ #include #include #include "detected.h" #include "iterator.h" namespace mmdeploy { namespace detail { template using arrow_t = decltype(std::declval().operator->()); template constexpr auto to_address(const T& p) noexcept { if constexpr (std::is_pointer_v) { return p; } else if (detail::is_detected_v) { return to_address(p.operator->()); } } } // namespace detail template class Span { public: using element_type = T; using value_type = std::remove_cv_t; using size_type = std::size_t; using difference_type = std::ptrdiff_t; using pointer = T*; using const_pointer = const T*; using reference = T&; using const_reference = const T&; using iterator = T*; using reverse_iterator = std::reverse_iterator; public: constexpr Span() noexcept : data_(nullptr), size_(0) {} // clang-format off template ()))>* = nullptr> // clang-format on constexpr Span(It first, size_type size) : data_(detail::to_address(first)), size_(size) {} template , int> = 0> constexpr Span(It first, End last) : data_(detail::to_address(first)), size_(last - first) {} template ()))>, typename = std::void_t()))>> constexpr Span(U& v) : data_(std::data(v)), size_(std::size(v)) {} template constexpr Span(element_type (&arr)[N]) noexcept : data_(std::data(arr)), size_(N) {} template constexpr Span(const Span& other) noexcept : data_(std::data(other)), size_(std::size(other)) {} constexpr iterator begin() const noexcept { return data_; } constexpr iterator end() const noexcept { return data_ + size_; } constexpr reverse_iterator rbegin() const noexcept { return std::make_reverse_iterator(end()); } constexpr reverse_iterator rend() const noexcept { return std::make_reverse_iterator(begin()); } constexpr reference front() const { return data_[0]; } constexpr reference back() const { return data_[size_ - 1]; } constexpr reference operator[](size_type idx) const { return data_[idx]; } constexpr pointer data() const noexcept { return data_; } constexpr size_type size() const noexcept { return size_; } constexpr size_type size_bytes() const noexcept { return sizeof(value_type) * size(); } constexpr bool empty() const noexcept { return size_ == 0; } constexpr Span first(size_type count) const { return {begin(), count}; } constexpr Span last(size_type count) const { return {end() - count, count}; } constexpr Span subspan(size_type offset, size_type count = -1) const { if (count == -1) { return {begin() + offset, end()}; } else { return {begin() + offset, begin() + offset + count}; } } constexpr Span& operator=(const Span& other) noexcept = default; friend bool operator==(const Span& a, const Span& b) { if (a.size() != b.size()) return false; for (size_type i = 0; i < a.size(); ++i) { if (a[i] != b[i]) { return false; } } return true; } friend bool operator!=(const Span& a, const Span& b) { return !(a == b); } private: T* data_; size_type size_; }; // clang-format off template Span(It, EndOrSize) -> Span>>; template Span(T (&)[N]) -> Span; template ().data())>, typename = std::void_t().size())>> Span(U& v) -> Span::value_type>; // clang-format on } // namespace mmdeploy #endif // MMDEPLOY_SRC_CORE_MPL_SPAN_H_