| Message ID | 20260831132312.619946-4-barnabas.pocze@ideasonboard.com |
|---|---|
| State | Superseded |
| Headers | show |
| Series |
|
| Related | show |
Quoting Barnabás Pőcze (2026-08-31 14:23:12) > With the switch to C++20, this type has largely become unnecessary, > so remove it, but leave a deprecated alias instructing users to use > `std::span`. > > Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com> > --- > include/libcamera/base/span.h | 405 +--------------------------------- > test/meson.build | 1 - > test/span.cpp | 205 ----------------- > 3 files changed, 5 insertions(+), 606 deletions(-) > delete mode 100644 test/span.cpp > > diff --git a/include/libcamera/base/span.h b/include/libcamera/base/span.h > index 5c7a98d8e7..ca10aa2954 100644 > --- a/include/libcamera/base/span.h > +++ b/include/libcamera/base/span.h > @@ -7,408 +7,13 @@ > > #pragma once > > +namespace libcamera { > > +template<typename T, std::size_t Extent = std::dynamic_extent> > +using Span [[deprecated("use std::span instead")]] = std::span<T, Extent>; > > } /* namespace libcamera */ Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Hi Barnabás, Thank you for the patch. On Mon, Aug 31, 2026 at 03:23:12PM +0200, Barnabás Pőcze wrote: > With the switch to C++20, this type has largely become unnecessary, > so remove it, but leave a deprecated alias instructing users to use > `std::span`. > > Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> > --- > include/libcamera/base/span.h | 405 +--------------------------------- > test/meson.build | 1 - > test/span.cpp | 205 ----------------- > 3 files changed, 5 insertions(+), 606 deletions(-) > delete mode 100644 test/span.cpp > > diff --git a/include/libcamera/base/span.h b/include/libcamera/base/span.h > index 5c7a98d8e7..ca10aa2954 100644 > --- a/include/libcamera/base/span.h > +++ b/include/libcamera/base/span.h > @@ -7,408 +7,13 @@ > > #pragma once > > -#include <array> > -#include <iterator> > -#include <limits> > -#include <type_traits> > +#include <span> > > -namespace libcamera { > - > -static constexpr std::size_t dynamic_extent = std::numeric_limits<std::size_t>::max(); > - > -template<typename T, std::size_t Extent = dynamic_extent> > -class Span; > - > -namespace details { > - > -template<typename U> > -struct is_array : public std::false_type { > -}; > - > -template<typename U, std::size_t N> > -struct is_array<std::array<U, N>> : public std::true_type { > -}; > - > -template<typename U> > -struct is_libcamera_span : public std::false_type { > -}; > - > -template<typename U, std::size_t Extent> > -struct is_libcamera_span<Span<U, Extent>> : public std::true_type { > -}; > - > -} /* namespace details */ > - > -namespace utils { > - > -template<typename C> > -constexpr auto size(const C &c) -> decltype(c.size()) > -{ > - return c.size(); > -} > - > -template<typename C> > -constexpr auto data(const C &c) -> decltype(c.data()) > -{ > - return c.data(); > -} > - > -template<typename C> > -constexpr auto data(C &c) -> decltype(c.data()) > -{ > - return c.data(); > -} > - > -template<class T, std::size_t N> > -constexpr T *data(T (&array)[N]) noexcept > -{ > - return array; > -} > - > -template<std::size_t I, typename T> > -struct tuple_element; > - > -template<std::size_t I, typename T, std::size_t N> > -struct tuple_element<I, Span<T, N>> { > - using type = T; > -}; > - > -template<typename T> > -struct tuple_size; > - > -template<typename T, std::size_t N> > -struct tuple_size<Span<T, N>> : public std::integral_constant<std::size_t, N> { > -}; > - > -template<typename T> > -struct tuple_size<Span<T, dynamic_extent>>; > - > -} /* namespace utils */ > - > -template<typename T, std::size_t Extent> > -class Span > -{ > -public: > - using element_type = T; > - using value_type = typename std::remove_cv_t<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 = pointer; > - using const_iterator = const_pointer; > - using reverse_iterator = std::reverse_iterator<iterator>; > - using const_reverse_iterator = std::reverse_iterator<const_iterator>; > - > - static constexpr std::size_t extent = Extent; > - > - template<bool Dependent = false, > - typename = std::enable_if_t<Dependent || Extent == 0>> > - constexpr Span() noexcept > - : data_(nullptr) > - { > - } > - > - explicit constexpr Span(pointer ptr, [[maybe_unused]] size_type count) > - : data_(ptr) > - { > - } > - > - explicit constexpr Span(pointer first, [[maybe_unused]] pointer last) > - : data_(first) > - { > - } > - > - template<std::size_t N> > - constexpr Span(element_type (&arr)[N], > - std::enable_if_t<std::is_convertible<std::remove_pointer_t<decltype(utils::data(arr))> (*)[], > - element_type (*)[]>::value && > - N == Extent, > - std::nullptr_t> = nullptr) noexcept > - : data_(arr) > - { > - } > - > - template<std::size_t N> > - constexpr Span(std::array<value_type, N> &arr, > - std::enable_if_t<std::is_convertible<std::remove_pointer_t<decltype(utils::data(arr))> (*)[], > - element_type (*)[]>::value && > - N == Extent, > - std::nullptr_t> = nullptr) noexcept > - : data_(arr.data()) > - { > - } > - > - template<std::size_t N> > - constexpr Span(const std::array<value_type, N> &arr, > - std::enable_if_t<std::is_convertible<std::remove_pointer_t<decltype(utils::data(arr))> (*)[], > - element_type (*)[]>::value && > - N == Extent, > - std::nullptr_t> = nullptr) noexcept > - : data_(arr.data()) > - { > - } > - > - template<class Container> > - explicit constexpr Span(Container &cont, > - std::enable_if_t<!details::is_libcamera_span<Container>::value && > - !details::is_array<Container>::value && > - !std::is_array<Container>::value && > - std::is_convertible<std::remove_pointer_t<decltype(utils::data(cont))> (*)[], > - element_type (*)[]>::value, > - std::nullptr_t> = nullptr) > - : data_(utils::data(cont)) > - { > - } > - > - template<class Container> > - explicit constexpr Span(const Container &cont, > - std::enable_if_t<!details::is_libcamera_span<Container>::value && > - !details::is_array<Container>::value && > - !std::is_array<Container>::value && > - std::is_convertible<std::remove_pointer_t<decltype(utils::data(cont))> (*)[], > - element_type (*)[]>::value, > - std::nullptr_t> = nullptr) > - : data_(utils::data(cont)) > - { > - static_assert(utils::size(cont) == Extent, "Size mismatch"); > - } > - > - template<class U, std::size_t N> > - explicit constexpr Span(const Span<U, N> &s, > - std::enable_if_t<std::is_convertible<U (*)[], element_type (*)[]>::value && > - N == Extent, > - std::nullptr_t> = nullptr) noexcept > - : data_(s.data()) > - { > - } > - > - constexpr Span(const Span &other) noexcept = default; > - constexpr Span &operator=(const Span &other) noexcept = default; > +/* \todo Remove this header. */ > > - constexpr iterator begin() const { return data(); } > - constexpr const_iterator cbegin() const { return begin(); } > - constexpr iterator end() const { return data() + size(); } > - constexpr const_iterator cend() const { return end(); } > - constexpr reverse_iterator rbegin() const { return reverse_iterator(end()); } > - constexpr const_reverse_iterator crbegin() const { return rbegin(); } > - constexpr reverse_iterator rend() const { return reverse_iterator(begin()); } > - constexpr const_reverse_iterator crend() const { return rend(); } > - > - constexpr reference front() const { return *data(); } > - 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 Extent; } > - constexpr size_type size_bytes() const noexcept { return size() * sizeof(element_type); } > - constexpr bool empty() const noexcept { return size() == 0; } > - > - template<std::size_t Count> > - constexpr Span<element_type, Count> first() const > - { > - static_assert(Count <= Extent, "Count larger than size"); > - return Span<element_type, Count>{ data(), Count }; > - } > - > - constexpr Span<element_type, dynamic_extent> first(std::size_t Count) const > - { > - return Span<element_type, dynamic_extent>{ data(), Count }; > - } > - > - template<std::size_t Count> > - constexpr Span<element_type, Count> last() const > - { > - static_assert(Count <= Extent, "Count larger than size"); > - return Span<element_type, Count>{ data() + size() - Count, Count }; > - } > - > - constexpr Span<element_type, dynamic_extent> last(std::size_t Count) const > - { > - return Span<element_type, dynamic_extent>{ data() + size() - Count, Count }; > - } > - > - template<std::size_t Offset, std::size_t Count = dynamic_extent> > - constexpr Span<element_type, Count != dynamic_extent ? Count : Extent - Offset> subspan() const > - { > - static_assert(Offset <= Extent, "Offset larger than size"); > - static_assert(Count == dynamic_extent || Count + Offset <= Extent, > - "Offset + Count larger than size"); > - return Span<element_type, Count != dynamic_extent ? Count : Extent - Offset>{ > - data() + Offset, > - Count == dynamic_extent ? size() - Offset : Count > - }; > - } > - > - constexpr Span<element_type, dynamic_extent> > - subspan(std::size_t Offset, std::size_t Count = dynamic_extent) const > - { > - return Span<element_type, dynamic_extent>{ > - data() + Offset, > - Count == dynamic_extent ? size() - Offset : Count > - }; > - } > - > -private: > - pointer data_; > -}; > - > -template<typename T> > -class Span<T, dynamic_extent> > -{ > -public: > - using element_type = T; > - using value_type = typename std::remove_cv_t<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 const_iterator = const T *; > - using reverse_iterator = std::reverse_iterator<iterator>; > - using const_reverse_iterator = std::reverse_iterator<const_iterator>; > - > - static constexpr std::size_t extent = dynamic_extent; > - > - constexpr Span() noexcept > - : data_(nullptr), size_(0) > - { > - } > - > - constexpr Span(pointer ptr, size_type count) > - : data_(ptr), size_(count) > - { > - } > - > - constexpr Span(pointer first, pointer last) > - : data_(first), size_(last - first) > - { > - } > - > - template<std::size_t N> > - constexpr Span(element_type (&arr)[N], > - std::enable_if_t<std::is_convertible<std::remove_pointer_t<decltype(utils::data(arr))> (*)[], > - element_type (*)[]>::value, > - std::nullptr_t> = nullptr) noexcept > - : data_(arr), size_(N) > - { > - } > - > - template<std::size_t N> > - constexpr Span(std::array<value_type, N> &arr, > - std::enable_if_t<std::is_convertible<std::remove_pointer_t<decltype(utils::data(arr))> (*)[], > - element_type (*)[]>::value, > - std::nullptr_t> = nullptr) noexcept > - : data_(utils::data(arr)), size_(N) > - { > - } > - > - template<std::size_t N> > - constexpr Span(const std::array<value_type, N> &arr) noexcept > - : data_(utils::data(arr)), size_(N) > - { > - } > - > - template<class Container> > - constexpr Span(Container &cont, > - std::enable_if_t<!details::is_libcamera_span<Container>::value && > - !details::is_array<Container>::value && > - !std::is_array<Container>::value && > - std::is_convertible<std::remove_pointer_t<decltype(utils::data(cont))> (*)[], > - element_type (*)[]>::value, > - std::nullptr_t> = nullptr) > - : data_(utils::data(cont)), size_(utils::size(cont)) > - { > - } > - > - template<class Container> > - constexpr Span(const Container &cont, > - std::enable_if_t<!details::is_libcamera_span<Container>::value && > - !details::is_array<Container>::value && > - !std::is_array<Container>::value && > - std::is_convertible<std::remove_pointer_t<decltype(utils::data(cont))> (*)[], > - element_type (*)[]>::value, > - std::nullptr_t> = nullptr) > - : data_(utils::data(cont)), size_(utils::size(cont)) > - { > - } > - > - template<class U, std::size_t N> > - constexpr Span(const Span<U, N> &s, > - std::enable_if_t<std::is_convertible<U (*)[], element_type (*)[]>::value, > - std::nullptr_t> = nullptr) noexcept > - : data_(s.data()), size_(s.size()) > - { > - } > - > - constexpr Span(const Span &other) noexcept = default; > - constexpr Span &operator=(const Span &other) noexcept = default; > - > - constexpr iterator begin() const { return data(); } > - constexpr const_iterator cbegin() const { return begin(); } > - constexpr iterator end() const { return data() + size(); } > - constexpr const_iterator cend() const { return end(); } > - constexpr reverse_iterator rbegin() const { return reverse_iterator(end()); } > - constexpr const_reverse_iterator crbegin() const { return rbegin(); } > - constexpr reverse_iterator rend() const { return reverse_iterator(begin()); } > - constexpr const_reverse_iterator crend() const { return rend(); } > - > - constexpr reference front() const { return *data(); } > - 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 size() * sizeof(element_type); } > - constexpr bool empty() const noexcept { return size() == 0; } > - > - template<std::size_t Count> > - constexpr Span<element_type, Count> first() const > - { > - return Span<element_type, Count>{ data(), Count }; > - } > - > - constexpr Span<element_type, dynamic_extent> first(std::size_t Count) const > - { > - return { data(), Count }; > - } > - > - template<std::size_t Count> > - constexpr Span<element_type, Count> last() const > - { > - return Span<element_type, Count>{ data() + size() - Count, Count }; > - } > - > - constexpr Span<element_type, dynamic_extent> last(std::size_t Count) const > - { > - return Span<element_type, dynamic_extent>{ data() + size() - Count, Count }; > - } > - > - template<std::size_t Offset, std::size_t Count = dynamic_extent> > - constexpr Span<element_type, Count> subspan() const > - { > - return Span<element_type, Count>{ > - data() + Offset, > - Count == dynamic_extent ? size() - Offset : Count > - }; > - } > - > - constexpr Span<element_type, dynamic_extent> > - subspan(std::size_t Offset, std::size_t Count = dynamic_extent) const > - { > - return Span<element_type, dynamic_extent>{ > - data() + Offset, > - Count == dynamic_extent ? size() - Offset : Count > - }; > - } > +namespace libcamera { > > -private: > - pointer data_; > - size_type size_; > -}; > +template<typename T, std::size_t Extent = std::dynamic_extent> > +using Span [[deprecated("use std::span instead")]] = std::span<T, Extent>; > > } /* namespace libcamera */ > diff --git a/test/meson.build b/test/meson.build > index e4450625ee..363a2829d8 100644 > --- a/test/meson.build > +++ b/test/meson.build > @@ -45,7 +45,6 @@ public_tests = [ > {'name': 'geometry', 'sources': ['geometry.cpp']}, > {'name': 'public-api', 'sources': ['public-api.cpp']}, > {'name': 'signal', 'sources': ['signal.cpp']}, > - {'name': 'span', 'sources': ['span.cpp']}, > {'name': 'transform', 'sources': ['transform.cpp']}, > ] > > diff --git a/test/span.cpp b/test/span.cpp > deleted file mode 100644 > index 4b9f3279ad..0000000000 > --- a/test/span.cpp > +++ /dev/null > @@ -1,205 +0,0 @@ > -/* SPDX-License-Identifier: GPL-2.0-or-later */ > -/* > - * Copyright (C) 2020, Google Inc. > - * > - * Span tests > - */ > - > -/* > - * Include first to ensure the header is self-contained, as there's no span.cpp > - * in libcamera. > - */ > -#include <libcamera/base/span.h> > - > -#include <array> > -#include <iostream> > -#include <vector> > - > -#include "test.h" > - > -using namespace std; > -using namespace libcamera; > - > -class SpanTest : public Test > -{ > -protected: > - int run() > - { > - int i[4]{ 1, 2, 3, 4 }; > - std::array<int, 4> a{ 1, 2, 3, 4 }; > - const std::array<int, 4> ca{ 1, 2, 3, 4 }; > - std::vector<int> v{ 1, 2, 3, 4 }; > - const std::vector<int> cv{ 1, 2, 3, 4 }; > - > - /* > - * Compile-test construction and usage of spans with static > - * extent. Commented-out tests are expected not to compile, or > - * to generate undefined behaviour. > - */ > - > - Span<int, 0>{}; > - /* Span<int, 4>{}; */ > - > - Span<int, 4>{ &i[0], 4 }; > - Span<int, 4>{ &i[0], &i[3] }; > - > - Span<int, 4>{ i }; > - /* Span<float, 4>{ i }; */ > - /* Span<int, 2>{ i }; */ > - > - Span<int, 4>{ a }; > - Span<const int, 4>{ a }; > - /* Span<float, 4>{ a }; */ > - /* Span<int, 2>{ a }; */ > - > - Span<const int, 4>{ ca }; > - /* Span<const int, 2>{ ca }; */ > - /* Span<const float, 4>{ ca }; */ > - /* Span<int, 4>{ ca }; */ > - > - Span<int, 4>{ v }; > - Span<const int, 4>{ v }; > - /* Span<float, 4>{ v }; */ > - > - Span<const int, 4>{ v }; > - /* Span<int, 4>{ v }; */ > - /* Span<const float, 4>{ v }; */ > - > - Span<int, 4> staticSpan{ i }; > - Span<int, 4>{ staticSpan }; > - Span<const int, 4>{ staticSpan }; > - /* Span<const int, 2>{ staticSpan }; */ > - > - staticSpan = Span<int, 4>{ v }; > - > - if (*staticSpan.begin() != 1) { > - std::cout << "Span<static_extent>::begin() failed" << std::endl; > - return TestFail; > - } > - if (*staticSpan.cbegin() != 1) { > - std::cout << "Span<static_extent>::cbegin() failed" << std::endl; > - return TestFail; > - } > - staticSpan.end(); > - staticSpan.cend(); > - if (*staticSpan.rbegin() != 4) { > - std::cout << "Span<static_extent>::rbegin() failed" << std::endl; > - return TestFail; > - } > - if (*staticSpan.crbegin() != 4) { > - std::cout << "Span<static_extent>::crbegin() failed" << std::endl; > - return TestFail; > - } > - staticSpan.rend(); > - staticSpan.crend(); > - > - staticSpan.front(); > - staticSpan.back(); > - staticSpan[0]; > - staticSpan.data(); > - > - staticSpan.size(); > - staticSpan.size_bytes(); > - > - staticSpan.empty(); > - > - staticSpan.first<2>(); > - staticSpan.first(2); > - /* staticSpan.first<6>(); */ > - /* staticSpan.first(6); */ > - staticSpan.last<2>(); > - staticSpan.last(2); > - /* staticSpan.last<6>(); */ > - /* staticSpan.last(6); */ > - staticSpan.subspan<1>(); > - staticSpan.subspan<1, 2>(); > - staticSpan.subspan(1); > - staticSpan.subspan(1, 2); > - /* staticSpan.subspan(2, 4); */ > - > - /* > - * Compile-test construction and usage of spans with dynamic > - * extent. Commented-out tests are expected not to compile, or > - * to generate undefined behaviour. > - */ > - > - Span<int>{}; > - > - Span<int>{ &i[0], 4 }; > - Span<int>{ &i[0], &i[3] }; > - > - Span<int>{ i }; > - /* Span<float>{ i }; */ > - > - Span<int>{ a }; > - Span<const int>{ a }; > - /* Span<float>{ a }; */ > - > - Span<const int>{ ca }; > - /* Span<const float>{ca}; */ > - /* Span<int>{ca}; */ > - > - Span<int>{ v }; > - Span<const int>{ v }; > - /* Span<float>{ v }; */ > - > - Span<const int>{ cv }; > - /* Span<int>{ cv }; */ > - /* Span<const float>{ cv }; */ > - > - Span<int> dynamicSpan{ i }; > - Span<int>{ dynamicSpan }; > - Span<const int>{ dynamicSpan }; > - > - dynamicSpan = Span<int>{ a }; > - > - if (*dynamicSpan.begin() != 1) { > - std::cout << "Span<dynamic_extent>::begin() failed" << std::endl; > - return TestFail; > - } > - if (*dynamicSpan.cbegin() != 1) { > - std::cout << "Span<dynamic_extent>::cbegin() failed" << std::endl; > - return TestFail; > - } > - dynamicSpan.end(); > - dynamicSpan.cend(); > - if (*dynamicSpan.rbegin() != 4) { > - std::cout << "Span<dynamic_extent>::rbegin() failed" << std::endl; > - return TestFail; > - } > - if (*dynamicSpan.crbegin() != 4) { > - std::cout << "Span<dynamic_extent>::crbegin() failed" << std::endl; > - return TestFail; > - } > - dynamicSpan.rend(); > - dynamicSpan.crend(); > - > - dynamicSpan.front(); > - dynamicSpan.back(); > - dynamicSpan[0]; > - dynamicSpan.data(); > - > - dynamicSpan.size(); > - dynamicSpan.size_bytes(); > - > - dynamicSpan.empty(); > - > - dynamicSpan.first<2>(); > - dynamicSpan.first(2); > - /* dynamicSpan.first<6>(); */ > - /* dynamicSpan.first(6); */ > - dynamicSpan.last<2>(); > - dynamicSpan.last(2); > - /* dynamicSpan.last<6>(); */ > - /* dynamicSpan.last(6); */ > - dynamicSpan.subspan<1>(); > - dynamicSpan.subspan<1, 2>(); > - dynamicSpan.subspan(1); > - dynamicSpan.subspan(1, 2); > - /* dynamicSpan.subspan(2, 4); */ > - > - return TestPass; > - } > -}; > - > -TEST_REGISTER(SpanTest)
diff --git a/include/libcamera/base/span.h b/include/libcamera/base/span.h index 5c7a98d8e7..ca10aa2954 100644 --- a/include/libcamera/base/span.h +++ b/include/libcamera/base/span.h @@ -7,408 +7,13 @@ #pragma once -#include <array> -#include <iterator> -#include <limits> -#include <type_traits> +#include <span> -namespace libcamera { - -static constexpr std::size_t dynamic_extent = std::numeric_limits<std::size_t>::max(); - -template<typename T, std::size_t Extent = dynamic_extent> -class Span; - -namespace details { - -template<typename U> -struct is_array : public std::false_type { -}; - -template<typename U, std::size_t N> -struct is_array<std::array<U, N>> : public std::true_type { -}; - -template<typename U> -struct is_libcamera_span : public std::false_type { -}; - -template<typename U, std::size_t Extent> -struct is_libcamera_span<Span<U, Extent>> : public std::true_type { -}; - -} /* namespace details */ - -namespace utils { - -template<typename C> -constexpr auto size(const C &c) -> decltype(c.size()) -{ - return c.size(); -} - -template<typename C> -constexpr auto data(const C &c) -> decltype(c.data()) -{ - return c.data(); -} - -template<typename C> -constexpr auto data(C &c) -> decltype(c.data()) -{ - return c.data(); -} - -template<class T, std::size_t N> -constexpr T *data(T (&array)[N]) noexcept -{ - return array; -} - -template<std::size_t I, typename T> -struct tuple_element; - -template<std::size_t I, typename T, std::size_t N> -struct tuple_element<I, Span<T, N>> { - using type = T; -}; - -template<typename T> -struct tuple_size; - -template<typename T, std::size_t N> -struct tuple_size<Span<T, N>> : public std::integral_constant<std::size_t, N> { -}; - -template<typename T> -struct tuple_size<Span<T, dynamic_extent>>; - -} /* namespace utils */ - -template<typename T, std::size_t Extent> -class Span -{ -public: - using element_type = T; - using value_type = typename std::remove_cv_t<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 = pointer; - using const_iterator = const_pointer; - using reverse_iterator = std::reverse_iterator<iterator>; - using const_reverse_iterator = std::reverse_iterator<const_iterator>; - - static constexpr std::size_t extent = Extent; - - template<bool Dependent = false, - typename = std::enable_if_t<Dependent || Extent == 0>> - constexpr Span() noexcept - : data_(nullptr) - { - } - - explicit constexpr Span(pointer ptr, [[maybe_unused]] size_type count) - : data_(ptr) - { - } - - explicit constexpr Span(pointer first, [[maybe_unused]] pointer last) - : data_(first) - { - } - - template<std::size_t N> - constexpr Span(element_type (&arr)[N], - std::enable_if_t<std::is_convertible<std::remove_pointer_t<decltype(utils::data(arr))> (*)[], - element_type (*)[]>::value && - N == Extent, - std::nullptr_t> = nullptr) noexcept - : data_(arr) - { - } - - template<std::size_t N> - constexpr Span(std::array<value_type, N> &arr, - std::enable_if_t<std::is_convertible<std::remove_pointer_t<decltype(utils::data(arr))> (*)[], - element_type (*)[]>::value && - N == Extent, - std::nullptr_t> = nullptr) noexcept - : data_(arr.data()) - { - } - - template<std::size_t N> - constexpr Span(const std::array<value_type, N> &arr, - std::enable_if_t<std::is_convertible<std::remove_pointer_t<decltype(utils::data(arr))> (*)[], - element_type (*)[]>::value && - N == Extent, - std::nullptr_t> = nullptr) noexcept - : data_(arr.data()) - { - } - - template<class Container> - explicit constexpr Span(Container &cont, - std::enable_if_t<!details::is_libcamera_span<Container>::value && - !details::is_array<Container>::value && - !std::is_array<Container>::value && - std::is_convertible<std::remove_pointer_t<decltype(utils::data(cont))> (*)[], - element_type (*)[]>::value, - std::nullptr_t> = nullptr) - : data_(utils::data(cont)) - { - } - - template<class Container> - explicit constexpr Span(const Container &cont, - std::enable_if_t<!details::is_libcamera_span<Container>::value && - !details::is_array<Container>::value && - !std::is_array<Container>::value && - std::is_convertible<std::remove_pointer_t<decltype(utils::data(cont))> (*)[], - element_type (*)[]>::value, - std::nullptr_t> = nullptr) - : data_(utils::data(cont)) - { - static_assert(utils::size(cont) == Extent, "Size mismatch"); - } - - template<class U, std::size_t N> - explicit constexpr Span(const Span<U, N> &s, - std::enable_if_t<std::is_convertible<U (*)[], element_type (*)[]>::value && - N == Extent, - std::nullptr_t> = nullptr) noexcept - : data_(s.data()) - { - } - - constexpr Span(const Span &other) noexcept = default; - constexpr Span &operator=(const Span &other) noexcept = default; +/* \todo Remove this header. */ - constexpr iterator begin() const { return data(); } - constexpr const_iterator cbegin() const { return begin(); } - constexpr iterator end() const { return data() + size(); } - constexpr const_iterator cend() const { return end(); } - constexpr reverse_iterator rbegin() const { return reverse_iterator(end()); } - constexpr const_reverse_iterator crbegin() const { return rbegin(); } - constexpr reverse_iterator rend() const { return reverse_iterator(begin()); } - constexpr const_reverse_iterator crend() const { return rend(); } - - constexpr reference front() const { return *data(); } - 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 Extent; } - constexpr size_type size_bytes() const noexcept { return size() * sizeof(element_type); } - constexpr bool empty() const noexcept { return size() == 0; } - - template<std::size_t Count> - constexpr Span<element_type, Count> first() const - { - static_assert(Count <= Extent, "Count larger than size"); - return Span<element_type, Count>{ data(), Count }; - } - - constexpr Span<element_type, dynamic_extent> first(std::size_t Count) const - { - return Span<element_type, dynamic_extent>{ data(), Count }; - } - - template<std::size_t Count> - constexpr Span<element_type, Count> last() const - { - static_assert(Count <= Extent, "Count larger than size"); - return Span<element_type, Count>{ data() + size() - Count, Count }; - } - - constexpr Span<element_type, dynamic_extent> last(std::size_t Count) const - { - return Span<element_type, dynamic_extent>{ data() + size() - Count, Count }; - } - - template<std::size_t Offset, std::size_t Count = dynamic_extent> - constexpr Span<element_type, Count != dynamic_extent ? Count : Extent - Offset> subspan() const - { - static_assert(Offset <= Extent, "Offset larger than size"); - static_assert(Count == dynamic_extent || Count + Offset <= Extent, - "Offset + Count larger than size"); - return Span<element_type, Count != dynamic_extent ? Count : Extent - Offset>{ - data() + Offset, - Count == dynamic_extent ? size() - Offset : Count - }; - } - - constexpr Span<element_type, dynamic_extent> - subspan(std::size_t Offset, std::size_t Count = dynamic_extent) const - { - return Span<element_type, dynamic_extent>{ - data() + Offset, - Count == dynamic_extent ? size() - Offset : Count - }; - } - -private: - pointer data_; -}; - -template<typename T> -class Span<T, dynamic_extent> -{ -public: - using element_type = T; - using value_type = typename std::remove_cv_t<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 const_iterator = const T *; - using reverse_iterator = std::reverse_iterator<iterator>; - using const_reverse_iterator = std::reverse_iterator<const_iterator>; - - static constexpr std::size_t extent = dynamic_extent; - - constexpr Span() noexcept - : data_(nullptr), size_(0) - { - } - - constexpr Span(pointer ptr, size_type count) - : data_(ptr), size_(count) - { - } - - constexpr Span(pointer first, pointer last) - : data_(first), size_(last - first) - { - } - - template<std::size_t N> - constexpr Span(element_type (&arr)[N], - std::enable_if_t<std::is_convertible<std::remove_pointer_t<decltype(utils::data(arr))> (*)[], - element_type (*)[]>::value, - std::nullptr_t> = nullptr) noexcept - : data_(arr), size_(N) - { - } - - template<std::size_t N> - constexpr Span(std::array<value_type, N> &arr, - std::enable_if_t<std::is_convertible<std::remove_pointer_t<decltype(utils::data(arr))> (*)[], - element_type (*)[]>::value, - std::nullptr_t> = nullptr) noexcept - : data_(utils::data(arr)), size_(N) - { - } - - template<std::size_t N> - constexpr Span(const std::array<value_type, N> &arr) noexcept - : data_(utils::data(arr)), size_(N) - { - } - - template<class Container> - constexpr Span(Container &cont, - std::enable_if_t<!details::is_libcamera_span<Container>::value && - !details::is_array<Container>::value && - !std::is_array<Container>::value && - std::is_convertible<std::remove_pointer_t<decltype(utils::data(cont))> (*)[], - element_type (*)[]>::value, - std::nullptr_t> = nullptr) - : data_(utils::data(cont)), size_(utils::size(cont)) - { - } - - template<class Container> - constexpr Span(const Container &cont, - std::enable_if_t<!details::is_libcamera_span<Container>::value && - !details::is_array<Container>::value && - !std::is_array<Container>::value && - std::is_convertible<std::remove_pointer_t<decltype(utils::data(cont))> (*)[], - element_type (*)[]>::value, - std::nullptr_t> = nullptr) - : data_(utils::data(cont)), size_(utils::size(cont)) - { - } - - template<class U, std::size_t N> - constexpr Span(const Span<U, N> &s, - std::enable_if_t<std::is_convertible<U (*)[], element_type (*)[]>::value, - std::nullptr_t> = nullptr) noexcept - : data_(s.data()), size_(s.size()) - { - } - - constexpr Span(const Span &other) noexcept = default; - constexpr Span &operator=(const Span &other) noexcept = default; - - constexpr iterator begin() const { return data(); } - constexpr const_iterator cbegin() const { return begin(); } - constexpr iterator end() const { return data() + size(); } - constexpr const_iterator cend() const { return end(); } - constexpr reverse_iterator rbegin() const { return reverse_iterator(end()); } - constexpr const_reverse_iterator crbegin() const { return rbegin(); } - constexpr reverse_iterator rend() const { return reverse_iterator(begin()); } - constexpr const_reverse_iterator crend() const { return rend(); } - - constexpr reference front() const { return *data(); } - 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 size() * sizeof(element_type); } - constexpr bool empty() const noexcept { return size() == 0; } - - template<std::size_t Count> - constexpr Span<element_type, Count> first() const - { - return Span<element_type, Count>{ data(), Count }; - } - - constexpr Span<element_type, dynamic_extent> first(std::size_t Count) const - { - return { data(), Count }; - } - - template<std::size_t Count> - constexpr Span<element_type, Count> last() const - { - return Span<element_type, Count>{ data() + size() - Count, Count }; - } - - constexpr Span<element_type, dynamic_extent> last(std::size_t Count) const - { - return Span<element_type, dynamic_extent>{ data() + size() - Count, Count }; - } - - template<std::size_t Offset, std::size_t Count = dynamic_extent> - constexpr Span<element_type, Count> subspan() const - { - return Span<element_type, Count>{ - data() + Offset, - Count == dynamic_extent ? size() - Offset : Count - }; - } - - constexpr Span<element_type, dynamic_extent> - subspan(std::size_t Offset, std::size_t Count = dynamic_extent) const - { - return Span<element_type, dynamic_extent>{ - data() + Offset, - Count == dynamic_extent ? size() - Offset : Count - }; - } +namespace libcamera { -private: - pointer data_; - size_type size_; -}; +template<typename T, std::size_t Extent = std::dynamic_extent> +using Span [[deprecated("use std::span instead")]] = std::span<T, Extent>; } /* namespace libcamera */ diff --git a/test/meson.build b/test/meson.build index e4450625ee..363a2829d8 100644 --- a/test/meson.build +++ b/test/meson.build @@ -45,7 +45,6 @@ public_tests = [ {'name': 'geometry', 'sources': ['geometry.cpp']}, {'name': 'public-api', 'sources': ['public-api.cpp']}, {'name': 'signal', 'sources': ['signal.cpp']}, - {'name': 'span', 'sources': ['span.cpp']}, {'name': 'transform', 'sources': ['transform.cpp']}, ] diff --git a/test/span.cpp b/test/span.cpp deleted file mode 100644 index 4b9f3279ad..0000000000 --- a/test/span.cpp +++ /dev/null @@ -1,205 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * Copyright (C) 2020, Google Inc. - * - * Span tests - */ - -/* - * Include first to ensure the header is self-contained, as there's no span.cpp - * in libcamera. - */ -#include <libcamera/base/span.h> - -#include <array> -#include <iostream> -#include <vector> - -#include "test.h" - -using namespace std; -using namespace libcamera; - -class SpanTest : public Test -{ -protected: - int run() - { - int i[4]{ 1, 2, 3, 4 }; - std::array<int, 4> a{ 1, 2, 3, 4 }; - const std::array<int, 4> ca{ 1, 2, 3, 4 }; - std::vector<int> v{ 1, 2, 3, 4 }; - const std::vector<int> cv{ 1, 2, 3, 4 }; - - /* - * Compile-test construction and usage of spans with static - * extent. Commented-out tests are expected not to compile, or - * to generate undefined behaviour. - */ - - Span<int, 0>{}; - /* Span<int, 4>{}; */ - - Span<int, 4>{ &i[0], 4 }; - Span<int, 4>{ &i[0], &i[3] }; - - Span<int, 4>{ i }; - /* Span<float, 4>{ i }; */ - /* Span<int, 2>{ i }; */ - - Span<int, 4>{ a }; - Span<const int, 4>{ a }; - /* Span<float, 4>{ a }; */ - /* Span<int, 2>{ a }; */ - - Span<const int, 4>{ ca }; - /* Span<const int, 2>{ ca }; */ - /* Span<const float, 4>{ ca }; */ - /* Span<int, 4>{ ca }; */ - - Span<int, 4>{ v }; - Span<const int, 4>{ v }; - /* Span<float, 4>{ v }; */ - - Span<const int, 4>{ v }; - /* Span<int, 4>{ v }; */ - /* Span<const float, 4>{ v }; */ - - Span<int, 4> staticSpan{ i }; - Span<int, 4>{ staticSpan }; - Span<const int, 4>{ staticSpan }; - /* Span<const int, 2>{ staticSpan }; */ - - staticSpan = Span<int, 4>{ v }; - - if (*staticSpan.begin() != 1) { - std::cout << "Span<static_extent>::begin() failed" << std::endl; - return TestFail; - } - if (*staticSpan.cbegin() != 1) { - std::cout << "Span<static_extent>::cbegin() failed" << std::endl; - return TestFail; - } - staticSpan.end(); - staticSpan.cend(); - if (*staticSpan.rbegin() != 4) { - std::cout << "Span<static_extent>::rbegin() failed" << std::endl; - return TestFail; - } - if (*staticSpan.crbegin() != 4) { - std::cout << "Span<static_extent>::crbegin() failed" << std::endl; - return TestFail; - } - staticSpan.rend(); - staticSpan.crend(); - - staticSpan.front(); - staticSpan.back(); - staticSpan[0]; - staticSpan.data(); - - staticSpan.size(); - staticSpan.size_bytes(); - - staticSpan.empty(); - - staticSpan.first<2>(); - staticSpan.first(2); - /* staticSpan.first<6>(); */ - /* staticSpan.first(6); */ - staticSpan.last<2>(); - staticSpan.last(2); - /* staticSpan.last<6>(); */ - /* staticSpan.last(6); */ - staticSpan.subspan<1>(); - staticSpan.subspan<1, 2>(); - staticSpan.subspan(1); - staticSpan.subspan(1, 2); - /* staticSpan.subspan(2, 4); */ - - /* - * Compile-test construction and usage of spans with dynamic - * extent. Commented-out tests are expected not to compile, or - * to generate undefined behaviour. - */ - - Span<int>{}; - - Span<int>{ &i[0], 4 }; - Span<int>{ &i[0], &i[3] }; - - Span<int>{ i }; - /* Span<float>{ i }; */ - - Span<int>{ a }; - Span<const int>{ a }; - /* Span<float>{ a }; */ - - Span<const int>{ ca }; - /* Span<const float>{ca}; */ - /* Span<int>{ca}; */ - - Span<int>{ v }; - Span<const int>{ v }; - /* Span<float>{ v }; */ - - Span<const int>{ cv }; - /* Span<int>{ cv }; */ - /* Span<const float>{ cv }; */ - - Span<int> dynamicSpan{ i }; - Span<int>{ dynamicSpan }; - Span<const int>{ dynamicSpan }; - - dynamicSpan = Span<int>{ a }; - - if (*dynamicSpan.begin() != 1) { - std::cout << "Span<dynamic_extent>::begin() failed" << std::endl; - return TestFail; - } - if (*dynamicSpan.cbegin() != 1) { - std::cout << "Span<dynamic_extent>::cbegin() failed" << std::endl; - return TestFail; - } - dynamicSpan.end(); - dynamicSpan.cend(); - if (*dynamicSpan.rbegin() != 4) { - std::cout << "Span<dynamic_extent>::rbegin() failed" << std::endl; - return TestFail; - } - if (*dynamicSpan.crbegin() != 4) { - std::cout << "Span<dynamic_extent>::crbegin() failed" << std::endl; - return TestFail; - } - dynamicSpan.rend(); - dynamicSpan.crend(); - - dynamicSpan.front(); - dynamicSpan.back(); - dynamicSpan[0]; - dynamicSpan.data(); - - dynamicSpan.size(); - dynamicSpan.size_bytes(); - - dynamicSpan.empty(); - - dynamicSpan.first<2>(); - dynamicSpan.first(2); - /* dynamicSpan.first<6>(); */ - /* dynamicSpan.first(6); */ - dynamicSpan.last<2>(); - dynamicSpan.last(2); - /* dynamicSpan.last<6>(); */ - /* dynamicSpan.last(6); */ - dynamicSpan.subspan<1>(); - dynamicSpan.subspan<1, 2>(); - dynamicSpan.subspan(1); - dynamicSpan.subspan(1, 2); - /* dynamicSpan.subspan(2, 4); */ - - return TestPass; - } -}; - -TEST_REGISTER(SpanTest)
With the switch to C++20, this type has largely become unnecessary, so remove it, but leave a deprecated alias instructing users to use `std::span`. Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com> --- include/libcamera/base/span.h | 405 +--------------------------------- test/meson.build | 1 - test/span.cpp | 205 ----------------- 3 files changed, 5 insertions(+), 606 deletions(-) delete mode 100644 test/span.cpp