[libcamera-devel] [PATCH 12/23] libcamera: Add C++20 std::span<> implementation
Jacopo Mondi
jacopo at jmondi.org
Mon Jan 13 17:42:34 CET 2020
Add a simplified implementation of C++20 std::span<> class.
Signed-off-by: Jacopo Mondi <jacopo at jmondi.org>
---
Documentation/Doxyfile.in | 4 +-
include/libcamera/meson.build | 1 +
include/libcamera/span.h | 89 +++++++++++++++++++++++
src/libcamera/meson.build | 1 +
src/libcamera/span.cpp | 128 ++++++++++++++++++++++++++++++++++
5 files changed, 222 insertions(+), 1 deletion(-)
create mode 100644 include/libcamera/span.h
create mode 100644 src/libcamera/span.cpp
diff --git a/Documentation/Doxyfile.in b/Documentation/Doxyfile.in
index 8e6fbdbb92b6..6b08960a921f 100644
--- a/Documentation/Doxyfile.in
+++ b/Documentation/Doxyfile.in
@@ -838,8 +838,10 @@ RECURSIVE = YES
# Note that relative paths are relative to the directory from which doxygen is
# run.
-EXCLUDE = @TOP_SRCDIR@/src/libcamera/device_enumerator_sysfs.cpp \
+EXCLUDE = @TOP_SRCDIR@/include/libcamera/span.h \
+ @TOP_SRCDIR@/src/libcamera/device_enumerator_sysfs.cpp \
@TOP_SRCDIR@/src/libcamera/device_enumerator_udev.cpp \
+ @TOP_SRCDIR@/src/libcamera/span.cpp \
@TOP_SRCDIR@/src/libcamera/include/device_enumerator_sysfs.h \
@TOP_SRCDIR@/src/libcamera/include/device_enumerator_udev.h \
@TOP_SRCDIR@/src/libcamera/pipeline/ \
diff --git a/include/libcamera/meson.build b/include/libcamera/meson.build
index f58c02d2cf35..f47c583cbbc0 100644
--- a/include/libcamera/meson.build
+++ b/include/libcamera/meson.build
@@ -14,6 +14,7 @@ libcamera_api = files([
'pixelformats.h',
'request.h',
'signal.h',
+ 'span.h',
'stream.h',
'timer.h',
])
diff --git a/include/libcamera/span.h b/include/libcamera/span.h
new file mode 100644
index 000000000000..3e63603f60ed
--- /dev/null
+++ b/include/libcamera/span.h
@@ -0,0 +1,89 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2020, Google Inc.
+ *
+ * span.h - C++20 std::span<> implementation for C++11
+ */
+
+#ifndef __LIBCAMERA_SPAN_H__
+#define __LIBCAMERA_SPAN_H__
+
+#include <array>
+#include <stddef.h>
+
+namespace libcamera {
+
+template<typename T>
+class Span
+{
+private:
+ using iterator = T *;
+ using const_iterator = const T *;
+
+ class Storage
+ {
+ public:
+ Storage(T *ptr, size_t size)
+ : ptr_(ptr), size_(size)
+ {
+ }
+
+ T *ptr() const { return ptr_; }
+ size_t size() const { return size_; }
+
+ private:
+ T *ptr_;
+ size_t size_;
+ };
+
+public:
+ Span(T &v)
+ : storage_(&v, 1)
+ {
+ }
+
+ Span(const T &v)
+ : storage_(const_cast<T *>(&v), 1)
+ {
+ }
+
+ Span(T *v, size_t s)
+ : storage_(v, s)
+ {
+ }
+
+ Span(const T *v, size_t s)
+ : storage_(const_cast<T *>(v), s)
+ {
+ }
+
+ Span(std::initializer_list<T> list)
+ : storage_(const_cast<T *>(list.begin()), list.size())
+ {
+ }
+
+ Span(const Span &other) = default;
+ Span &operator=(const Span &other) = default;
+
+ T *data() const { return storage_.ptr(); }
+ size_t size() const { return storage_.size(); }
+
+ T &operator[](unsigned int index) const
+ {
+ if (index >= size())
+ return *(end() - 1);
+ return *(data() + index);
+ }
+
+ constexpr iterator begin() const { return data(); }
+ constexpr iterator cbegin() const { return begin(); }
+ constexpr iterator end() const { return data() + size(); }
+ constexpr iterator cend() const { return end(); }
+
+private:
+ Storage storage_;
+};
+
+}; /* namespace libcamera */
+
+#endif /* __LIBCAMERA_SPAN_H__ */
diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build
index 1e5b54b34078..ecc5b5fe4023 100644
--- a/src/libcamera/meson.build
+++ b/src/libcamera/meson.build
@@ -36,6 +36,7 @@ libcamera_sources = files([
'request.cpp',
'semaphore.cpp',
'signal.cpp',
+ 'span.cpp',
'stream.cpp',
'thread.cpp',
'timer.cpp',
diff --git a/src/libcamera/span.cpp b/src/libcamera/span.cpp
new file mode 100644
index 000000000000..72ffdf7481c4
--- /dev/null
+++ b/src/libcamera/span.cpp
@@ -0,0 +1,128 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2020, Google Inc.
+ *
+ * span.h - C++20 std::span<> implementation for C++11
+ */
+
+#include <libcamera/span.h>
+
+/**
+ * \file span.h
+ * \brief libcamera implementation of C++20 std::span<>
+ */
+
+namespace libcamera {
+
+/**
+ * \class Span
+ * \brief Representation of a sequence of contiguous objects of type T
+ *
+ * This class represents a sequence of fixed size of contiguous objects of
+ * template type T with the first object residing in position 0.
+ *
+ * A Span internally consists of a pointer to raw memory and an associated
+ * number of elements there located. It does not enforce any ownership on the
+ * memory it represents, but it only provides a convenient, lightweight and
+ * easily transportable view on such memory area.
+ *
+ * A Span can be constructed from a single element as well as from raw memory
+ * by providing an associated size. It can be accessed by index and iterated
+ * as a regular standard library container. As Span does not enforce any memory
+ * ownership, destroying a Span instance does not invalidate the memory it
+ * represents.
+ *
+ * The libcamera implementation of Span it's a simplified implementation of
+ * C++20 the std::span<> class and it is no 1-to-1 compatible with it. Care
+ * should be taken in not mixing usage of the two classes.
+ */
+
+/**
+ * \fn Span::Span(T &v)
+ * \brief Contruct a Span of size 1 representing element \a v
+ * \param[in] v The element represented by the Span
+ */
+
+/**
+ * \fn Span::Span(const T &v)
+ * \brief Contruct a Span of size 1 representing the constant element \a v
+ * \param[in] v The constant element represented by the Span
+ */
+
+/**
+ * \fn Span::Span(T *v, size_t s)
+ * \brief Contruct a Span of size \a s representing elements in memory \a v
+ * \param[in] v The memory area represeted by the Span
+ * \param[in] s The number of elements in memory area \a v
+ */
+
+/**
+ * \fn Span::Span(const T *v, size_t s)
+ * \brief Contruct a Span of size \a s representing elements in constant memory \a v
+ * \param[in] v The constant memory area represeted by the Span
+ * \param[in] s The number of elements in memory area \a v
+ */
+
+/**
+ * \fn Span::Span(std::initializer_list<T> list)
+ * \brief Contruct a Span with an initialier list of elements
+ * \param[in] list The initializer list
+ */
+
+/**
+ * \fn Span::Span(const Span &other)
+ * \brief Contruct a Span with the content of \a other
+ * \param[in] other The other Span
+ */
+
+/**
+ * \fn Span::operator=(const Span &other)
+ * \brief Replace the content of the Span with the one from \a other
+ * \param[in] other The other Span
+ */
+
+/**
+ * \fn Span::data()
+ * \brief Retrieve a pointer to the beginning of the memory area represented by
+ * the Span
+ * \return A pointer to the raw memory area
+ */
+
+/**
+ * \fn Span::size()
+ * \brief Retrieve the number of elements in the Span
+ * \return The number of elements in the Span
+ */
+
+/**
+ * \fn Span::operator[](unsigned int index)
+ * \brief Retrieve element in position \a index
+ * \param[in] index
+ *
+ * If \a index is larger than the number of elements in the Span, the last
+ * element is returned.
+ *
+ * \return The element at position \a index
+ */
+
+/**
+ * \fn iterator Span::begin()
+ * \brief Retrieve an iterator to the first element in the Span
+ */
+
+/**
+ * \fn const_iterator Span::cbegin()
+ * \brief Retrieve a constant iterator to the first element in the Span
+ */
+
+/**
+ * \fn iterator Span::end()
+ * \brief Retrieve an iterator pointing to the past-the-end element in the Span
+ */
+
+/**
+ * \fn const_iterator Span::cend()
+ * \brief Retrieve a constant iterator pointing to the past-the-end element in the Span
+ */
+
+} /* namespace libcamera */
--
2.24.0
More information about the libcamera-devel
mailing list