[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