1 // Copyright 2024 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef BASE_CONTAINERS_SPAN_OR_SIZE_H_ 6 #define BASE_CONTAINERS_SPAN_OR_SIZE_H_ 7 8 #include <stddef.h> 9 10 #include <variant> 11 12 #include "base/containers/span.h" 13 #include "base/functional/overloaded.h" 14 #include "base/types/optional_ref.h" 15 16 namespace base { 17 18 // `SpanOrSize<T>` contains either a `span<T>` or just the size of data. This 19 // is useful if the data is not retained in some scenarios, but size needs to be 20 // available in all the scenarios. 21 template <typename T> 22 class SpanOrSize { 23 public: SpanOrSize(base::span<T> span)24 explicit constexpr SpanOrSize(base::span<T> span) : span_or_size_(span) {} SpanOrSize(size_t size)25 explicit constexpr SpanOrSize(size_t size) : span_or_size_(size) {} 26 27 ~SpanOrSize() = default; 28 29 // `SpanOrSize` is copyable and movable (just like `span` and `size_t`). 30 SpanOrSize(const SpanOrSize&) = default; 31 SpanOrSize& operator=(const SpanOrSize&) = default; 32 SpanOrSize(SpanOrSize&&) = default; 33 SpanOrSize& operator=(SpanOrSize&&) = default; 34 ptr_or_null_if_no_data()35 constexpr T* ptr_or_null_if_no_data() const { 36 return std::visit(Overloaded{ 37 [](const base::span<T>& span) { return span.data(); }, 38 [](size_t size) -> T* { return nullptr; }, 39 }, 40 span_or_size_); 41 } 42 size()43 constexpr size_t size() const { 44 return std::visit(Overloaded{ 45 [](const base::span<T>& span) { return span.size(); }, 46 [](size_t size) { return size; }, 47 }, 48 span_or_size_); 49 } 50 span()51 constexpr optional_ref<const base::span<T>> span() const { 52 return std::visit( 53 Overloaded{ 54 [](const base::span<T>& span) { 55 return optional_ref<const base::span<T>>(span); 56 }, 57 [](size_t size) { return optional_ref<const base::span<T>>(); }, 58 }, 59 span_or_size_); 60 } 61 62 private: 63 std::variant<base::span<T>, size_t> span_or_size_; 64 }; 65 66 } // namespace base 67 68 #endif // BASE_CONTAINERS_SPAN_OR_SIZE_H_ 69