11 #ifndef LARDATA_UTILITIES_RANGEFORWRAPPER_H 12 #define LARDATA_UTILITIES_RANGEFORWRAPPER_H 15 #include "boost/variant.hpp" 21 #include <type_traits> 30 template <
typename BeginIter,
typename EndIter>
33 using traits_t = std::iterator_traits<BeginIter>;
44 using pointer =
typename traits_t::pointer;
55 std::bidirectional_iterator_tag,
56 typename traits_t::iterator_category
116 "RangeForWrapperIterator requires two different iterator types." 119 boost::variant<begin_t, end_t>
fIter;
132 template <
typename Iter>
137 template <
typename Result,
typename Iter,
typename =
void>
145 template <
typename Iter>
150 template <
typename Result,
typename Iter,
typename =
void>
158 template <
typename Iter>
163 template <
typename Iter,
typename =
void>
171 template <
typename Iter>
176 template <
typename Iter,
typename =
void>
183 struct Comparer:
public boost::static_visitor<bool> {
185 template <
typename A,
typename B>
190 template <
typename A,
typename B,
typename =
void>
202 template <
typename Iter>
207 template <
typename Result,
typename Iter,
typename =
void>
213 struct Difference:
public boost::static_visitor<difference_type > {
215 template <
typename A,
typename B>
220 template <
typename A,
typename B,
typename =
void>
230 template <
typename RangeRef>
236 using Range_t = std::remove_reference_t<RangeRef_t>;
240 {
using namespace std;
return begin(range); }
244 {
using namespace std;
return end(range); }
247 using BeginIter_t = decltype(extractBegin(std::declval<RangeRef_t>()));
250 using EndIter_t = decltype(extractEnd(std::declval<RangeRef_t>()));
253 static constexpr
bool sameIteratorTypes
254 = std::is_same<BeginIter_t, EndIter_t>();
263 using pointer =
typename BeginIter_t::pointer;
276 template <
typename RangeRef>
280 "RangeForWrapperBox requires a reference type.");
326 bool empty()
const {
return !(wrappedBegin() != wrappedEnd()); }
329 {
return wrappedBegin()[
index]; }
338 using Stored_t = std::conditional_t<
340 std::remove_reference_t<RangeRef_t>,
343 using Data_t = std::remove_reference_t<Stored_t>;
359 {
return Traits_t::extractBegin(static_cast<RangeRef_t>(fRange)); }
361 {
return Traits_t::extractEnd(static_cast<RangeRef_t>(fRange)); }
378 bool SameIteratorsType
384 template <
typename BaseRange>
396 template <
typename BaseRange>
398 template <
typename Range>
402 (
static_cast<decltype(range)
>(range));
425 template <
typename Range>
429 (std::forward<Range>(range));
457 template <
typename Range>
473 template <
typename T>
476 template <
typename T>
481 template <
typename BeginIter,
typename EndIter>
482 template <
typename A,
typename B,
typename >
487 {
throw std::logic_error(
"These iterators can't be compared!"); }
491 template <
typename BeginIter,
typename EndIter>
492 template <
typename A,
typename B>
494 A, B, std::enable_if_t<
496 <decltype(std::declval<A>() != std::declval<B>()), bool>::value
501 {
return left !=
right; }
506 template <
typename BeginIter,
typename EndIter>
507 template <
typename Result,
typename Iter,
typename >
512 {
throw std::logic_error(
"This iterator can't be dereferenced!"); }
516 template <
typename BeginIter,
typename EndIter>
517 template <
typename Result,
typename Iter>
519 Result, Iter, std::enable_if_t<is_type_v<decltype(*(std::declval<Iter>()))>>
528 template <
typename BeginIter,
typename EndIter>
529 template <
typename Result,
typename Iter,
typename >
533 [[noreturn]]
static Result
access(Iter
const&)
534 {
throw std::logic_error(
"This iterator can't be dereferenced!"); }
538 template <
typename BeginIter,
typename EndIter>
539 template <
typename Result,
typename Iter>
541 Result, Iter, std::enable_if_t<is_type_v<decltype(std::declval<Iter>().operator->())>>
544 static Result
access(Iter
const& iter)
545 {
return iter.operator->(); }
550 template <
typename BeginIter,
typename EndIter>
551 template <
typename Iter,
typename >
556 {
throw std::logic_error(
"This iterator can't be incremented!"); }
560 template <
typename BeginIter,
typename EndIter>
561 template <
typename Iter>
563 Iter, std::enable_if_t<is_type_v<decltype(++(std::declval<Iter>()))>>
572 template <
typename BeginIter,
typename EndIter>
573 template <
typename Iter,
typename >
578 {
throw std::logic_error(
"This iterator can't be decremented!"); }
582 template <
typename BeginIter,
typename EndIter>
583 template <
typename Iter>
585 Iter, std::enable_if_t<is_type_v<decltype(--(std::declval<Iter>()))>>
594 template <
typename BeginIter,
typename EndIter>
595 template <
typename Result,
typename Iter,
typename >
602 [[noreturn]] Result
access(Iter
const&)
const 603 {
throw std::logic_error(
"This iterator can't be indexed!"); }
607 template <
typename BeginIter,
typename EndIter>
608 template <
typename Result,
typename Iter>
610 Result, Iter, std::enable_if_t<is_type_v<decltype((std::declval<Iter>())[0])>>
618 {
return iter[offset]; }
623 template <
typename BeginIter,
typename EndIter>
624 template <
typename A,
typename B,
typename >
629 {
throw std::logic_error(
"These iterators can't be subtracted!"); }
633 template <
typename BeginIter,
typename EndIter>
634 template <
typename A,
typename B>
636 A, B, std::enable_if_t<
638 decltype(std::declval<A>() - std::declval<B>()),
639 typename RangeForWrapperIterator<BeginIter, EndIter>::difference_type>::value
644 {
return minuend - subtrahend; }
658 #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 &)
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)
int compare(unsigned *r, sha1::digest_t const &d)
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
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 Traits_t::value_type value_type
Type of value contained in the wrapped sequence.
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.
decltype(auto) constexpr end(T &&obj)
ADL-aware version of std::end.
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.
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.
double distance(double x1, double y1, double z1, double x2, double y2, double z2)
this_t operator++(int)
Increments the iterator (postfix operator).
static Result dereference(Iter const &)
typename traits_t::pointer pointer
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)
typename traits_t::value_type value_type
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...
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
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
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).