11 #ifndef LARDATA_UTILITIES_RANGEFORWRAPPER_H 12 #define LARDATA_UTILITIES_RANGEFORWRAPPER_H 15 #include "boost/variant.hpp" 20 #include <type_traits> 29 template <
typename BeginIter,
typename EndIter>
32 using traits_t = std::iterator_traits<BeginIter>;
43 using pointer =
typename traits_t::pointer;
53 std::conditional_t<std::is_base_of<std::bidirectional_iterator_tag,
54 typename traits_t::iterator_category>
::value,
55 std::bidirectional_iterator_tag,
56 typename traits_t::iterator_category>;
125 "RangeForWrapperIterator requires two different iterator types.");
127 boost::variant<begin_t, end_t>
fIter;
140 template <
typename Iter>
147 template <
typename Result,
typename Iter,
typename =
void>
155 template <
typename Iter>
162 template <
typename Result,
typename Iter,
typename =
void>
170 template <
typename Iter>
177 template <
typename Iter,
typename =
void>
185 template <
typename Iter>
192 template <
typename Iter,
typename =
void>
198 struct Comparer :
public boost::static_visitor<bool> {
200 template <
typename A,
typename B>
207 template <
typename A,
typename B,
typename =
void>
219 template <
typename Iter>
226 template <
typename Result,
typename Iter,
typename =
void>
232 struct Difference :
public boost::static_visitor<difference_type> {
234 template <
typename A,
typename B>
241 template <
typename A,
typename B,
typename =
void>
249 template <
typename RangeRef>
253 "RangeForWrapperBox requires a reference type.");
258 using Range_t = std::remove_reference_t<RangeRef_t>;
275 using BeginIter_t = decltype(extractBegin(std::declval<RangeRef_t>()));
278 using EndIter_t = decltype(extractEnd(std::declval<RangeRef_t>()));
281 static constexpr
bool sameIteratorTypes = std::is_same<BeginIter_t, EndIter_t>();
290 using pointer =
typename BeginIter_t::pointer;
302 template <
typename RangeRef>
306 "RangeForWrapperBox requires a reference type.");
344 bool empty()
const {
return !(wrappedBegin() != wrappedEnd()); }
348 return wrappedBegin()[index];
357 std::remove_reference_t<RangeRef_t>,
359 using Data_t = std::remove_reference_t<Stored_t>;
376 return Traits_t::extractBegin(static_cast<RangeRef_t>(fRange));
380 return Traits_t::extractEnd(static_cast<RangeRef_t>(fRange));
395 template <
typename BaseRange,
396 bool SameIteratorsType =
401 template <
typename BaseRange>
412 template <
typename BaseRange>
414 template <
typename Range>
439 template <
typename Range>
469 template <
typename Range>
485 template <
typename T>
488 template <
typename T>
492 template <
typename BeginIter,
typename EndIter>
493 template <
typename A,
typename B,
typename >
499 throw std::logic_error(
"These iterators can't be compared!");
504 template <
typename BeginIter,
typename EndIter>
505 template <
typename A,
typename B>
510 std::is_convertible<decltype(std::declval<A>() != std::declval<B>()), bool>::value>> {
515 template <
typename BeginIter,
typename EndIter>
516 template <
typename Result,
typename Iter,
typename >
522 throw std::logic_error(
"This iterator can't be dereferenced!");
527 template <
typename BeginIter,
typename EndIter>
528 template <
typename Result,
typename Iter>
532 std::enable_if_t<is_type_v<decltype(*(std::declval<Iter>()))>>> {
537 template <
typename BeginIter,
typename EndIter>
538 template <
typename Result,
typename Iter,
typename >
542 [[noreturn]]
static Result
access(Iter
const&)
544 throw std::logic_error(
"This iterator can't be dereferenced!");
549 template <
typename BeginIter,
typename EndIter>
550 template <
typename Result,
typename Iter>
554 std::enable_if_t<is_type_v<decltype(std::declval<Iter>().operator->())>>> {
555 static Result access(Iter
const& iter) {
return iter.operator->(); }
559 template <
typename BeginIter,
typename EndIter>
560 template <
typename Iter,
typename >
566 throw std::logic_error(
"This iterator can't be incremented!");
571 template <
typename BeginIter,
typename EndIter>
572 template <
typename Iter>
574 IncrementerImpl<Iter, std::enable_if_t<is_type_v<decltype(++(std::declval<Iter>()))>>> {
579 template <
typename BeginIter,
typename EndIter>
580 template <
typename Iter,
typename >
586 throw std::logic_error(
"This iterator can't be decremented!");
591 template <
typename BeginIter,
typename EndIter>
592 template <
typename Iter>
594 DecrementerImpl<Iter, std::enable_if_t<is_type_v<decltype(--(std::declval<Iter>()))>>> {
599 template <
typename BeginIter,
typename EndIter>
600 template <
typename Result,
typename Iter,
typename >
607 [[noreturn]] Result
access(Iter
const&)
const 609 throw std::logic_error(
"This iterator can't be indexed!");
614 template <
typename BeginIter,
typename EndIter>
615 template <
typename Result,
typename Iter>
619 std::enable_if_t<is_type_v<decltype((std::declval<Iter>())[0])>>> {
624 Result
dereference(Iter
const& iter)
const {
return iter[offset]; }
628 template <
typename BeginIter,
typename EndIter>
629 template <
typename A,
typename B,
typename >
635 throw std::logic_error(
"These iterators can't be subtracted!");
640 template <
typename BeginIter,
typename EndIter>
641 template <
typename A,
typename B>
645 std::enable_if_t<std::is_convertible<
646 decltype(std::declval<A>() - std::declval<B>()),
647 typename RangeForWrapperIterator<BeginIter, EndIter>::difference_type>::value>> {
650 return minuend - subtrahend;
661 #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
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 &)
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.
void operator()(Iter &iter) const
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.
auto wrapRangeFor(Range &&range) -> decltype(auto)
Wraps an object for use in a range-for loop.
reference operator[](difference_type offset) const
static bool compare(A const &, B const &)
auto wrappedBegin() const -> decltype(auto)
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.
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 void increment(Iter &iter)
static Result dereference(Iter const &iter)
boost::variant< begin_t, end_t > fIter
The actual iterator we store.
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.
bool operator()(A const &left, B const &right) const
static void decrement(Iter &iter)
Result access(Iter const &) const
void operator()(Iter &iter) 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.
bool operator()(Iter &iter) const
this_t operator++(int)
Increments the iterator (postfix operator).
static Result dereference(Iter const &)
std::conditional_t< std::is_rvalue_reference< RangeRef_t >::value, std::remove_reference_t< RangeRef_t >, RangeRef_t > Stored_t
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
decltype(extractBegin(std::declval< RangeRef_t >())) BeginIter_t
Type of wrapped begin iterator.
IndexAccessorImpl(difference_type offset)
auto operator()(Iter &iter) const -> decltype(auto)
constexpr auto const & left(const_AssnsIter< L, R, D, Dir > const &a, const_AssnsIter< L, R, D, Dir > const &b)
auto operator()(Iter &iter) const -> decltype(auto)
typename traits_t::value_type value_type
Iterator traits, imported from the wrapped begin iterator.
auto operator[](difference_type index) const -> decltype(auto)
static difference_type subtract(A const &minuend, B const &subtrahend)
auto operator|(Range &&range, RangeForWrapperTag) -> decltype(auto)
Transforms a range so that it can be used in a range-for loop.
Iterator_t end() const
Returns a end-of-range iterator.
Result dereference(Iter const &iter) const
difference_type operator()(A const &minuend, B const &subtrahend) const
Visitor to access element by index.
auto wrappedEnd() const -> decltype(auto)
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.
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.
Visitor to compare iterators (returns whether they differ).