|
|
|
@@ -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<size_t>::max();
|
|
|
|
|
|
|
|
namespace detail
|
|
|
|
{
|
|
|
|
//==============================================================================
|
|
|
|
template <typename, typename = void>
|
|
|
|
constexpr auto hasToAddress = false;
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
constexpr auto hasToAddress<T, Void<decltype (std::pointer_traits<T>::to_address (std::declval<T>()))>> = true;
|
|
|
|
|
|
|
|
template <typename, typename = void>
|
|
|
|
constexpr auto hasDataAndSize = false;
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
constexpr auto hasDataAndSize<T,
|
|
|
|
Void<decltype (std::data (std::declval<T>())),
|
|
|
|
decltype (std::size (std::declval<T>()))>> = true;
|
|
|
|
|
|
|
|
template <size_t Extent>
|
|
|
|
struct NumBase
|
|
|
|
{
|
|
|
|
constexpr NumBase() = default;
|
|
|
|
|
|
|
|
constexpr explicit NumBase (size_t) {}
|
|
|
|
|
|
|
|
constexpr size_t size() const { return Extent; }
|
|
|
|
};
|
|
|
|
|
|
|
|
template <>
|
|
|
|
struct NumBase<dynamicExtent>
|
|
|
|
{
|
|
|
|
constexpr NumBase() = default;
|
|
|
|
|
|
|
|
constexpr explicit NumBase (size_t arg)
|
|
|
|
: num (arg) {}
|
|
|
|
|
|
|
|
constexpr size_t size() const { return num; }
|
|
|
|
|
|
|
|
size_t num{};
|
|
|
|
};
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
constexpr T* toAddress (T* p)
|
|
|
|
{
|
|
|
|
return p;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename It>
|
|
|
|
constexpr auto toAddress (const It& it)
|
|
|
|
{
|
|
|
|
if constexpr (detail::hasToAddress<It>)
|
|
|
|
return std::pointer_traits<It>::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 <typename Value, size_t Extent = dynamicExtent>
|
|
|
|
class Span : private detail::NumBase<Extent> // for empty-base optimisation
|
|
|
|
{
|
|
|
|
using Base = detail::NumBase<Extent>;
|
|
|
|
|
|
|
|
public:
|
|
|
|
static constexpr auto extent = Extent;
|
|
|
|
|
|
|
|
template <size_t e = extent, std::enable_if_t<e == 0 || e == dynamicExtent, int> = 0>
|
|
|
|
constexpr Span() {}
|
|
|
|
|
|
|
|
template <typename It>
|
|
|
|
constexpr Span (It it, size_t end)
|
|
|
|
: Base (end), ptr (detail::toAddress (it)) {}
|
|
|
|
|
|
|
|
template <typename Range, std::enable_if_t<detail::hasDataAndSize<Range>, 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 <typename T, typename End>
|
|
|
|
Span (T, End) -> Span<std::remove_pointer_t<decltype (detail::toAddress (std::declval<T>()))>>;
|
|
|
|
|
|
|
|
template <typename T, size_t N>
|
|
|
|
Span (T (&) [N]) -> Span<T, N>;
|
|
|
|
|
|
|
|
template <typename T, size_t N>
|
|
|
|
Span (std::array<T, N>&) -> Span<T, N>;
|
|
|
|
|
|
|
|
template <typename T, size_t N>
|
|
|
|
Span (const std::array<T, N>&) -> Span<const T, N>;
|
|
|
|
|
|
|
|
template <typename Range>
|
|
|
|
Span (Range&& r) -> Span<std::remove_pointer_t<decltype (std::data (r))>>;
|
|
|
|
|
|
|
|
|
|
|
|
} // namespace juce
|