13 #ifndef LARDATA_UTILITIES_RANGEFORWRAPPER_H 14 #define LARDATA_UTILITIES_RANGEFORWRAPPER_H 17 #include "boost/variant.hpp" 23 #include <type_traits> 32 template <
typename BeginIter,
typename EndIter>
39 using traits_t = std::iterator_traits<BeginIter>;
50 using pointer =
typename traits_t::pointer;
61 std::bidirectional_iterator_tag,
62 typename traits_t::iterator_category
122 "RangeForWrapperIterator requires two different iterator types." 125 boost::variant<begin_t, end_t>
fIter;
138 template <
typename Iter>
143 template <
typename Result,
typename Iter,
typename =
void>
151 template <
typename Iter>
156 template <
typename Result,
typename Iter,
typename =
void>
164 template <
typename Iter>
169 template <
typename Iter,
typename =
void>
177 template <
typename Iter>
182 template <
typename Iter,
typename =
void>
189 struct Comparer:
public boost::static_visitor<bool> {
191 template <
typename A,
typename B>
196 template <
typename A,
typename B,
typename =
void>
208 template <
typename Iter>
213 template <
typename Result,
typename Iter,
typename =
void>
219 struct Difference:
public boost::static_visitor<difference_type > {
221 template <
typename A,
typename B>
226 template <
typename A,
typename B,
typename =
void>
236 template <
typename RangeRef>
242 using Range_t = std::remove_reference_t<RangeRef_t>;
246 {
using namespace std;
return begin(static_cast<RangeRef_t>(range)); }
250 {
using namespace std;
return end(static_cast<RangeRef_t>(range)); }
253 using BeginIter_t = decltype(extractBegin(std::declval<RangeRef_t>()));
256 using EndIter_t = decltype(extractEnd(std::declval<RangeRef_t>()));
259 static constexpr
bool sameIteratorTypes
260 = std::is_same<BeginIter_t, EndIter_t>();
269 using pointer =
typename BeginIter_t::pointer;
282 template <
typename RangeRef>
286 "RangeForWrapperBox requires a reference type.");
312 : fRange(
std::move(range))
328 bool empty()
const {
return !(wrappedBegin() != wrappedEnd()); }
331 {
return wrappedBegin()[index]; }
340 using Stored_t = std::conditional_t<
342 std::remove_reference_t<RangeRef_t>,
345 using Data_t = std::remove_reference_t<Stored_t>;
361 {
return Traits_t::extractBegin(static_cast<RangeRef_t>(fRange)); }
363 {
return Traits_t::extractEnd(static_cast<RangeRef_t>(fRange)); }
380 bool SameIteratorsType
386 template <
typename BaseRange>
398 template <
typename BaseRange>
400 template <
typename Range>
404 (
static_cast<decltype(range)
>(range));
427 template <
typename Range>
431 (std::forward<Range>(range));
459 template <
typename Range>
475 template <
typename T>
478 template <
typename T>
483 template <
typename BeginIter,
typename EndIter>
484 template <
typename A,
typename B,
typename >
489 {
throw std::logic_error(
"These iterators can't be compared!"); }
493 template <
typename BeginIter,
typename EndIter>
494 template <
typename A,
typename B>
496 A, B, std::enable_if_t<
498 <decltype(std::declval<A>() != std::declval<B>()), bool>::value
503 {
return left !=
right; }
508 template <
typename BeginIter,
typename EndIter>
509 template <
typename Result,
typename Iter,
typename >
514 {
throw std::logic_error(
"This iterator can't be dereferenced!"); }
518 template <
typename BeginIter,
typename EndIter>
519 template <
typename Result,
typename Iter>
521 Result, Iter, std::enable_if_t<is_type_v<decltype(*(std::declval<Iter>()))>>
530 template <
typename BeginIter,
typename EndIter>
531 template <
typename Result,
typename Iter,
typename >
535 [[noreturn]]
static Result
access(Iter
const&)
536 {
throw std::logic_error(
"This iterator can't be dereferenced!"); }
540 template <
typename BeginIter,
typename EndIter>
541 template <
typename Result,
typename Iter>
543 Result, Iter, std::enable_if_t<is_type_v<decltype(std::declval<Iter>().operator->())>>
546 static Result access(Iter
const& iter)
547 {
return iter.operator->(); }
552 template <
typename BeginIter,
typename EndIter>
553 template <
typename Iter,
typename >
558 {
throw std::logic_error(
"This iterator can't be incremented!"); }
562 template <
typename BeginIter,
typename EndIter>
563 template <
typename Iter>
565 Iter, std::enable_if_t<is_type_v<decltype(++(std::declval<Iter>()))>>
574 template <
typename BeginIter,
typename EndIter>
575 template <
typename Iter,
typename >
580 {
throw std::logic_error(
"This iterator can't be decremented!"); }
584 template <
typename BeginIter,
typename EndIter>
585 template <
typename Iter>
587 Iter, std::enable_if_t<is_type_v<decltype(--(std::declval<Iter>()))>>
596 template <
typename BeginIter,
typename EndIter>
597 template <
typename Result,
typename Iter,
typename >
604 [[noreturn]] Result
access(Iter
const&)
const 605 {
throw std::logic_error(
"This iterator can't be indexed!"); }
609 template <
typename BeginIter,
typename EndIter>
610 template <
typename Result,
typename Iter>
612 Result, Iter, std::enable_if_t<is_type_v<decltype((std::declval<Iter>())[0])>>
620 {
return iter[offset]; }
625 template <
typename BeginIter,
typename EndIter>
626 template <
typename A,
typename B,
typename >
631 {
throw std::logic_error(
"These iterators can't be subtracted!"); }
635 template <
typename BeginIter,
typename EndIter>
636 template <
typename A,
typename B>
638 A, B, std::enable_if_t<
640 decltype(std::declval<A>() - std::declval<B>()),
641 typename RangeForWrapperIterator<BeginIter, EndIter>::difference_type>::value
646 {
return minuend - subtrahend; }
660 #endif // LARDATA_UTILITIES_RANGEFORWRAPPER_H reference operator*() const
Returns the pointed value (just like the original iterator).
static BaseRange_t wrap(BaseRange_t &&range)
std::remove_reference_t< RangeRef_t > Range_t
DataBox fRange
A reference to the original range.
static BaseRange_t & wrap(BaseRange_t &range)
std::iterator_traits< BeginIter > traits_t
auto operator|(Range &&range, RangeForWrapperTag) -> decltype(auto)
Transforms a range so that it can be used in a range-for loop.
Namespace for general, non-LArSoft-specific utilities.
static Result access(Iter const &)
constexpr auto const & right(const_AssnsIter< L, R, D, Dir > const &a, const_AssnsIter< L, R, D, Dir > const &b)
Visitor to dereference an iterator.
IndexAccessorImpl(difference_type)
this_t & operator++()
Increments the iterator (prefix operator).
bool operator==(this_t const &other) const
Returns whether the other iterator is equal to this one.
static auto wrap(Range &&range)
static void decrement(Iter &)
auto wrappedEnd() const -> decltype(auto)
static auto extractEnd(RangeRef_t range)
Extracts the end iterator from a range object.
this_t operator--(int)
Decrements the iterator (postfix operator).
typename Traits_t::difference_type difference_type
Type of difference between element positions.
typename Traits_t::Iterator_t Iterator_t
Type of wrapper iterators (same for begin and end iterators).
difference_type operator-(this_t const &other) const
Visitor to compare iterators (returns whether they differ).
RangeForWrapperIterator(begin_t &&begin)
Constructor: initializes with a begin-type iterator.
static void increment(Iter &)
bool operator!=(this_t const &other) const
Returns whether the other iterator is not equal to this one.
RangeRef RangeRef_t
Type of the stored range (constantness is preserved).
Class offering begin/end iterators of the same type out of a range of iterators of different types...
typename traits_t::reference reference
Iterator traits, imported from the wrapped begin iterator.
reference operator[](difference_type offset) const
static void increment(Iter &iter)
static bool compare(A const &, B const &)
static auto extractBegin(RangeRef_t range)
Extractor of the begin iterator from a range.
Iterator_t begin() const
Returns a begin-of-range iterator.
static difference_type subtract(A const &, B const &)
typename BeginIter_t::pointer pointer
typename BeginIter_t::value_type reference
static BaseRange_t const & wrap(BaseRange_t const &range)
EndIter end_t
Type of end iterator we can store.
static Result dereference(Iter const &iter)
boost::variant< begin_t, end_t > fIter
The actual iterator we store.
auto wrapRangeFor(Range &&range) -> decltype(auto)
Wraps an object for use in a range-for loop.
std::remove_reference_t< Stored_t > Data_t
Visitor to increment an iterator.
constexpr RangeForWrapperTag range_for
pointer operator->() const
Returns the pointed value (just like the original iterator).
typename Traits_t::Range_t Range_t
typename traits_t::difference_type difference_type
Iterator traits, imported from the wrapped begin iterator.
std::vector< evd::details::RawDigitInfo_t >::const_iterator begin(RawDigitCacheDataClass const &cache)
static void decrement(Iter &iter)
Result access(Iter const &) const
RangeForWrapperBox(Range_t &range)
Constructor: references the specified range (lvalue reference).
typename BeginIter_t::value_type value_type
Visitor to access a data member of the pointed class.
this_t operator++(int)
Increments the iterator (postfix operator).
static Result dereference(Iter const &)
typename traits_t::pointer pointer
Iterator traits, imported from the wrapped begin iterator.
std::decay_t< BaseRange > BaseRange_t
typename Traits_t::RangeRef_t RangeRef_t
auto wrappedBegin() const -> decltype(auto)
decltype(extractBegin(std::declval< RangeRef_t >())) BeginIter_t
Type of wrapped begin iterator.
IndexAccessorImpl(difference_type offset)
constexpr auto const & left(const_AssnsIter< L, R, D, Dir > const &a, const_AssnsIter< L, R, D, Dir > const &b)
std::string value(boost::any const &)
typename traits_t::value_type value_type
Iterator traits, imported from the wrapped begin iterator.
static difference_type subtract(A const &minuend, B const &subtrahend)
Iterator_t end() const
Returns a end-of-range iterator.
Result dereference(Iter const &iter) const
Visitor to access element by index.
represents a "Range" w/ notion of ordering. A range is defined by a pair of "start" and "end" values...
std::vector< evd::details::RawDigitInfo_t >::const_iterator end(RawDigitCacheDataClass const &cache)
typename Traits_t::size_type size_type
Type of number of stored elements.
std::conditional_t< std::is_base_of< std::bidirectional_iterator_tag, typename traits_t::iterator_category >::value, std::bidirectional_iterator_tag, typename traits_t::iterator_category > iterator_category
Iterator traits, imported from the wrapped begin iterator.
RangeForWrapperIterator()
Constructor: initializes with a end-type default-constructed iterator.
BeginIter begin_t
Type of begin iterator we can store.
typename BeginIter_t::difference_type difference_type
IndexAccessor(difference_type offset)
this_t & operator--()
Decrements the iterator (prefix operator).
RangeForWrapperBox(Range_t &&range)
Constructor: references the specified range (rvalue reference).
static bool compare(A const &left, B const &right)
decltype(extractEnd(std::declval< RangeRef_t >())) EndIter_t
Type of wrapped end iterator.
Class defining types and traits for RangeForWrapperBox.
Visitor to decrement an iterator.
RangeForWrapperIterator(end_t &&end)
Constructor: initializes with a end-type iterator.
Tag marking the use of RangeForWrapperBox.
auto operator()(Iter &iter) const -> decltype(auto)
std::conditional_t< std::is_rvalue_reference< RangeRef_t >::value, std::remove_reference_t< RangeRef_t >, RangeRef_t > Stored_t
Visitor to compare iterators (returns whether they differ).