@@ -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 */
@@ -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']},
]
deleted file mode 100644
@@ -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