From f1f68007c68ecf0982312e2323099c660b0cfd8a Mon Sep 17 00:00:00 2001 From: reuk Date: Wed, 8 Feb 2023 19:24:54 +0000 Subject: [PATCH] Containers: Add simple Span implementation --- modules/juce_core/containers/juce_Span.h | 148 +++++++++++++++++++++++ modules/juce_core/juce_core.h | 1 + 2 files changed, 149 insertions(+) create mode 100644 modules/juce_core/containers/juce_Span.h diff --git a/modules/juce_core/containers/juce_Span.h b/modules/juce_core/containers/juce_Span.h new file mode 100644 index 0000000000..cf66ca8336 --- /dev/null +++ b/modules/juce_core/containers/juce_Span.h @@ -0,0 +1,148 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2022 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + The code included in this file is provided under the terms of the ISC license + http://www.isc.org/downloads/software-support-policy/isc-license. Permission + To use, copy, modify, and/or distribute this software for any purpose with or + without fee is hereby granted provided that the above copyright notice and + this permission notice appear in all copies. + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ + +//============================================================================== +inline constexpr auto dynamicExtent = std::numeric_limits::max(); + +namespace detail +{ + //============================================================================== + template + constexpr auto hasToAddress = false; + + template + constexpr auto hasToAddress::to_address (std::declval()))>> = true; + + template + constexpr auto hasDataAndSize = false; + + template + constexpr auto hasDataAndSize())), + decltype (std::size (std::declval()))>> = true; + + template + struct NumBase + { + constexpr NumBase() = default; + + constexpr explicit NumBase (size_t) {} + + constexpr size_t size() const { return Extent; } + }; + + template <> + struct NumBase + { + constexpr NumBase() = default; + + constexpr explicit NumBase (size_t arg) + : num (arg) {} + + constexpr size_t size() const { return num; } + + size_t num{}; + }; + + template + constexpr T* toAddress (T* p) + { + return p; + } + + template + constexpr auto toAddress (const It& it) + { + if constexpr (detail::hasToAddress) + return std::pointer_traits::to_address (it); + else + return toAddress (it.operator->()); + } +} + +//============================================================================== +/** + A non-owning view over contiguous objects stored in an Array or vector + or other similar container. + + This is a bit like std::span from C++20, but with a more limited interface. +*/ +template +class Span : private detail::NumBase // for empty-base optimisation +{ + using Base = detail::NumBase; + +public: + static constexpr auto extent = Extent; + + template = 0> + constexpr Span() {} + + template + constexpr Span (It it, size_t end) + : Base (end), ptr (detail::toAddress (it)) {} + + template , int> = 0> + constexpr Span (Range&& range) + : Base (std::size (range)), ptr (std::data (range)) {} + + constexpr Span (const Span&) = default; + + constexpr Span& operator= (const Span&) = default; + + using Base::size; + + constexpr Value* begin() const { return ptr; } + constexpr Value* end() const { return ptr + size(); } + + constexpr auto& front() const { return ptr[0]; } + constexpr auto& back() const { return ptr[size() - 1]; } + + constexpr auto& operator[] (size_t index) const { return ptr[index]; } + constexpr Value* data() const { return ptr; } + + constexpr bool empty() const { return size() == 0; } + +private: + Value* ptr = nullptr; +}; + +template +Span (T, End) -> Span()))>>; + +template +Span (T (&) [N]) -> Span; + +template +Span (std::array&) -> Span; + +template +Span (const std::array&) -> Span; + +template +Span (Range&& r) -> Span>; + + +} // namespace juce diff --git a/modules/juce_core/juce_core.h b/modules/juce_core/juce_core.h index 8490eaec1c..aa18cf0eb3 100644 --- a/modules/juce_core/juce_core.h +++ b/modules/juce_core/juce_core.h @@ -276,6 +276,7 @@ JUCE_END_IGNORE_WARNINGS_MSVC #include "text/juce_LocalisedStrings.h" #include "text/juce_Base64.h" #include "misc/juce_Functional.h" +#include "containers/juce_Span.h" #include "misc/juce_Result.h" #include "misc/juce_Uuid.h" #include "misc/juce_ConsoleApplication.h"