OpenShot Audio Library | OpenShotAudio  0.6.0
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 
23 namespace juce
24 {
25 
26 //==============================================================================
27 inline constexpr auto dynamicExtent = std::numeric_limits<size_t>::max();
28 
29 namespace 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 //==============================================================================
94 template <typename Value, size_t Extent = dynamicExtent>
95 class Span : private detail::NumBase<Extent> // for empty-base optimisation
96 {
97  using Base = detail::NumBase<Extent>;
98 
99 public:
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 
134 private:
135  Value* ptr = nullptr;
136 };
137 
138 template <typename T, typename End>
140 
141 template <typename T, size_t N>
142 Span (T (&) [N]) -> Span<T, N>;
143 
144 template <typename T, size_t N>
145 Span (std::array<T, N>&) -> Span<T, N>;
146 
147 template <typename T, size_t N>
148 Span (const std::array<T, N>&) -> Span<const T, N>;
149 
150 template <typename Range>
151 Span (Range&& r) -> Span<std::remove_pointer_t<decltype (std::data (r))>>;
152 
153 
154 } // namespace juce