From patchwork Mon Jan 13 16:42:34 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 2627 X-Patchwork-Delegate: jacopo@jmondi.org Return-Path: Received: from relay11.mail.gandi.net (relay11.mail.gandi.net [217.70.178.231]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 1D258606EA for ; Mon, 13 Jan 2020 17:40:34 +0100 (CET) Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay11.mail.gandi.net (Postfix) with ESMTPSA id ABA0B100009; Mon, 13 Jan 2020 16:40:33 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Mon, 13 Jan 2020 17:42:34 +0100 Message-Id: <20200113164245.52535-13-jacopo@jmondi.org> X-Mailer: git-send-email 2.24.0 In-Reply-To: <20200113164245.52535-1-jacopo@jmondi.org> References: <20200113164245.52535-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 12/23] libcamera: Add C++20 std::span<> implementation X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 13 Jan 2020 16:40:34 -0000 Add a simplified implementation of C++20 std::span<> class. Signed-off-by: Jacopo Mondi --- 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 +#include + +namespace libcamera { + +template +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(&v), 1) + { + } + + Span(T *v, size_t s) + : storage_(v, s) + { + } + + Span(const T *v, size_t s) + : storage_(const_cast(v), s) + { + } + + Span(std::initializer_list list) + : storage_(const_cast(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 + +/** + * \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 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 */