| // Copyright 2019 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef V8_CRDTP_SPAN_H_ |
| #define V8_CRDTP_SPAN_H_ |
| |
| #include <cstdint> |
| #include <cstring> |
| #include <string> |
| |
| #include "export.h" |
| |
| namespace v8_crdtp { |
| // ============================================================================= |
| // span - sequence of bytes |
| // ============================================================================= |
| |
| // This template is similar to std::span, which will be included in C++20. |
| template <typename T> |
| class span { |
| public: |
| using index_type = size_t; |
| |
| constexpr span() : data_(nullptr), size_(0) {} |
| constexpr span(const T* data, index_type size) : data_(data), size_(size) {} |
| |
| constexpr const T* data() const { return data_; } |
| |
| constexpr const T* begin() const { return data_; } |
| constexpr const T* end() const { return data_ + size_; } |
| |
| constexpr const T& operator[](index_type idx) const { return data_[idx]; } |
| |
| constexpr span<T> subspan(index_type offset, index_type count) const { |
| return span(data_ + offset, count); |
| } |
| |
| constexpr span<T> subspan(index_type offset) const { |
| return span(data_ + offset, size_ - offset); |
| } |
| |
| constexpr bool empty() const { return size_ == 0; } |
| |
| constexpr index_type size() const { return size_; } |
| constexpr index_type size_bytes() const { return size_ * sizeof(T); } |
| |
| private: |
| const T* data_; |
| index_type size_; |
| }; |
| |
| template <size_t N> |
| constexpr span<char> MakeSpan(const char (&str)[N]) { |
| return span<char>(str, N - 1); |
| } |
| |
| template <size_t N> |
| constexpr span<uint8_t> SpanFrom(const char (&str)[N]) { |
| return span<uint8_t>(reinterpret_cast<const uint8_t*>(str), N - 1); |
| } |
| |
| constexpr inline span<uint8_t> SpanFrom(const char* str) { |
| return str ? span<uint8_t>(reinterpret_cast<const uint8_t*>(str), strlen(str)) |
| : span<uint8_t>(); |
| } |
| |
| inline span<uint8_t> SpanFrom(const std::string& v) { |
| return span<uint8_t>(reinterpret_cast<const uint8_t*>(v.data()), v.size()); |
| } |
| |
| // This SpanFrom routine works for std::vector<uint8_t> and |
| // std::vector<uint16_t>, but also for base::span<const uint8_t> in Chromium. |
| template <typename C, |
| typename = std::enable_if_t< |
| std::is_unsigned<typename C::value_type>{} && |
| std::is_member_function_pointer<decltype(&C::size)>{}>> |
| inline span<typename C::value_type> SpanFrom(const C& v) { |
| return span<typename C::value_type>(v.data(), v.size()); |
| } |
| |
| // Less than / equality comparison functions for sorting / searching for byte |
| // spans. |
| bool SpanLessThan(span<uint8_t> x, span<uint8_t> y) noexcept; |
| bool SpanEquals(span<uint8_t> x, span<uint8_t> y) noexcept; |
| |
| // Less than / equality comparison functions for sorting / searching for byte |
| // spans. |
| bool SpanLessThan(span<char> x, span<char> y) noexcept; |
| bool SpanEquals(span<char> x, span<char> y) noexcept; |
| |
| struct SpanLt { |
| bool operator()(span<uint8_t> l, span<uint8_t> r) const { |
| return SpanLessThan(l, r); |
| } |
| }; |
| } // namespace v8_crdtp |
| |
| #endif // V8_CRDTP_SPAN_H_ |