OpenShot Audio Library | OpenShotAudio  0.6.0
juce_Enumerate.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 namespace detail
27 {
28 
29 template <typename T, typename = void>
30 constexpr auto canPreDecrement = false;
31 
32 template <typename T>
33 constexpr auto canPreDecrement<T, std::void_t<decltype (--std::declval<T>())>> = true;
34 
35 template <typename T, typename I, typename = void>
36 constexpr auto canAddAssign = false;
37 
38 template <typename T, typename I>
39 constexpr auto canAddAssign<T, I, std::void_t<decltype (std::declval<T>() += std::declval<I>())>> = true;
40 
41 template <typename T, typename I, typename = void>
42 constexpr auto canSubAssign = false;
43 
44 template <typename T, typename I>
45 constexpr auto canSubAssign<T, I, std::void_t<decltype (std::declval<T>() -= std::declval<I>())>> = true;
46 
47 template <typename T, typename I, typename = void>
48 constexpr auto canAdd = false;
49 
50 template <typename T, typename I>
51 constexpr auto canAdd<T, I, std::void_t<decltype (std::declval<T>() + std::declval<I>())>> = true;
52 
53 template <typename T, typename I, typename = void>
54 constexpr auto canSub = false;
55 
56 template <typename T, typename I>
57 constexpr auto canSub<T, I, std::void_t<decltype (std::declval<T>() - std::declval<I>())>> = true;
58 
59 template <typename T, typename I, typename = void>
60 constexpr auto canLessThan = false;
61 
62 template <typename T, typename I>
63 constexpr auto canLessThan<T, I, std::void_t<decltype (std::declval<T>() < std::declval<I>())>> = true;
64 
65 template <typename T, typename I, typename = void>
66 constexpr auto canLessThanEqual = false;
67 
68 template <typename T, typename I>
69 constexpr auto canLessThanEqual<T, I, std::void_t<decltype (std::declval<T>() <= std::declval<I>())>> = true;
70 
71 template <typename T, typename I, typename = void>
72 constexpr auto canGreaterThan = false;
73 
74 template <typename T, typename I>
75 constexpr auto canGreaterThan<T, I, std::void_t<decltype (std::declval<T>() > std::declval<I>())>> = true;
76 
77 template <typename T, typename I, typename = void>
78 constexpr auto canGreaterThanEqual = false;
79 
80 template <typename T, typename I>
81 constexpr auto canGreaterThanEqual<T, I, std::void_t<decltype (std::declval<T>() >= std::declval<I>())>> = true;
82 
83 namespace withAdlSize
84 {
85  using std::size;
86 
87  template <typename Range>
88  using AdlSize = decltype (size (std::declval<Range>()));
89 
90  template <typename Range>
91  using AdlSignedSize = std::common_type_t<std::ptrdiff_t, std::make_signed_t<AdlSize<Range>>>;
92 }
93 
94 } // namespace detail
95 
108 template <typename Index, typename Value>
110 {
111  Index index;
112  Value value;
113 };
114 
126 template <typename Iter, typename Index = ptrdiff_t>
128 {
129 public:
131  constexpr EnumerateIterator() = default;
132 
134  constexpr explicit EnumerateIterator (Iter iter)
135  : EnumerateIterator (std::move (iter), Index{}) {}
136 
138  constexpr EnumerateIterator (Iter iter, Index ind)
139  : iterator (std::move (iter)), index (ind) {}
140 
142  template <typename OtherIter, typename OtherInd>
143  [[nodiscard]] constexpr bool operator== (const EnumerateIterator<OtherIter, OtherInd>& other) const
144  {
145  return iterator == other.iterator;
146  }
147 
149  template <typename OtherIter, typename OtherInd>
150  [[nodiscard]] constexpr bool operator!= (const EnumerateIterator<OtherIter, OtherInd>& other) const
151  {
152  return ! operator== (other);
153  }
154 
159  [[nodiscard]] constexpr Enumerated<Index, decltype (*std::declval<Iter>())> operator*() const
160  {
161  return { index, *iterator };
162  }
163 
166  {
167  ++iterator;
168  ++index;
169  return *this;
170  }
171 
174  {
175  auto copy = *this;
176  operator++();
177  return copy;
178  }
179 
183  template <typename T = Iter, std::enable_if_t<detail::canPreDecrement<T>, int> = 0>
185  {
186  --iterator;
187  --index;
188  return *this;
189  }
190 
194  template <typename T = Iter, std::enable_if_t<detail::canPreDecrement<T>, int> = 0>
196  {
197  auto copy = *this;
198  operator--();
199  return copy;
200  }
201 
205  template <typename I, std::enable_if_t<detail::canAddAssign<Iter&, I>, int> = 0>
206  constexpr EnumerateIterator& operator+= (I diff)
207  {
208  iterator += diff;
209  index += static_cast<Index> (diff);
210  return *this;
211  }
212 
216  template <typename I, std::enable_if_t<detail::canSubAssign<Iter&, I>, int> = 0>
217  constexpr EnumerateIterator& operator-= (I diff)
218  {
219  iterator -= diff;
220  index -= static_cast<Index> (diff);
221  return *this;
222  }
223 
229  template <typename OtherIter, typename OtherInd, std::enable_if_t<detail::canSub<Iter, OtherIter>, int> = 0>
230  [[nodiscard]] constexpr auto operator- (const EnumerateIterator<OtherIter, OtherInd>& other) const
231  {
232  return iterator - other.iterator;
233  }
234 
240  template <typename I, std::enable_if_t<detail::canAdd<EnumerateIterator, I>, int> = 0>
241  [[nodiscard]] constexpr auto operator[] (I diff) const
242  {
243  return *(*this + diff);
244  }
245 
249  template <typename OtherIter, typename OtherInd, std::enable_if_t<detail::canLessThan<Iter, OtherIter>, int> = 0>
250  [[nodiscard]] constexpr bool operator< (const EnumerateIterator<OtherIter, OtherInd>& other) const
251  {
252  return iterator < other.iterator;
253  }
254 
258  template <typename OtherIter, typename OtherInd, std::enable_if_t<detail::canLessThanEqual<Iter, OtherIter>, int> = 0>
259  [[nodiscard]] constexpr bool operator<= (const EnumerateIterator<OtherIter, OtherInd>& other) const
260  {
261  return iterator <= other.iterator;
262  }
263 
267  template <typename OtherIter, typename OtherInd, std::enable_if_t<detail::canGreaterThan<Iter, OtherIter>, int> = 0>
268  [[nodiscard]] constexpr bool operator> (const EnumerateIterator<OtherIter, OtherInd>& other) const
269  {
270  return iterator > other.iterator;
271  }
272 
276  template <typename OtherIter, typename OtherInd, std::enable_if_t<detail::canGreaterThanEqual<Iter, OtherIter>, int> = 0>
277  [[nodiscard]] constexpr bool operator>= (const EnumerateIterator<OtherIter, OtherInd>& other) const
278  {
279  return iterator >= other.iterator;
280  }
281 
285  template <typename I, std::enable_if_t<detail::canAddAssign<EnumerateIterator&, I>, int> = 0>
286  constexpr friend auto operator+ (EnumerateIterator iter, I ind)
287  {
288  return iter += ind;
289  }
290 
294  template <typename I, std::enable_if_t<detail::canAddAssign<EnumerateIterator&, I>, int> = 0>
295  constexpr friend auto operator+ (I ind, EnumerateIterator iter)
296  {
297  return iter += ind;
298  }
299 
303  template <typename I, std::enable_if_t<detail::canSubAssign<EnumerateIterator&, I>, int> = 0>
304  constexpr friend auto operator- (EnumerateIterator iter, I ind)
305  {
306  return iter -= ind;
307  }
308 
309 private:
310  Iter iterator{};
311  Index index = 0;
312 };
313 
314 //==============================================================================
324 template <typename Begin, typename End>
326 {
327 public:
331  constexpr IteratorPair (Begin bIn, End eIn)
332  : b (std::move (bIn)), e (std::move (eIn)) {}
333 
335  constexpr auto begin() const { return b; }
336 
338  constexpr auto end() const { return e; }
339 
340 private:
341  Begin b;
342  End e;
343 };
344 
352 template <typename Begin, typename End = Begin>
353 [[nodiscard]] constexpr auto makeRange (Begin begin, End end)
354 {
355  return IteratorPair<Begin, End> { std::move (begin), std::move (end) };
356 }
357 
358 //==============================================================================
418 template <typename Range, typename Index = detail::withAdlSize::AdlSignedSize<Range>>
419 [[nodiscard]] constexpr auto enumerate (Range&& range, Index startingValue = {})
420 {
421  // This ensures argument-dependent lookup works properly for user-defined non-member begin/end
422  using std::begin, std::end;
423  return makeRange (EnumerateIterator { begin (range), startingValue },
424  EnumerateIterator { end (range), startingValue });
425 }
426 
427 } // namespace juce
constexpr EnumerateIterator(Iter iter, Index ind)
constexpr bool operator<(const EnumerateIterator< OtherIter, OtherInd > &other) const
constexpr EnumerateIterator & operator+=(I diff)
constexpr EnumerateIterator & operator--()
constexpr EnumerateIterator & operator++()
constexpr EnumerateIterator()=default
constexpr EnumerateIterator(Iter iter)
constexpr bool operator!=(const EnumerateIterator< OtherIter, OtherInd > &other) const
constexpr bool operator>(const EnumerateIterator< OtherIter, OtherInd > &other) const
constexpr EnumerateIterator & operator-=(I diff)
constexpr friend auto operator+(EnumerateIterator iter, I ind)
constexpr auto operator[](I diff) const
constexpr bool operator<=(const EnumerateIterator< OtherIter, OtherInd > &other) const
constexpr bool operator==(const EnumerateIterator< OtherIter, OtherInd > &other) const
constexpr auto operator-(const EnumerateIterator< OtherIter, OtherInd > &other) const
constexpr bool operator>=(const EnumerateIterator< OtherIter, OtherInd > &other) const
constexpr IteratorPair(Begin bIn, End eIn)
constexpr auto end() const
constexpr auto begin() const