14 #ifndef ROOT_RHYSD_ARRAY_VIEW_H 15 #define ROOT_RHYSD_ARRAY_VIEW_H 18 #if __cplusplus >= 201402L 19 #define R__CONSTEXPR_IF_CXX14 constexpr 21 #define R__CONSTEXPR_IF_CXX14 32 #include <type_traits> 34 #include <initializer_list> 38 inline namespace __ROOT {
46 static bool const value =
false;
48 template<
class T,
size_t N>
63 template<
size_t... Indices >
65 static constexpr
size_t value[
sizeof...(Indices)] = {Indices...};
68 template<
class IndicesType,
size_t Next>
71 template<
size_t... Indices,
size_t Next>
76 template<
class IndicesType,
size_t Next,
size_t Tail>
79 template<
size_t... Indices,
size_t Next,
size_t Tail>
84 template<
size_t First,
size_t Step,
size_t N,
class =
void>
87 template<
size_t First,
size_t Step,
size_t N>
97 template<
size_t First,
size_t Step,
size_t N>
107 template<
size_t First,
size_t Step,
size_t N>
112 typename
std::enable_if<(N > 1 && N % 2 == 0)>
::type 115 typename detail::make_indices_impl<First, Step, N / 2>::type,
120 template<
size_t First,
size_t Step,
size_t N>
125 typename std::enable_if<(N > 1 && N % 2 == 1)>
::type 128 typename detail::make_indices_impl<First, Step, N / 2>::type,
129 First + N / 2 * Step,
130 First + (N - 1) * Step
134 template<
size_t First,
size_t Last,
size_t Step = 1>
139 ((Last - First) + (Step - 1)) / Step
143 template <
size_t Start,
size_t Last,
size_t Step = 1 >
175 : length_(0), data_(
nullptr)
183 template<
size_type N>
185 : length_(
N), data_(
N > 0 ?
a.data() :
nullptr)
190 template<
size_type N>
192 : length_(
N), data_(
N > 0 ? std::addressof(
a[0]) :
nullptr)
194 static_assert(
N > 0,
"Zero-length array is not permitted in ISO C++.");
198 : length_(
v.size()), data_(
v.empty() ? nullptr :
v.data())
202 : length_(
n), data_(
a)
207 class =
typename std::enable_if<
210 typename std::iterator_traits<InputIterator>::value_type
215 : length_(
std::distance(start, last)), data_(start)
219 : length_(l.size()), data_(
std::begin(l))
228 constexpr const_iterator
begin() const noexcept
232 constexpr const_iterator
end() const noexcept
234 return data_ + length_;
236 constexpr const_iterator
cbegin() const noexcept
240 constexpr const_iterator
cend() const noexcept
248 const_reverse_iterator
rend()
const 256 const_reverse_iterator
crend()
const 264 constexpr size_type
size() const noexcept
268 constexpr size_type
length() const noexcept
276 constexpr
bool empty() const noexcept
280 constexpr const_reference
operator[](size_type
const n)
const noexcept
284 constexpr const_reference
at(size_type
const n)
const 289 return n >= length_ ?
throw std::out_of_range(
"array_view::at()") : *(data_ +
n);
291 constexpr const_pointer
data() const noexcept
295 constexpr const_reference
front() const noexcept
299 constexpr const_reference
back() const noexcept
301 return *(data_ + length_ - 1);
316 return pos >= length_ || pos + slicelen >= length_ ?
throw std::out_of_range(
"array_view::slice()") :
array_view<T>{begin() + pos, begin() + pos + slicelen};
325 return pos >= length_ ? std::out_of_range(
"array_view::slice()") :
array_view<T>{begin(), begin() + pos};
334 return pos >= length_ ? std::out_of_range(
"array_view::slice()") :
array_view<T>{begin() + pos, end()};
340 return array_view<T>{begin() + pos, begin() + pos + slicelen};
364 return ( start >= end() ||
367 static_cast<size_t>(std::distance(start, last > end() ? end() : last)) > length_ - std::distance(begin(), start) ) ?
throw std::out_of_range(
"array_view::slice()") :
array_view<T>{start, last > end() ? end() : last};
376 return pos < begin() || pos > end() ?
throw std::out_of_range(
"array_view::slice()") :
array_view<T>{begin(), pos > end() ? end() : pos};
385 return pos < begin() || pos > end() ?
throw std::out_of_range(
"array_view::slice()") :
array_view<T>{pos < begin() ? begin() : pos, end()};
407 template<
class Allocator = std::allocator<T>>
408 auto to_vector(Allocator
const& alloc = Allocator{})
const 409 -> std::vector<T, Allocator>
411 return {begin(), end(), alloc};
421 template<
size_t...
I>
423 -> std::array<
T,
sizeof...(I)>
425 return {{(
I < length_ ? *(data_ +
I) : T{} )...}};
437 template<
class ArrayL,
class ArrayR >
439 bool operator_equal_impl(ArrayL
const& lhs,
size_t const lhs_size, ArrayR
const& rhs,
size_t const rhs_size)
441 if (lhs_size != rhs_size) {
445 auto litr = std::begin(lhs);
446 auto ritr = std::begin(rhs);
447 for (; litr != std::end(lhs); ++litr, ++ritr) {
448 if (!(*litr == *ritr)) {
457 template<
class T1,
class T2>
467 class =
typename std::enable_if<
477 template<
class T1,
class T2,
size_t N>
487 class =
typename std::enable_if<
488 is_array<Array>::value
494 return !(lhs == rhs);
500 class =
typename std::enable_if<
501 is_array<Array>::value
513 class =
typename std::enable_if<
514 is_array<Array>::value,
521 return !(rhs == lhs);
528 class =
typename std::enable_if<
539 template<
class T,
size_t N>
553 template<class InputIterator, class Result = array_view<typename std::iterator_traits<InputIterator>::value_type>>
555 Result
make_view(InputIterator begin, InputIterator end)
557 return Result{begin, end};
580 #include <type_traits> 592 static constexpr
int rank = Rank;
593 using reference = ptrdiff_t &;
594 using const_reference =
const ptrdiff_t &;
595 using size_type = size_t;
596 using value_type = ptrdiff_t;
599 std::array<value_type, Rank> m_B;
602 constexpr bounds() noexcept;
604 constexpr bounds(value_type
b) noexcept: m_B{{b}} { };
609 reference operator[](size_type i) noexcept {
return m_B[i]; }
611 constexpr const_reference operator[](
612 size_type i)
const noexcept {
return m_B[i]; };
615 bool operator==(
const bounds &rhs)
const noexcept;
617 bool operator!=(
const bounds &rhs)
const noexcept;
619 bounds
operator+(
const index<rank> &rhs)
const noexcept;
621 bounds
operator-(
const index<rank> &rhs)
const noexcept;
623 bounds &
operator+=(
const index<rank> &rhs) noexcept;
625 bounds &operator-=(
const index<rank> &rhs) noexcept;
627 constexpr size_type size()
const noexcept;
629 bool contains(
const index<rank> &idx)
const noexcept;
640 static constexpr
int rank = Rank;
641 using reference = ptrdiff_t &;
642 using const_reference =
const ptrdiff_t &;
643 using size_type = size_t;
644 using value_type = ptrdiff_t;
647 constexpr index() noexcept;
649 constexpr index(value_type) noexcept;
651 constexpr index(
const initializer_list<value_type> &) noexcept;
653 constexpr index(
const index &) noexcept;
655 index &
operator=(
const index &) noexcept;
657 reference operator[](size_type component_idx) noexcept;
659 constexpr const_reference operator[](size_type component_idx)
const noexcept;
661 bool operator==(
const index &rhs)
const noexcept;
663 bool operator!=(
const index &rhs)
const noexcept;
665 index
operator+(
const index &rhs)
const noexcept;
667 index
operator-(
const index &rhs)
const noexcept;
671 index &operator-=(
const index &rhs) noexcept;
673 index &operator++() noexcept;
675 index operator++(
int) noexcept;
677 index &operator--() noexcept;
679 index operator--(
int) noexcept;
688 template<
typename ValueType,
int Rank = 1>
691 static constexpr
int rank = Rank;
692 using index_type = index<rank>;
693 using bounds_type = bounds<rank>;
694 using size_type =
typename bounds_type::size_type;
695 using value_type = ValueType;
696 using pointer =
typename std::add_pointer_t<value_type>;
697 using reference =
typename std::add_lvalue_reference_t<value_type>;
701 constexpr
explicit array_view(std::vector<ValueType> &cont) noexcept;
703 template<
typename ArrayType>
706 template<
typename ViewValueType>
709 template<
typename Container>
710 constexpr
array_view(bounds_type bounds, Container &cont) noexcept;
712 constexpr
array_view(bounds_type bounds, pointer data) noexcept;
714 template<
typename ViewValueType>
717 constexpr bounds_type bounds()
const noexcept;
718 constexpr size_type size()
const noexcept;
719 constexpr index_type stride()
const noexcept;
721 constexpr pointer
data()
const noexcept;
722 constexpr reference operator[](
const index_type& idx)
const noexcept;
726 #endif // too complex!
constexpr const_pointer data() const noexcept
array_view(InputIterator start, InputIterator last)
constexpr array_view< T > slice_before(iterator const pos) const
constexpr const_iterator cbegin() const noexcept
std::reverse_iterator< const_iterator > const_reverse_iterator
constexpr const_iterator end() const noexcept
constexpr array_view() noexcept
constexpr array_view< T > slice(check_bound_t, iterator start, iterator last) const
static constexpr check_bound_t check_bound
void Step(const gsl_rng *r, void *xp, double step_size)
constexpr size_type max_size() const noexcept
value_type const * pointer
constexpr const_iterator begin() const noexcept
const_reverse_iterator rend() const
value_type const & reference
#define R__CONSTEXPR_IF_CXX14
constexpr const_reference operator[](size_type const n) const noexcept
constexpr array_view< T > slice_before(size_type const pos) const
array_view(std::initializer_list< T > const &l)
constexpr const_iterator cend() const noexcept
constexpr array_view< T > slice_before(check_bound_t, iterator const pos) const
constexpr array_view(T const *a, size_type const n) noexcept
constexpr array_view< T > slice(size_type const pos, size_type const slicelen) const
TTime operator-(const TTime &t1, const TTime &t2)
std::reverse_iterator< iterator > reverse_iterator
constexpr auto make_view(Array const &a) -> array_view< typename Array::value_type >
TString operator+(const TString &s1, const TString &s2)
Use the special concatenation constructor.
auto to_vector(Allocator const &alloc=Allocator{}) const -> std::vector< T, Allocator >
const_reverse_iterator crend() const
array_view(std::vector< T > const &v) noexcept
value_type const * iterator
auto to_array_impl(detail::indices< I... >) const -> std::array< T, sizeof...(I)>
constexpr array_view< T > slice_after(check_bound_t, iterator const pos) const
R__CONSTEXPR_IF_CXX14 bool operator_equal_impl(ArrayL const &lhs, size_t const lhs_size, ArrayR const &rhs, size_t const rhs_size)
constexpr const_reference back() const noexcept
const_pointer const data_
const_reverse_iterator rbegin() const
constexpr bool operator==(array_view< T1 > const &lhs, array_view< T2 > const &rhs)
constexpr array_view< T > slice_after(iterator const pos) const
constexpr array_view< T > slice_after(check_bound_t, size_type const pos) const
constexpr array_view< T > slice_after(size_type const pos) const
constexpr array_view< T > slice_before(check_bound_t, size_type const pos) const
array_view(T const (&a)[N]) noexcept
typename make_indices_< Start, Last, Step >::type make_indices
constexpr array_view< T > slice(check_bound_t, size_type const pos, size_type const slicelen) const
value_type const * const_pointer
Binding & operator=(OUT(*fun)(void))
auto to_array() const -> std::array< T, N >
constexpr size_type length() const noexcept
constexpr const_reference at(size_type const n) const
constexpr bool empty() const noexcept
constexpr array_view< T > slice(iterator start, iterator last) const
you should not use this method at all Int_t Int_t Double_t Double_t Double_t Int_t Double_t Double_t Double_t Double_t b
value_type const * const_iterator
ptrdiff_t difference_type
constexpr size_type size() const noexcept
constexpr bool operator!=(array_view< T > const &lhs, Array const &rhs)
value_type const & const_reference
array_view(std::array< T, N > const &a) noexcept
constexpr const_reference front() const noexcept
const_reverse_iterator crbegin() const
std::string & operator+=(std::string &left, const TString &right)