OpenShot Audio Library | OpenShotAudio 0.4.0
 
Loading...
Searching...
No Matches
juce_Span.h
1/*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2022 - Raw Material Software Limited
6
7 JUCE is an open source library subject to commercial or open-source
8 licensing.
9
10 The code included in this file is provided under the terms of the ISC license
11 http://www.isc.org/downloads/software-support-policy/isc-license. Permission
12 To use, copy, modify, and/or distribute this software for any purpose with or
13 without fee is hereby granted provided that the above copyright notice and
14 this permission notice appear in all copies.
15
16 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
17 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
18 DISCLAIMED.
19
20 ==============================================================================
21*/
22
23namespace juce
24{
25
26//==============================================================================
27inline constexpr auto dynamicExtent = std::numeric_limits<size_t>::max();
28
29namespace detail
30{
31 //==============================================================================
32 template <typename, typename = void>
33 constexpr auto hasToAddress = false;
34
35 template <typename T>
36 constexpr auto hasToAddress<T, Void<decltype (std::pointer_traits<T>::to_address (std::declval<T>()))>> = true;
37
38 template <typename, typename = void>
39 constexpr auto hasDataAndSize = false;
40
41 template <typename T>
42 constexpr auto hasDataAndSize<T,
43 Void<decltype (std::data (std::declval<T>())),
44 decltype (std::size (std::declval<T>()))>> = true;
45
46 template <size_t Extent>
47 struct NumBase
48 {
49 constexpr NumBase() = default;
50
51 constexpr explicit NumBase (size_t) {}
52
53 constexpr size_t size() const { return Extent; }
54 };
55
56 template <>
57 struct NumBase<dynamicExtent>
58 {
59 constexpr NumBase() = default;
60
61 constexpr explicit NumBase (size_t arg)
62 : num (arg) {}
63
64 constexpr size_t size() const { return num; }
65
66 size_t num{};
67 };
68
69 template <typename T>
70 constexpr T* toAddress (T* p)
71 {
72 return p;
73 }
74
75 template <typename It>
76 constexpr auto toAddress (const It& it)
77 {
78 if constexpr (detail::hasToAddress<It>)
79 return std::pointer_traits<It>::to_address (it);
80 else
81 return toAddress (it.operator->());
82 }
83}
84
85//==============================================================================
94template <typename Value, size_t Extent = dynamicExtent>
95class Span : private detail::NumBase<Extent> // for empty-base optimisation
96{
97 using Base = detail::NumBase<Extent>;
98
99public:
100 static constexpr auto extent = Extent;
101
102 template <size_t e = extent, std::enable_if_t<e == 0 || e == dynamicExtent, int> = 0>
103 constexpr Span() {}
104
105 template <typename It>
106 constexpr Span (It it, size_t end)
107 : Base (end), ptr (detail::toAddress (it)) {}
108
109 template <typename Range, std::enable_if_t<detail::hasDataAndSize<Range>, int> = 0>
110 constexpr Span (Range&& range)
111 : Base (std::size (range)), ptr (std::data (range)) {}
112
113 constexpr Span (const Span&) = default;
114
115 constexpr Span& operator= (const Span&) = default;
116
117 constexpr Span (Span&&) noexcept = default;
118
119 constexpr Span& operator= (Span&&) noexcept = default;
120
121 using Base::size;
122
123 constexpr Value* begin() const { return ptr; }
124 constexpr Value* end() const { return ptr + size(); }
125
126 constexpr auto& front() const { return ptr[0]; }
127 constexpr auto& back() const { return ptr[size() - 1]; }
128
129 constexpr auto& operator[] (size_t index) const { return ptr[index]; }
130 constexpr Value* data() const { return ptr; }
131
132 constexpr bool empty() const { return size() == 0; }
133
134private:
135 Value* ptr = nullptr;
136};
137
138template <typename T, typename End>
140
141template <typename T, size_t N>
142Span (T (&) [N]) -> Span<T, N>;
143
144template <typename T, size_t N>
145Span (std::array<T, N>&) -> Span<T, N>;
146
147template <typename T, size_t N>
148Span (const std::array<T, N>&) -> Span<const T, N>;
149
150template <typename Range>
151Span (Range&& r) -> Span<std::remove_pointer_t<decltype (std::data (r))>>;
152
153
154} // namespace juce