Loading...
Searching...
No Matches
juce_Enumerate.h
/*
==============================================================================
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
{
namespace detail
{
template <typename T, typename = void>
constexpr auto canPreDecrement = false;
template <typename T>
constexpr auto canPreDecrement<T, std::void_t<decltype (--std::declval<T>())>> = true;
template <typename T, typename I, typename = void>
constexpr auto canAddAssign = false;
template <typename T, typename I>
constexpr auto canAddAssign<T, I, std::void_t<decltype (std::declval<T>() += std::declval<I>())>> = true;
template <typename T, typename I, typename = void>
constexpr auto canSubAssign = false;
template <typename T, typename I>
constexpr auto canSubAssign<T, I, std::void_t<decltype (std::declval<T>() -= std::declval<I>())>> = true;
template <typename T, typename I, typename = void>
constexpr auto canAdd = false;
template <typename T, typename I>
constexpr auto canAdd<T, I, std::void_t<decltype (std::declval<T>() + std::declval<I>())>> = true;
template <typename T, typename I, typename = void>
constexpr auto canSub = false;
template <typename T, typename I>
constexpr auto canSub<T, I, std::void_t<decltype (std::declval<T>() - std::declval<I>())>> = true;
template <typename T, typename I, typename = void>
constexpr auto canLessThan = false;
template <typename T, typename I>
constexpr auto canLessThan<T, I, std::void_t<decltype (std::declval<T>() < std::declval<I>())>> = true;
template <typename T, typename I, typename = void>
constexpr auto canLessThanEqual = false;
template <typename T, typename I>
constexpr auto canLessThanEqual<T, I, std::void_t<decltype (std::declval<T>() <= std::declval<I>())>> = true;
template <typename T, typename I, typename = void>
constexpr auto canGreaterThan = false;
template <typename T, typename I>
constexpr auto canGreaterThan<T, I, std::void_t<decltype (std::declval<T>() > std::declval<I>())>> = true;
template <typename T, typename I, typename = void>
constexpr auto canGreaterThanEqual = false;
template <typename T, typename I>
constexpr auto canGreaterThanEqual<T, I, std::void_t<decltype (std::declval<T>() >= std::declval<I>())>> = true;
namespace withAdlSize
{
using std::size;
template <typename Range>
using AdlSize = decltype (size (std::declval<Range>()));
template <typename Range>
using AdlSignedSize = std::common_type_t<std::ptrdiff_t, std::make_signed_t<AdlSize<Range>>>;
}
} // namespace detail
template <typename Index, typename Value>
struct Enumerated
{
Index index;
Value value;
};
template <typename Iter, typename Index = ptrdiff_t>
class EnumerateIterator
{
public:
constexpr EnumerateIterator() = default;
constexpr explicit EnumerateIterator (Iter iter)
: EnumerateIterator (std::move (iter), Index{}) {}
constexpr EnumerateIterator (Iter iter, Index ind)
: iterator (std::move (iter)), index (ind) {}
template <typename OtherIter, typename OtherInd>
[[nodiscard]] constexpr bool operator== (const EnumerateIterator<OtherIter, OtherInd>& other) const
{
return iterator == other.iterator;
}
template <typename OtherIter, typename OtherInd>
[[nodiscard]] constexpr bool operator!= (const EnumerateIterator<OtherIter, OtherInd>& other) const
{
return ! operator== (other);
}
[[nodiscard]] constexpr Enumerated<Index, decltype (*std::declval<Iter>())> operator*() const
{
return { index, *iterator };
}
constexpr EnumerateIterator& operator++()
{
++iterator;
++index;
return *this;
}
constexpr EnumerateIterator operator++ (int)
{
auto copy = *this;
operator++();
return copy;
}
template <typename T = Iter, std::enable_if_t<detail::canPreDecrement<T>, int> = 0>
constexpr EnumerateIterator& operator--()
{
--iterator;
--index;
return *this;
}
template <typename T = Iter, std::enable_if_t<detail::canPreDecrement<T>, int> = 0>
constexpr EnumerateIterator operator-- (int)
{
auto copy = *this;
operator--();
return copy;
}
template <typename I, std::enable_if_t<detail::canAddAssign<Iter&, I>, int> = 0>
constexpr EnumerateIterator& operator+= (I diff)
{
iterator += diff;
index += static_cast<Index> (diff);
return *this;
}
template <typename I, std::enable_if_t<detail::canSubAssign<Iter&, I>, int> = 0>
constexpr EnumerateIterator& operator-= (I diff)
{
iterator -= diff;
index -= static_cast<Index> (diff);
return *this;
}
template <typename OtherIter, typename OtherInd, std::enable_if_t<detail::canSub<Iter, OtherIter>, int> = 0>
[[nodiscard]] constexpr auto operator- (const EnumerateIterator<OtherIter, OtherInd>& other) const
{
return iterator - other.iterator;
}
template <typename I, std::enable_if_t<detail::canAdd<EnumerateIterator, I>, int> = 0>
[[nodiscard]] constexpr auto operator[] (I diff) const
{
return *(*this + diff);
}
template <typename OtherIter, typename OtherInd, std::enable_if_t<detail::canLessThan<Iter, OtherIter>, int> = 0>
[[nodiscard]] constexpr bool operator< (const EnumerateIterator<OtherIter, OtherInd>& other) const
{
return iterator < other.iterator;
}
template <typename OtherIter, typename OtherInd, std::enable_if_t<detail::canLessThanEqual<Iter, OtherIter>, int> = 0>
[[nodiscard]] constexpr bool operator<= (const EnumerateIterator<OtherIter, OtherInd>& other) const
{
return iterator <= other.iterator;
}
template <typename OtherIter, typename OtherInd, std::enable_if_t<detail::canGreaterThan<Iter, OtherIter>, int> = 0>
[[nodiscard]] constexpr bool operator> (const EnumerateIterator<OtherIter, OtherInd>& other) const
{
return iterator > other.iterator;
}
template <typename OtherIter, typename OtherInd, std::enable_if_t<detail::canGreaterThanEqual<Iter, OtherIter>, int> = 0>
[[nodiscard]] constexpr bool operator>= (const EnumerateIterator<OtherIter, OtherInd>& other) const
{
return iterator >= other.iterator;
}
template <typename I, std::enable_if_t<detail::canAddAssign<EnumerateIterator&, I>, int> = 0>
constexpr friend auto operator+ (EnumerateIterator iter, I ind)
{
return iter += ind;
}
template <typename I, std::enable_if_t<detail::canAddAssign<EnumerateIterator&, I>, int> = 0>
constexpr friend auto operator+ (I ind, EnumerateIterator iter)
{
return iter += ind;
}
template <typename I, std::enable_if_t<detail::canSubAssign<EnumerateIterator&, I>, int> = 0>
constexpr friend auto operator- (EnumerateIterator iter, I ind)
{
return iter -= ind;
}
private:
Iter iterator{};
Index index = 0;
};
//==============================================================================
template <typename Begin, typename End>
class IteratorPair
{
public:
constexpr IteratorPair (Begin bIn, End eIn)
: b (std::move (bIn)), e (std::move (eIn)) {}
constexpr auto begin() const { return b; }
constexpr auto end() const { return e; }
private:
Begin b;
End e;
};
template <typename Begin, typename End = Begin>
[[nodiscard]] constexpr auto makeRange (Begin begin, End end)
{
return IteratorPair<Begin, End> { std::move (begin), std::move (end) };
}
//==============================================================================
template <typename Range, typename Index = detail::withAdlSize::AdlSignedSize<Range>>
[[nodiscard]] constexpr auto enumerate (Range&& range, Index startingValue = {})
{
// This ensures argument-dependent lookup works properly for user-defined non-member begin/end
using std::begin, std::end;
return makeRange (EnumerateIterator { begin (range), startingValue },
EnumerateIterator { end (range), startingValue });
}
} // namespace juce
juce::EnumerateIterator
Definition juce_Enumerate.h:128
juce::EnumerateIterator::EnumerateIterator
constexpr EnumerateIterator(Iter iter, Index ind)
Definition juce_Enumerate.h:138
juce::EnumerateIterator::operator-=
constexpr EnumerateIterator & operator-=(I diff)
Definition juce_Enumerate.h:217
juce::EnumerateIterator::operator++
constexpr EnumerateIterator & operator++()
Definition juce_Enumerate.h:165
juce::EnumerateIterator::operator<
constexpr bool operator<(const EnumerateIterator< OtherIter, OtherInd > &other) const
Definition juce_Enumerate.h:250
juce::EnumerateIterator::EnumerateIterator
constexpr EnumerateIterator()=default
juce::EnumerateIterator::EnumerateIterator
constexpr EnumerateIterator(Iter iter)
Definition juce_Enumerate.h:134
juce::EnumerateIterator::operator!=
constexpr bool operator!=(const EnumerateIterator< OtherIter, OtherInd > &other) const
Definition juce_Enumerate.h:150
juce::EnumerateIterator::operator>
constexpr bool operator>(const EnumerateIterator< OtherIter, OtherInd > &other) const
Definition juce_Enumerate.h:268
juce::EnumerateIterator::operator--
constexpr EnumerateIterator & operator--()
Definition juce_Enumerate.h:184
juce::EnumerateIterator::operator+
constexpr friend auto operator+(EnumerateIterator iter, I ind)
Definition juce_Enumerate.h:286
juce::EnumerateIterator::operator[]
constexpr auto operator[](I diff) const
Definition juce_Enumerate.h:241
juce::EnumerateIterator::operator<=
constexpr bool operator<=(const EnumerateIterator< OtherIter, OtherInd > &other) const
Definition juce_Enumerate.h:259
juce::EnumerateIterator::operator+=
constexpr EnumerateIterator & operator+=(I diff)
Definition juce_Enumerate.h:206
juce::EnumerateIterator::operator==
constexpr bool operator==(const EnumerateIterator< OtherIter, OtherInd > &other) const
Definition juce_Enumerate.h:143
juce::EnumerateIterator::operator-
constexpr auto operator-(const EnumerateIterator< OtherIter, OtherInd > &other) const
Definition juce_Enumerate.h:230
juce::EnumerateIterator::operator>=
constexpr bool operator>=(const EnumerateIterator< OtherIter, OtherInd > &other) const
Definition juce_Enumerate.h:277
juce::IteratorPair::IteratorPair
constexpr IteratorPair(Begin bIn, End eIn)
Definition juce_Enumerate.h:331
juce::IteratorPair::end
constexpr auto end() const
Definition juce_Enumerate.h:338
juce::IteratorPair::begin
constexpr auto begin() const
Definition juce_Enumerate.h:335
juce::Range
Definition juce_Range.h:40
juce::Value
Definition juce_Value.h:51
juce::Enumerated
Definition juce_Enumerate.h:110