From 8dccb3808165e76bcefd111fd966ec89d390b15e Mon Sep 17 00:00:00 2001 From: attila Date: Tue, 28 Jan 2025 17:15:43 +0100 Subject: [PATCH] Make IntersectingRangedValues independent from the RangedValues type With this change you can use makeIntersectingRangedValues() not just for RangedValues objects, but any object that has a begin() and end() function returning a RangedValuesIterator. --- modules/juce_graphics/detail/juce_Ranges.h | 48 ++++++++-------------- 1 file changed, 18 insertions(+), 30 deletions(-) diff --git a/modules/juce_graphics/detail/juce_Ranges.h b/modules/juce_graphics/detail/juce_Ranges.h index 263a2e6a73..e5f8515e18 100644 --- a/modules/juce_graphics/detail/juce_Ranges.h +++ b/modules/juce_graphics/detail/juce_Ranges.h @@ -903,9 +903,9 @@ public: /* We pass a pointer rather than a reference here to make it clearer that the pointed-to object must outlive the RangedIteratorWrapper, otherwise the wrapped iterators will dangle. */ - explicit RangedIteratorWrapper (const RangedValues* rv) - : iterator { rv->cbegin() }, - end { rv->cend() } + RangedIteratorWrapper (RangedValuesIterator iteratorIn, RangedValuesIterator endIn) + : iterator { std::move (iteratorIn) }, + end { std::move (endIn) } {} //============================================================================== @@ -917,12 +917,9 @@ public: const T& getValue() const { return iterator->value; } private: - decltype (std::declval&>().cbegin()) iterator, end; + RangedValuesIterator iterator, end; }; -template -class IntersectingRangedValues; - /* A wrapper type encapsulating multiple RangedValues objects and providing iterator support. The iterator will advance through Ranges that are intersections with homogeneous values in each @@ -949,36 +946,31 @@ class IntersectingRangedValues; @endcode */ template -class IntersectingRangedValues...> +class IntersectingRangedValues { -private: +public: static_assert (sizeof...(Values) > 0, "IntersectingRangedValues() must wrap at least one RangedValues object"); - static auto createIteratorWrappers (const RangedValues*... containers) - { - return std::make_tuple (RangedIteratorWrapper { containers }...); - } - -public: /* This constructor takes a pointer rather than a reference to make it clearer that the pointed-to objects must outlive the IntersectingRangedValues instance. Passing a pointer also makes it harder to accidentally reference a temporary when constructing IntersectingRangedValues. */ - explicit IntersectingRangedValues (const RangedValues*... t) - : items { t... } + template + explicit IntersectingRangedValues (Iterables*... iterable) + : iteratorWrappers { std::make_tuple (RangedIteratorWrapper { iterable->begin(), iterable->end() }...) } { } struct IntersectionIteratorSentinel {}; + using IteratorWrappersType = std::tuple...>; + struct IntersectionIterator { using reference = std::tuple, const Values&...>; using iterator_category = std::forward_iterator_tag; - using IteratorWrappersType = decltype (createIteratorWrappers (std::declval*>()...)); - - explicit IntersectionIterator (IteratorWrappersType&& wrappers) + explicit IntersectionIterator (IteratorWrappersType wrappers) : iteratorWrappers { std::move (wrappers) } { std::apply ([this] (auto&&... args) @@ -1065,11 +1057,7 @@ public: auto begin() const { - auto wrappers = std::apply ([] (auto&&... args) - { return createIteratorWrappers (std::forward (args)...); }, - items); - - return IntersectionIterator { std::move (wrappers) }; + return IntersectionIterator { iteratorWrappers }; } auto end() const @@ -1078,17 +1066,17 @@ public: } private: - std::tuple*...> items; + IteratorWrappersType iteratorWrappers; }; /* See IntersectingRangedValues. */ -template -[[nodiscard]] auto makeIntersectingRangedValues (const RangedValues*... rvs) +template +[[nodiscard]] auto makeIntersectingRangedValues (Iterables*... iterables) { - static_assert (sizeof...(Values) > 0, "makeIntersectingRangedValues() requires at least one parameter"); + static_assert (sizeof...(Iterables) > 0, "makeIntersectingRangedValues() requires at least one parameter"); - return IntersectingRangedValues...> { rvs... }; + return IntersectingRangedValues().begin()->value)>...> { iterables... }; } } // namespace juce::detail