span.h 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. // Copyright 2019 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef CRDTP_SPAN_H_
  5. #define CRDTP_SPAN_H_
  6. #include <cstdint>
  7. #include <cstring>
  8. #include <string>
  9. #include "export.h"
  10. namespace crdtp {
  11. // =============================================================================
  12. // span - sequence of bytes
  13. // =============================================================================
  14. // This template is similar to std::span, which will be included in C++20.
  15. template <typename T>
  16. class span {
  17. public:
  18. using index_type = size_t;
  19. constexpr span() : data_(nullptr), size_(0) {}
  20. constexpr span(const T* data, index_type size) : data_(data), size_(size) {}
  21. constexpr const T* data() const { return data_; }
  22. constexpr const T* begin() const { return data_; }
  23. constexpr const T* end() const { return data_ + size_; }
  24. constexpr const T& operator[](index_type idx) const { return data_[idx]; }
  25. constexpr span<T> subspan(index_type offset, index_type count) const {
  26. return span(data_ + offset, count);
  27. }
  28. constexpr span<T> subspan(index_type offset) const {
  29. return span(data_ + offset, size_ - offset);
  30. }
  31. constexpr bool empty() const { return size_ == 0; }
  32. constexpr index_type size() const { return size_; }
  33. constexpr index_type size_bytes() const { return size_ * sizeof(T); }
  34. private:
  35. const T* data_;
  36. index_type size_;
  37. };
  38. template <size_t N>
  39. constexpr span<char> MakeSpan(const char (&str)[N]) {
  40. return span<char>(str, N - 1);
  41. }
  42. template <size_t N>
  43. constexpr span<uint8_t> SpanFrom(const char (&str)[N]) {
  44. return span<uint8_t>(reinterpret_cast<const uint8_t*>(str), N - 1);
  45. }
  46. constexpr inline span<uint8_t> SpanFrom(const char* str) {
  47. return str ? span<uint8_t>(reinterpret_cast<const uint8_t*>(str), strlen(str))
  48. : span<uint8_t>();
  49. }
  50. inline span<uint8_t> SpanFrom(const std::string& v) {
  51. return span<uint8_t>(reinterpret_cast<const uint8_t*>(v.data()), v.size());
  52. }
  53. // This SpanFrom routine works for std::vector<uint8_t> and
  54. // std::vector<uint16_t>, but also for base::span<const uint8_t> in Chromium.
  55. template <typename C,
  56. typename = std::enable_if_t<
  57. std::is_unsigned<typename C::value_type>{} &&
  58. std::is_member_function_pointer<decltype(&C::size)>{}>>
  59. inline span<typename C::value_type> SpanFrom(const C& v) {
  60. return span<typename C::value_type>(v.data(), v.size());
  61. }
  62. // Less than / equality comparison functions for sorting / searching for byte
  63. // spans.
  64. CRDTP_EXPORT bool SpanLessThan(span<uint8_t> x, span<uint8_t> y) noexcept;
  65. CRDTP_EXPORT bool SpanEquals(span<uint8_t> x, span<uint8_t> y) noexcept;
  66. // Less than / equality comparison functions for sorting / searching for byte
  67. // spans.
  68. CRDTP_EXPORT bool SpanLessThan(span<char> x, span<char> y) noexcept;
  69. CRDTP_EXPORT bool SpanEquals(span<char> x, span<char> y) noexcept;
  70. struct SpanLt {
  71. bool operator()(span<uint8_t> l, span<uint8_t> r) const {
  72. return SpanLessThan(l, r);
  73. }
  74. };
  75. } // namespace crdtp
  76. #endif // CRDTP_SPAN_H_