16#if __cplusplus > 201402L
17#define R__RVEC_NODISCARD [[nodiscard]]
19#define R__RVEC_NODISCARD
24 #ifndef _USE_MATH_DEFINES
25 #define _USE_MATH_DEFINES
28 #undef _USE_MATH_DEFINES
30 #define _VECOPS_USE_EXTERN_TEMPLATES false
32 #define _VECOPS_USE_EXTERN_TEMPLATES true
54#include <vdt/vdtMath.h>
79constexpr bool All(
const bool *vals, std::size_t
size)
81 for (
auto i = 0u; i <
size; ++i)
87template <
typename... T>
90 constexpr const auto nArgs =
sizeof...(T);
91 const std::size_t sizes[] = {vs.
size()...};
93 for (
auto i = 1UL; i < nArgs; i++) {
94 if (sizes[0] == sizes[i])
97 msg +=
": input RVec instances have different lengths!";
98 throw std::runtime_error(msg);
104template <
typename F,
typename... RVecs>
110 for (
auto i = 0UL; i <
size; i++)
111 ret[i] =
f(vs[i]...);
116template <
typename Tuple_t, std::size_t... Is>
118 ->
decltype(
MapImpl(std::get<std::tuple_size<Tuple_t>::value - 1>(t), std::get<Is>(t)...))
120 constexpr const auto tupleSizeM1 = std::tuple_size<Tuple_t>::value - 1;
121 return MapImpl(std::get<tupleSizeM1>(t), std::get<Is>(t)...);
153 static constexpr size_t SizeTypeMax() {
return std::numeric_limits<Size_T>::max(); }
156 SmallVectorBase(
void *FirstEl,
size_t TotalCapacity) : fBeginX(FirstEl), fCapacity(TotalCapacity) {}
161 void grow_pod(
void *FirstEl,
size_t MinSize,
size_t TSize);
165 static void report_size_overflow(
size_t MinSize);
168 static void report_at_maximum_capacity();
171 bool Owns()
const {
return fCapacity != -1; }
190 if (
N > capacity()) {
191 throw std::runtime_error(
"Setting size to a value greater than capacity.");
201 alignas(T)
char FirstEl[
sizeof(T)];
214 return const_cast<void *
>(
reinterpret_cast<const void *
>(
reinterpret_cast<const char *
>(
this) +
222 void grow_pod(
size_t MinSize,
size_t TSize) { Base::grow_pod(getFirstEl(), MinSize, TSize); }
226 bool isSmall()
const {
return this->fBeginX == getFirstEl(); }
231 this->fBeginX = getFirstEl();
234 this->
fSize = this->fCapacity = 0;
254 using Base::capacity;
287 throw std::runtime_error(
"`front` called on an empty RVec");
295 throw std::runtime_error(
"`front` called on an empty RVec");
303 throw std::runtime_error(
"`back` called on an empty RVec");
311 throw std::runtime_error(
"`back` called on an empty RVec");
325template <
typename T,
bool = (std::is_trivially_copy_constructible<T>::value) &&
326 (std::is_trivially_move_constructible<T>::value) &&
327 std::is_trivially_destructible<T>::value>
342 template <
typename It1,
typename It2>
345 std::uninitialized_copy(std::make_move_iterator(
I), std::make_move_iterator(E), Dest);
350 template <
typename It1,
typename It2>
353 std::uninitialized_copy(
I, E, Dest);
366 ::new ((
void *)this->end()) T(Elt);
367 this->set_size(this->
size() + 1);
374 ::new ((
void *)this->end()) T(::std::move(Elt));
375 this->set_size(this->
size() + 1);
380 this->set_size(this->
size() - 1);
386template <
typename T,
bool TriviallyCopyable>
391 if (MinSize > this->SizeTypeMax())
392 this->report_size_overflow(MinSize);
398 if (this->capacity() == this->SizeTypeMax())
399 this->report_at_maximum_capacity();
402 size_t NewCapacity = size_t(
NextPowerOf2(this->capacity() + 2));
403 NewCapacity = std::min(std::max(NewCapacity, MinSize), this->SizeTypeMax());
404 T *NewElts =
static_cast<T *
>(
malloc(NewCapacity *
sizeof(T)));
408 this->uninitialized_move(this->begin(), this->end(), NewElts);
412 destroy_range(this->begin(), this->end());
415 if (!this->isSmall())
419 this->fBeginX = NewElts;
420 this->fCapacity = NewCapacity;
439 template <
typename It1,
typename It2>
443 uninitialized_copy(
I, E, Dest);
448 template <
typename It1,
typename It2>
452 std::uninitialized_copy(
I, E, Dest);
457 template <
typename T1,
typename T2>
460 typename std::enable_if<std::is_same<
typename std::remove_const<T1>::type,
T2>
::value>
::type * =
nullptr)
467 memcpy(
reinterpret_cast<void *
>(Dest),
I, (E -
I) *
sizeof(T));
474 this->grow_pod(MinSize,
sizeof(T));
487 memcpy(
reinterpret_cast<void *
>(this->end()), &Elt,
sizeof(T));
488 this->set_size(this->
size() + 1);
496template <
typename T,
unsigned N>
498 alignas(T)
char InlineElts[
N *
sizeof(T)]{};
514#ifdef R__HAS_HARDWARE_INTERFERENCE_SIZE
515 constexpr std::size_t cacheLineSize = std::hardware_destructive_interference_size;
518 static constexpr std::size_t cacheLineSize = 64;
520 static constexpr unsigned elementsPerCacheLine = (cacheLineSize -
sizeof(
SmallVectorBase)) /
sizeof(T);
521 static constexpr unsigned maxInlineByteSize = 1024;
525 elementsPerCacheLine >= 8 ? elementsPerCacheLine : (
sizeof(T) * 8 > maxInlineByteSize ? 0 : 8);
529template <
typename ForwardIt>
532#if __cplusplus < 201703L
533 for (; first != last; ++first)
534 new (
static_cast<void *
>(std::addressof(*first)))
typename std::iterator_traits<ForwardIt>::value_type();
536 std::uninitialized_value_construct(first, last);
572 explicit RVecImpl(
unsigned N) :
ROOT::Internal::VecOps::SmallVectorTemplateBase<T>(
N) {}
581 if (!this->isSmall() && this->Owns())
589 this->destroy_range(this->begin(), this->end());
592 this->resetToSmall();
598 if (N < this->
size()) {
600 this->destroy_range(this->begin() +
N, this->end());
602 }
else if (
N > this->
size()) {
603 if (this->capacity() <
N)
605 for (
auto I = this->end(), E = this->begin() +
N;
I != E; ++
I)
613 if (N < this->
size()) {
615 this->destroy_range(this->begin() +
N, this->end());
617 }
else if (
N > this->
size()) {
618 if (this->capacity() <
N)
620 std::uninitialized_fill(this->end(), this->begin() +
N, NV);
627 if (this->capacity() <
N)
633 if (this->
size() < NumItems) {
634 throw std::runtime_error(
"Popping back more elements than those available.");
637 this->destroy_range(this->end() - NumItems, this->end());
638 this->set_size(this->
size() - NumItems);
643 T Result = ::std::move(this->back());
651 template <
typename in_iter,
652 typename =
typename std::enable_if<std::is_convertible<
653 typename std::iterator_traits<in_iter>::iterator_category, std::input_iterator_tag>
::value>
::type>
654 void append(in_iter in_start, in_iter in_end)
656 size_type NumInputs = std::distance(in_start, in_end);
657 if (NumInputs > this->capacity() - this->
size())
658 this->grow(this->
size() + NumInputs);
660 this->uninitialized_copy(in_start, in_end, this->end());
661 this->set_size(this->
size() + NumInputs);
667 if (NumInputs > this->capacity() - this->
size())
668 this->grow(this->
size() + NumInputs);
670 std::uninitialized_fill_n(this->end(), NumInputs, Elt);
671 this->set_size(this->
size() + NumInputs);
674 void append(std::initializer_list<T> IL) {
append(IL.begin(), IL.end()); }
683 if (this->capacity() < NumElts)
685 this->set_size(NumElts);
686 std::uninitialized_fill(this->begin(), this->end(), Elt);
689 template <
typename in_iter,
690 typename =
typename std::enable_if<std::is_convertible<
691 typename std::iterator_traits<in_iter>::iterator_category, std::input_iterator_tag>
::value>
::type>
692 void assign(in_iter in_start, in_iter in_end)
695 append(in_start, in_end);
709 if (I < this->begin() ||
I >= this->end()) {
710 throw std::runtime_error(
"The iterator passed to `erase` is out of bounds.");
715 std::move(
I + 1, this->end(),
I);
727 if (S < this->begin() || E > this->end() || S > E) {
728 throw std::runtime_error(
"Invalid start/end pair passed to `erase` (out of bounds or start > end).");
733 iterator I = std::move(E, this->end(), S);
736 this->destroy_range(
I, this->end());
737 this->set_size(
I - this->begin());
743 if (
I == this->end()) {
744 this->push_back(::std::move(Elt));
745 return this->end() - 1;
748 if (I < this->begin() ||
I > this->end()) {
749 throw std::runtime_error(
"The iterator passed to `insert` is out of bounds.");
752 if (this->
size() >= this->capacity()) {
753 size_t EltNo =
I - this->begin();
755 I = this->begin() + EltNo;
758 ::new ((
void *)this->end()) T(::std::move(this->back()));
760 std::move_backward(
I, this->end() - 1, this->end());
761 this->set_size(this->
size() + 1);
766 if (
I <= EltPtr && EltPtr < this->end())
769 *
I = ::std::move(*EltPtr);
775 if (
I == this->end()) {
776 this->push_back(Elt);
777 return this->end() - 1;
780 if (I < this->begin() ||
I > this->end()) {
781 throw std::runtime_error(
"The iterator passed to `insert` is out of bounds.");
784 if (this->
size() >= this->capacity()) {
785 size_t EltNo =
I - this->begin();
787 I = this->begin() + EltNo;
789 ::new ((
void *)this->end()) T(std::move(this->back()));
791 std::move_backward(
I, this->end() - 1, this->end());
792 this->set_size(this->
size() + 1);
796 const T *EltPtr = &Elt;
797 if (
I <= EltPtr && EltPtr < this->end())
807 size_t InsertElt =
I - this->begin();
809 if (
I == this->end()) {
810 append(NumToInsert, Elt);
811 return this->begin() + InsertElt;
814 if (I < this->begin() ||
I > this->end()) {
815 throw std::runtime_error(
"The iterator passed to `insert` is out of bounds.");
819 reserve(this->
size() + NumToInsert);
822 I = this->begin() + InsertElt;
828 if (
size_t(this->end() -
I) >= NumToInsert) {
829 T *OldEnd = this->end();
830 append(std::move_iterator<iterator>(this->end() - NumToInsert), std::move_iterator<iterator>(this->end()));
833 std::move_backward(
I, OldEnd - NumToInsert, OldEnd);
835 std::fill_n(
I, NumToInsert, Elt);
843 T *OldEnd = this->end();
844 this->set_size(this->
size() + NumToInsert);
845 size_t NumOverwritten = OldEnd -
I;
846 this->uninitialized_move(
I, OldEnd, this->end() - NumOverwritten);
849 std::fill_n(
I, NumOverwritten, Elt);
852 std::uninitialized_fill_n(OldEnd, NumToInsert - NumOverwritten, Elt);
856 template <
typename ItTy,
857 typename =
typename std::enable_if<std::is_convertible<
858 typename std::iterator_traits<ItTy>::iterator_category, std::input_iterator_tag>
::value>
::type>
862 size_t InsertElt =
I - this->begin();
864 if (
I == this->end()) {
866 return this->begin() + InsertElt;
869 if (I < this->begin() ||
I > this->end()) {
870 throw std::runtime_error(
"The iterator passed to `insert` is out of bounds.");
873 size_t NumToInsert = std::distance(From, To);
876 reserve(this->
size() + NumToInsert);
879 I = this->begin() + InsertElt;
885 if (
size_t(this->end() -
I) >= NumToInsert) {
886 T *OldEnd = this->end();
887 append(std::move_iterator<iterator>(this->end() - NumToInsert), std::move_iterator<iterator>(this->end()));
890 std::move_backward(
I, OldEnd - NumToInsert, OldEnd);
892 std::copy(From, To,
I);
900 T *OldEnd = this->end();
901 this->set_size(this->
size() + NumToInsert);
902 size_t NumOverwritten = OldEnd -
I;
903 this->uninitialized_move(
I, OldEnd, this->end() - NumOverwritten);
906 for (T *J =
I; NumOverwritten > 0; --NumOverwritten) {
913 this->uninitialized_copy(From, To, OldEnd);
919 template <
typename... ArgTypes>
924 ::new ((
void *)this->end()) T(std::forward<ArgTypes>(Args)...);
925 this->set_size(this->
size() + 1);
941 if (!this->isSmall() && !RHS.
isSmall()) {
942 std::swap(this->fBeginX, RHS.
fBeginX);
944 std::swap(this->fCapacity, RHS.
fCapacity);
950 if (this->isSmall() && !RHS.
Owns()) {
952 temp = std::move(RHS);
953 RHS = std::move(*
this);
954 *
this = std::move(temp);
956 }
else if (RHS.
isSmall() && !this->Owns()) {
958 temp = std::move(*
this);
959 *
this = std::move(RHS);
960 RHS = std::move(temp);
964 if (RHS.
size() > this->capacity())
965 this->grow(RHS.
size());
970 size_t NumShared = this->
size();
971 if (NumShared > RHS.
size())
972 NumShared = RHS.
size();
973 for (
size_type i = 0; i != NumShared; ++i)
974 std::iter_swap(this->begin() + i, RHS.
begin() + i);
978 size_t EltDiff = this->
size() - RHS.
size();
979 this->uninitialized_copy(this->begin() + NumShared, this->end(), RHS.
end());
982 this->destroy_range(this->begin() + NumShared, this->end());
983 this->set_size(NumShared);
984 }
else if (RHS.
size() > this->size()) {
985 size_t EltDiff = RHS.
size() - this->
size();
986 this->uninitialized_copy(RHS.
begin() + NumShared, RHS.
end(), this->end());
987 this->set_size(this->
size() + EltDiff);
989 this->destroy_range(RHS.
begin() + NumShared, RHS.
end());
1003 size_t RHSSize = RHS.
size();
1004 size_t CurSize = this->
size();
1005 if (CurSize >= RHSSize) {
1009 NewEnd = std::copy(RHS.
begin(), RHS.
begin() + RHSSize, this->begin());
1011 NewEnd = this->begin();
1015 this->destroy_range(NewEnd, this->end());
1018 this->set_size(RHSSize);
1026 if (this->capacity() < RHSSize) {
1029 this->destroy_range(this->begin(), this->end());
1033 this->grow(RHSSize);
1034 }
else if (CurSize) {
1036 std::copy(RHS.
begin(), RHS.
begin() + CurSize, this->begin());
1040 this->uninitialized_copy(RHS.
begin() + CurSize, RHS.
end(), this->begin() + CurSize);
1043 this->set_size(RHSSize);
1047template <
typename T>
1055 if (!RHS.isSmall()) {
1057 this->destroy_range(this->begin(), this->end());
1058 if (!this->isSmall())
1059 free(this->begin());
1061 this->fBeginX = RHS.fBeginX;
1062 this->
fSize = RHS.fSize;
1063 this->fCapacity = RHS.fCapacity;
1070 size_t RHSSize = RHS.size();
1071 size_t CurSize = this->
size();
1072 if (CurSize >= RHSSize) {
1076 NewEnd = std::move(RHS.begin(), RHS.end(), NewEnd);
1080 this->destroy_range(NewEnd, this->end());
1081 this->set_size(RHSSize);
1094 if (this->capacity() < RHSSize) {
1097 this->destroy_range(this->begin(), this->end());
1101 this->grow(RHSSize);
1102 }
else if (CurSize) {
1104 std::move(RHS.begin(), RHS.begin() + CurSize, this->begin());
1108 this->uninitialized_move(RHS.begin() + CurSize, RHS.end(), this->begin() + CurSize);
1111 this->set_size(RHSSize);
1117template <
typename T>
1123template <
typename T>
1150template <
typename T,
unsigned int N>
1159 this->destroy_range(this->begin(), this->end());
1163 explicit RVecN(
size_t Size,
const T &
Value) : Detail::VecOps::RVecImpl<T>(
N) { this->assign(Size,
Value); }
1165 explicit RVecN(
size_t Size) : Detail::VecOps::RVecImpl<T>(
N)
1173 template <
typename ItTy,
1174 typename =
typename std::enable_if<std::is_convertible<
1175 typename std::iterator_traits<ItTy>::iterator_category, std::input_iterator_tag>
::value>
::type>
1176 RVecN(ItTy S, ItTy E) : Detail::VecOps::RVecImpl<T>(
N)
1181 RVecN(std::initializer_list<T> IL) : Detail::VecOps::RVecImpl<T>(
N) { this->assign(IL); }
1207 RVecN(
const std::vector<T> &RHS) :
RVecN(RHS.begin(), RHS.end()) {}
1219 this->fCapacity = -1;
1243 return begin()[idx];
1248 return begin()[idx];
1251 template <typename V, unsigned M, typename = std::enable_if<std::is_convertible<V, bool>::value>>
1256 if (
n != this->
size()) {
1257 std::string msg =
"Cannot index RVecN of size " + std::to_string(this->
size()) +
1258 " with condition vector of different size (" + std::to_string(
n) +
").";
1259 throw std::runtime_error(msg);
1263 for (
auto c : conds)
1279 template <typename U, unsigned M, typename = std::enable_if<std::is_convertible<T, U>::value>>
1288 std::string msg =
"RVecN::at: size is " + std::to_string(this->
fSize) +
" but out-of-bounds index " +
1289 std::to_string(pos) +
" was requested.";
1290 throw std::out_of_range(msg);
1292 return this->operator[](pos);
1298 std::string msg =
"RVecN::at: size is " + std::to_string(this->
fSize) +
" but out-of-bounds index " +
1299 std::to_string(pos) +
" was requested.";
1300 throw std::out_of_range(msg);
1302 return this->operator[](pos);
1310 return this->operator[](pos);
1318 return this->operator[](pos);
1528template <
typename T>
1529class R__CLING_PTRCHECK(off)
RVec :
public RVecN<T, Internal::VecOps::RVecInlineStorageSize<T>::value> {
1532 friend void Internal::VecOps::ResetView<>(
RVec<T> &
v, T *addr, std::size_t sz);
1539 using SuperClass::begin;
1540 using SuperClass::size;
1548 template <
typename ItTy,
1549 typename =
typename std::enable_if<std::is_convertible<
1550 typename std::iterator_traits<ItTy>::iterator_category, std::input_iterator_tag>
::value>
::type>
1561 SuperClass::operator=(RHS);
1569 SuperClass::operator=(std::move(RHS));
1575 template <
unsigned N>
1578 template <
unsigned N>
1586 template <typename U, typename = std::enable_if<std::is_convertible<T, U>::value>>
1589 return RVec<U>(this->begin(), this->end());
1592 using SuperClass::operator[];
1594 template <typename V, typename = std::enable_if<std::is_convertible<V, bool>::value>>
1597 return RVec(SuperClass::operator[](conds));
1600 using SuperClass::at;
1602 friend bool ROOT::Detail::VecOps::IsSmall<T>(
const RVec<T> &
v);
1604 friend bool ROOT::Detail::VecOps::IsAdopting<T>(
const RVec<T> &
v);
1607template <
typename T,
unsigned N>
1610 return X.capacity_in_bytes();
1616#define RVEC_UNARY_OPERATOR(OP) \
1617template <typename T> \
1618RVec<T> operator OP(const RVec<T> &v) \
1621 for (auto &x : ret) \
1630#undef RVEC_UNARY_OPERATOR
1636#define ERROR_MESSAGE(OP) \
1637 "Cannot call operator " #OP " on vectors of different sizes."
1639#define RVEC_BINARY_OPERATOR(OP) \
1640template <typename T0, typename T1> \
1641auto operator OP(const RVec<T0> &v, const T1 &y) \
1642 -> RVec<decltype(v[0] OP y)> \
1644 RVec<decltype(v[0] OP y)> ret(v.size()); \
1645 auto op = [&y](const T0 &x) { return x OP y; }; \
1646 std::transform(v.begin(), v.end(), ret.begin(), op); \
1650template <typename T0, typename T1> \
1651auto operator OP(const T0 &x, const RVec<T1> &v) \
1652 -> RVec<decltype(x OP v[0])> \
1654 RVec<decltype(x OP v[0])> ret(v.size()); \
1655 auto op = [&x](const T1 &y) { return x OP y; }; \
1656 std::transform(v.begin(), v.end(), ret.begin(), op); \
1660template <typename T0, typename T1> \
1661auto operator OP(const RVec<T0> &v0, const RVec<T1> &v1) \
1662 -> RVec<decltype(v0[0] OP v1[0])> \
1664 if (v0.size() != v1.size()) \
1665 throw std::runtime_error(ERROR_MESSAGE(OP)); \
1667 RVec<decltype(v0[0] OP v1[0])> ret(v0.size()); \
1668 auto op = [](const T0 &x, const T1 &y) { return x OP y; }; \
1669 std::transform(v0.begin(), v0.end(), v1.begin(), ret.begin(), op); \
1681#undef RVEC_BINARY_OPERATOR
1687#define RVEC_ASSIGNMENT_OPERATOR(OP) \
1688template <typename T0, typename T1> \
1689RVec<T0>& operator OP(RVec<T0> &v, const T1 &y) \
1691 auto op = [&y](T0 &x) { return x OP y; }; \
1692 std::transform(v.begin(), v.end(), v.begin(), op); \
1696template <typename T0, typename T1> \
1697RVec<T0>& operator OP(RVec<T0> &v0, const RVec<T1> &v1) \
1699 if (v0.size() != v1.size()) \
1700 throw std::runtime_error(ERROR_MESSAGE(OP)); \
1702 auto op = [](T0 &x, const T1 &y) { return x OP y; }; \
1703 std::transform(v0.begin(), v0.end(), v1.begin(), v0.begin(), op); \
1717#undef RVEC_ASSIGNMENT_OPERATOR
1723#define RVEC_LOGICAL_OPERATOR(OP) \
1724template <typename T0, typename T1> \
1725auto operator OP(const RVec<T0> &v, const T1 &y) \
1728 RVec<int> ret(v.size()); \
1729 auto op = [y](const T0 &x) -> int { return x OP y; }; \
1730 std::transform(v.begin(), v.end(), ret.begin(), op); \
1734template <typename T0, typename T1> \
1735auto operator OP(const T0 &x, const RVec<T1> &v) \
1738 RVec<int> ret(v.size()); \
1739 auto op = [x](const T1 &y) -> int { return x OP y; }; \
1740 std::transform(v.begin(), v.end(), ret.begin(), op); \
1744template <typename T0, typename T1> \
1745auto operator OP(const RVec<T0> &v0, const RVec<T1> &v1) \
1748 if (v0.size() != v1.size()) \
1749 throw std::runtime_error(ERROR_MESSAGE(OP)); \
1751 RVec<int> ret(v0.size()); \
1752 auto op = [](const T0 &x, const T1 &y) -> int { return x OP y; }; \
1753 std::transform(v0.begin(), v0.end(), v1.begin(), ret.begin(), op); \
1765#undef RVEC_LOGICAL_OPERATOR
1772template <
typename T>
struct PromoteTypeImpl;
1774template <>
struct PromoteTypeImpl<float> {
using Type = float; };
1775template <>
struct PromoteTypeImpl<
double> {
using Type =
double; };
1776template <>
struct PromoteTypeImpl<long
double> {
using Type =
long double; };
1778template <
typename T>
struct PromoteTypeImpl {
using Type =
double; };
1780template <
typename T>
1781using PromoteType =
typename PromoteTypeImpl<T>::Type;
1783template <
typename U,
typename V>
1784using PromoteTypes =
decltype(PromoteType<U>() + PromoteType<V>());
1788#define RVEC_UNARY_FUNCTION(NAME, FUNC) \
1789 template <typename T> \
1790 RVec<PromoteType<T>> NAME(const RVec<T> &v) \
1792 RVec<PromoteType<T>> ret(v.size()); \
1793 auto f = [](const T &x) { return FUNC(x); }; \
1794 std::transform(v.begin(), v.end(), ret.begin(), f); \
1798#define RVEC_BINARY_FUNCTION(NAME, FUNC) \
1799 template <typename T0, typename T1> \
1800 RVec<PromoteTypes<T0, T1>> NAME(const T0 &x, const RVec<T1> &v) \
1802 RVec<PromoteTypes<T0, T1>> ret(v.size()); \
1803 auto f = [&x](const T1 &y) { return FUNC(x, y); }; \
1804 std::transform(v.begin(), v.end(), ret.begin(), f); \
1808 template <typename T0, typename T1> \
1809 RVec<PromoteTypes<T0, T1>> NAME(const RVec<T0> &v, const T1 &y) \
1811 RVec<PromoteTypes<T0, T1>> ret(v.size()); \
1812 auto f = [&y](const T0 &x) { return FUNC(x, y); }; \
1813 std::transform(v.begin(), v.end(), ret.begin(), f); \
1817 template <typename T0, typename T1> \
1818 RVec<PromoteTypes<T0, T1>> NAME(const RVec<T0> &v0, const RVec<T1> &v1) \
1820 if (v0.size() != v1.size()) \
1821 throw std::runtime_error(ERROR_MESSAGE(NAME)); \
1823 RVec<PromoteTypes<T0, T1>> ret(v0.size()); \
1824 auto f = [](const T0 &x, const T1 &y) { return FUNC(x, y); }; \
1825 std::transform(v0.begin(), v0.end(), v1.begin(), ret.begin(), f); \
1829#define RVEC_STD_UNARY_FUNCTION(F) RVEC_UNARY_FUNCTION(F, std::F)
1830#define RVEC_STD_BINARY_FUNCTION(F) RVEC_BINARY_FUNCTION(F, std::F)
1877#undef RVEC_STD_UNARY_FUNCTION
1884#define RVEC_VDT_UNARY_FUNCTION(F) RVEC_UNARY_FUNCTION(F, vdt::F)
1886RVEC_VDT_UNARY_FUNCTION(fast_expf)
1887RVEC_VDT_UNARY_FUNCTION(fast_logf)
1888RVEC_VDT_UNARY_FUNCTION(fast_sinf)
1889RVEC_VDT_UNARY_FUNCTION(fast_cosf)
1890RVEC_VDT_UNARY_FUNCTION(fast_tanf)
1891RVEC_VDT_UNARY_FUNCTION(fast_asinf)
1892RVEC_VDT_UNARY_FUNCTION(fast_acosf)
1893RVEC_VDT_UNARY_FUNCTION(fast_atanf)
1895RVEC_VDT_UNARY_FUNCTION(fast_exp)
1896RVEC_VDT_UNARY_FUNCTION(fast_log)
1897RVEC_VDT_UNARY_FUNCTION(fast_sin)
1898RVEC_VDT_UNARY_FUNCTION(fast_cos)
1899RVEC_VDT_UNARY_FUNCTION(fast_tan)
1900RVEC_VDT_UNARY_FUNCTION(fast_asin)
1901RVEC_VDT_UNARY_FUNCTION(fast_acos)
1902RVEC_VDT_UNARY_FUNCTION(fast_atan)
1903#undef RVEC_VDT_UNARY_FUNCTION
1907#undef RVEC_UNARY_FUNCTION
1922template <
typename T,
typename V>
1925 if (
v0.size() !=
v1.size())
1926 throw std::runtime_error(
"Cannot compute inner product of vectors of different sizes");
1927 return std::inner_product(
v0.begin(),
v0.end(),
v1.begin(),
decltype(
v0[0] *
v1[0])(0));
1953template <
typename T>
1956 return std::accumulate(
v.begin(),
v.end(), zero);
1961 return std::accumulate(
v.begin(),
v.end(), zero);
1965template <
typename T>
1968 return std::accumulate(
v.begin(),
v.end(), init, std::multiplies<T>());
1983template <
typename T>
1986 if (
v.empty())
return 0.;
2015template <
typename T,
typename R = T>
2018 if (
v.empty())
return zero;
2019 return Sum(
v, zero) /
v.size();
2032template <
typename T>
2035 return *std::max_element(
v.begin(),
v.end());
2048template <
typename T>
2051 return *std::min_element(
v.begin(),
v.end());
2066template <
typename T>
2069 return std::distance(
v.begin(), std::max_element(
v.begin(),
v.end()));
2084template <
typename T>
2087 return std::distance(
v.begin(), std::min_element(
v.begin(),
v.end()));
2101template <
typename T>
2104 const std::size_t
size =
v.size();
2105 if (
size < std::size_t(2))
return 0.;
2106 T sum_squares(0), squared_sum(0);
2107 auto pred = [&sum_squares, &squared_sum](
const T&
x) {sum_squares+=
x*
x; squared_sum+=
x;};
2108 std::for_each(
v.begin(),
v.end(), pred);
2109 squared_sum *= squared_sum;
2111 return 1. / (dsize - 1.) * (sum_squares - squared_sum / dsize );
2125template <
typename T>
2128 return std::sqrt(
Var(
v));
2149template <
typename... Args>
2162 constexpr auto nArgs =
sizeof...(Args);
2165 "Map: the first N-1 arguments must be RVecs or references to RVecs");
2168 std::make_index_sequence<
sizeof...(args) - 1>());
2181template <
typename T,
typename F>
2184 const auto thisSize =
v.size();
2187 for (
auto &&val :
v) {
2189 w.emplace_back(val);
2204template <
typename T>
2208 if (
static_cast<bool>(
e) ==
true)
2223template <
typename T>
2227 if (
static_cast<bool>(
e) ==
false)
2232template <
typename T>
2249template <
typename T>
2255 std::sort(i.
begin(), i.
end(), [&
v](size_type i1, size_type i2) { return v[i1] < v[i2]; });
2270template <
typename T,
typename Compare>
2277 [&
v, &
c](size_type i1, size_type i2) { return c(v[i1], v[i2]); });
2294template <
typename T>
2300 std::stable_sort(i.
begin(), i.
end(), [&
v](size_type i1, size_type i2) { return v[i1] < v[i2]; });
2317template <
typename T,
typename Compare>
2323 std::stable_sort(i.
begin(), i.
end(), [&
v, &
c](size_type i1, size_type i2) { return c(v[i1], v[i2]); });
2338template <
typename T>
2342 const size_type isize = i.size();
2344 for (size_type k = 0; k < isize; k++)
2350template <
typename T>
2354 const size_type isize = i.size();
2356 for (size_type k = 0; k < isize; k++)
2358 if (i[k] <
v.size() && i[k]>=0){
2381template <
typename T>
2385 const size_type
size =
v.size();
2386 const size_type absn = std::abs(
n);
2388 const auto msg = std::to_string(absn) +
" elements requested from Take but input contains only " +
2389 std::to_string(
size) +
" elements.";
2390 throw std::runtime_error(msg);
2394 for (size_type k = 0; k < absn; k++)
2395 r[k] =
v[
size - absn + k];
2397 for (size_type k = 0; k < absn; k++)
2422template <
typename T>
2426 const size_type
size =
v.size();
2427 const size_type absn = std::abs(
n);
2439 const auto num_to_fill = absn -
size;
2447template <
typename T>
2451 std::sort(idxs.begin(), idxs.end());
2452 idxs.erase(std::unique(idxs.begin(), idxs.end()), idxs.end());
2455 if (
v.size() > idxs.size())
2456 r.reserve(
v.size() - idxs.size());
2458 auto discardIt = idxs.begin();
2460 for (sz_t i = 0u; i <
v.size(); ++i) {
2461 if (discardIt != idxs.end() && i == *discardIt)
2464 r.emplace_back(
v[i]);
2480template <
typename T>
2484 std::reverse(
r.begin(),
r.end());
2501template <
typename T>
2505 std::sort(
r.begin(),
r.end());
2526template <
typename T,
typename Compare>
2530 std::sort(
r.begin(),
r.end(), std::forward<Compare>(
c));
2550template <
typename T>
2554 std::stable_sort(
r.begin(),
r.end());
2586template <
typename T,
typename Compare>
2590 std::stable_sort(
r.begin(),
r.end(), std::forward<Compare>(
c));
2608 using size_type = std::size_t;
2610 r[0].resize(size1*size2);
2611 r[1].resize(size1*size2);
2613 for(size_type i=0; i<size1; i++) {
2614 for(size_type j=0; j<size2; j++) {
2637template <
typename T1,
typename T2>
2662template <
typename T>
2666 const size_type s =
v.size();
2668 throw std::runtime_error(
"Cannot make unique combinations of size " + std::to_string(
n) +
2669 " from vector of size " + std::to_string(s) +
".");
2673 for(size_type k=0; k<s; k++)
2676 const auto innersize = [=] {
2677 size_type inners = s -
n + 1;
2678 for (size_type
m = s -
n + 2;
m <= s; ++
m)
2681 size_type factn = 1;
2682 for (size_type i = 2; i <=
n; ++i)
2690 size_type inneridx = 0;
2691 for (size_type k = 0; k <
n; k++)
2696 bool run_through =
true;
2700 run_through =
false;
2708 for (
long j=i+1; j<(long)
n; j++)
2710 for (size_type k = 0; k <
n; k++)
2726template <
typename T>
2731 const auto size =
v.size();
2733 for(size_type i=0; i<
size; i++) {
2757template <
typename T>
2761 if (!v2_is_sorted) v2_sorted = Sort(
v2);
2762 const auto v2_begin = v2_is_sorted ?
v2.begin() : v2_sorted.
begin();
2763 const auto v2_end = v2_is_sorted ?
v2.end() : v2_sorted.
end();
2765 const auto size =
v1.size();
2768 for(size_type i=0; i<
size; i++) {
2769 if (std::binary_search(v2_begin, v2_end,
v1[i])) {
2770 r.emplace_back(
v1[i]);
2791template <
typename T>
2795 const size_type
size =
c.size();
2798 for (size_type i=0; i<
size; i++) {
2799 r.emplace_back(
c[i] != 0 ?
v1[i] :
v2[i]);
2819template <
typename T>
2823 const size_type
size =
c.size();
2826 for (size_type i=0; i<
size; i++) {
2827 r.emplace_back(
c[i] != 0 ?
v1[i] :
v2);
2847template <
typename T>
2851 const size_type
size =
c.size();
2854 for (size_type i=0; i<
size; i++) {
2855 r.emplace_back(
c[i] != 0 ?
v1 :
v2[i]);
2873template <
typename T>
2877 const size_type
size =
c.size();
2880 for (size_type i=0; i<
size; i++) {
2881 r.emplace_back(
c[i] != 0 ?
v1 :
v2);
2896template <typename T0, typename T1, typename Common_t = typename std::common_type<T0, T1>::type>
2901 std::copy(
v0.begin(),
v0.end(), std::back_inserter(res));
2902 std::copy(
v1.begin(),
v1.end(), std::back_inserter(res));
2912template <
typename T0,
typename T1 = T0,
typename Common_t = std::common_type_t<T0, T1>>
2915 static_assert(std::is_floating_point<T0>::value && std::is_floating_point<T1>::value,
2916 "DeltaPhi must be called with floating point values.");
2917 auto r = std::fmod(
v2 -
v1, 2.0 *
c);
2933template <
typename T0,
typename T1 = T0,
typename Common_t =
typename std::common_type_t<T0, T1>>
2937 const size_type
size =
v1.size();
2939 for (size_type i = 0; i <
size; i++) {
2940 r[i] = DeltaPhi(
v1[i],
v2[i],
c);
2951template <
typename T0,
typename T1 = T0,
typename Common_t =
typename std::common_type_t<T0, T1>>
2955 const size_type
size =
v1.size();
2957 for (size_type i = 0; i <
size; i++) {
2958 r[i] = DeltaPhi(
v1[i],
v2,
c);
2969template <
typename T0,
typename T1 = T0,
typename Common_t =
typename std::common_type_t<T0, T1>>
2973 const size_type
size =
v2.size();
2975 for (size_type i = 0; i <
size; i++) {
2976 r[i] = DeltaPhi(
v1,
v2[i],
c);
2988template <
typename T0,
typename T1 = T0,
typename T2 = T0,
typename T3 = T0,
typename Common_t = std::common_type_t<T0, T1, T2, T3>>
2991 const auto dphi = DeltaPhi(phi1, phi2,
c);
2992 return (eta1 - eta2) * (eta1 - eta2) + dphi * dphi;
3002template <
typename T0,
typename T1 = T0,
typename T2 = T0,
typename T3 = T0,
typename Common_t = std::common_type_t<T0, T1, T2, T3>>
3005 return sqrt(DeltaR2(eta1, eta2, phi1, phi2,
c));
3015template <
typename T0,
typename T1 = T0,
typename T2 = T0,
typename T3 = T0,
typename Common_t = std::common_type_t<T0, T1, T2, T3>>
3016Common_t DeltaR(T0 eta1,
T1 eta2,
T2 phi1,
T3 phi2,
const Common_t
c =
M_PI)
3018 const auto dphi = DeltaPhi(phi1, phi2,
c);
3019 return std::sqrt((eta1 - eta2) * (eta1 - eta2) + dphi * dphi);
3027template <
typename T0,
typename T1 = T0,
typename T2 = T0,
typename T3 = T0,
typename T4 = T0,
3028 typename T5 = T0,
typename T6 = T0,
typename T7 = T0,
typename Common_t = std::common_type_t<T0, T1, T2, T3, T4, T5, T6, T7>>
3040 for (std::size_t i = 0u; i <
size; ++i) {
3042 const auto x1 = pt1[i] * std::cos(phi1[i]);
3043 const auto y1 = pt1[i] * std::sin(phi1[i]);
3044 const auto z1 = pt1[i] * std::sinh(eta1[i]);
3045 const auto e1 = std::sqrt(
x1 *
x1 +
y1 *
y1 + z1 * z1 + mass1[i] * mass1[i]);
3047 const auto x2 = pt2[i] * std::cos(phi2[i]);
3048 const auto y2 = pt2[i] * std::sin(phi2[i]);
3049 const auto z2 = pt2[i] * std::sinh(eta2[i]);
3050 const auto e2 = std::sqrt(
x2 *
x2 +
y2 *
y2 + z2 * z2 + mass2[i] * mass2[i]);
3053 const auto e = e1 + e2;
3054 const auto x =
x1 +
x2;
3055 const auto y =
y1 +
y2;
3056 const auto z = z1 + z2;
3058 inv_masses[i] = std::sqrt(
e *
e -
x *
x -
y *
y - z * z);
3070template <
typename T0,
typename T1 = T0,
typename T2 = T0,
typename T3 = T0,
typename Common_t = std::common_type_t<T0, T1, T2, T3>>
3073 const std::size_t
size =
pt.size();
3077 Common_t x_sum = 0.;
3078 Common_t y_sum = 0.;
3079 Common_t z_sum = 0.;
3080 Common_t e_sum = 0.;
3082 for (std::size_t i = 0u; i <
size; ++ i) {
3084 const auto x =
pt[i] * std::cos(phi[i]);
3086 const auto y =
pt[i] * std::sin(phi[i]);
3088 const auto z =
pt[i] * std::sinh(eta[i]);
3090 const auto e = std::sqrt(
x *
x +
y *
y + z * z + mass[i] * mass[i]);
3095 return std::sqrt(e_sum * e_sum - x_sum * x_sum - y_sum * y_sum - z_sum * z_sum);
3116template <
typename T,
typename... Args_t>
3122 for (
auto i = 0UL; i <
size; ++i) {
3136template <
typename T>
3139 const auto size =
v.size();
3142 for (
auto i = 0UL; i <
size; ++i) {
3159 for (
auto i = 0UL; i <
length; ++i) {
3170 ret.
reserve(begin < end ? end - begin : 0u);
3171 for (
auto i = begin; i < end; ++i)
3192 throw std::runtime_error(
"Range: the stride must not be zero");
3195 float ret_cap = std::ceil(
static_cast<float>(end-begin) / stride);
3201 ret.
reserve(
static_cast<size_t>(ret_cap));
3204 for (
auto i = begin; i < end; i+=stride)
3209 for (
auto i = begin; i > end; i+=stride)
3221 constexpr bool mustConvert = std::is_same<char, T>::value || std::is_same<signed char, T>::value ||
3222 std::is_same<unsigned char, T>::value || std::is_same<wchar_t, T>::value ||
3223 std::is_same<char16_t, T>::value || std::is_same<char32_t, T>::value;
3224 using Print_t =
typename std::conditional<mustConvert, long long int, T>::type;
3226 auto size =
v.size();
3228 for (std::size_t i = 0; i <
size - 1; ++i) {
3229 os << (Print_t)
v[i] <<
", ";
3231 os << (Print_t)
v[
size - 1];
3237#if (_VECOPS_USE_EXTERN_TEMPLATES)
3239#define RVEC_EXTERN_UNARY_OPERATOR(T, OP) \
3240 extern template RVec<T> operator OP<T>(const RVec<T> &);
3242#define RVEC_EXTERN_BINARY_OPERATOR(T, OP) \
3243 extern template auto operator OP<T, T>(const T &x, const RVec<T> &v) \
3244 -> RVec<decltype(x OP v[0])>; \
3245 extern template auto operator OP<T, T>(const RVec<T> &v, const T &y) \
3246 -> RVec<decltype(v[0] OP y)>; \
3247 extern template auto operator OP<T, T>(const RVec<T> &v0, const RVec<T> &v1)\
3248 -> RVec<decltype(v0[0] OP v1[0])>;
3250#define RVEC_EXTERN_ASSIGN_OPERATOR(T, OP) \
3251 extern template RVec<T> &operator OP<T, T>(RVec<T> &, const T &); \
3252 extern template RVec<T> &operator OP<T, T>(RVec<T> &, const RVec<T> &);
3254#define RVEC_EXTERN_LOGICAL_OPERATOR(T, OP) \
3255 extern template RVec<int> operator OP<T, T>(const RVec<T> &, const T &); \
3256 extern template RVec<int> operator OP<T, T>(const T &, const RVec<T> &); \
3257 extern template RVec<int> operator OP<T, T>(const RVec<T> &, const RVec<T> &);
3259#define RVEC_EXTERN_FLOAT_TEMPLATE(T) \
3260 extern template class RVec<T>; \
3261 RVEC_EXTERN_UNARY_OPERATOR(T, +) \
3262 RVEC_EXTERN_UNARY_OPERATOR(T, -) \
3263 RVEC_EXTERN_UNARY_OPERATOR(T, !) \
3264 RVEC_EXTERN_BINARY_OPERATOR(T, +) \
3265 RVEC_EXTERN_BINARY_OPERATOR(T, -) \
3266 RVEC_EXTERN_BINARY_OPERATOR(T, *) \
3267 RVEC_EXTERN_BINARY_OPERATOR(T, /) \
3268 RVEC_EXTERN_ASSIGN_OPERATOR(T, +=) \
3269 RVEC_EXTERN_ASSIGN_OPERATOR(T, -=) \
3270 RVEC_EXTERN_ASSIGN_OPERATOR(T, *=) \
3271 RVEC_EXTERN_ASSIGN_OPERATOR(T, /=) \
3272 RVEC_EXTERN_LOGICAL_OPERATOR(T, <) \
3273 RVEC_EXTERN_LOGICAL_OPERATOR(T, >) \
3274 RVEC_EXTERN_LOGICAL_OPERATOR(T, ==) \
3275 RVEC_EXTERN_LOGICAL_OPERATOR(T, !=) \
3276 RVEC_EXTERN_LOGICAL_OPERATOR(T, <=) \
3277 RVEC_EXTERN_LOGICAL_OPERATOR(T, >=) \
3278 RVEC_EXTERN_LOGICAL_OPERATOR(T, &&) \
3279 RVEC_EXTERN_LOGICAL_OPERATOR(T, ||)
3281#define RVEC_EXTERN_INTEGER_TEMPLATE(T) \
3282 extern template class RVec<T>; \
3283 RVEC_EXTERN_UNARY_OPERATOR(T, +) \
3284 RVEC_EXTERN_UNARY_OPERATOR(T, -) \
3285 RVEC_EXTERN_UNARY_OPERATOR(T, ~) \
3286 RVEC_EXTERN_UNARY_OPERATOR(T, !) \
3287 RVEC_EXTERN_BINARY_OPERATOR(T, +) \
3288 RVEC_EXTERN_BINARY_OPERATOR(T, -) \
3289 RVEC_EXTERN_BINARY_OPERATOR(T, *) \
3290 RVEC_EXTERN_BINARY_OPERATOR(T, /) \
3291 RVEC_EXTERN_BINARY_OPERATOR(T, %) \
3292 RVEC_EXTERN_BINARY_OPERATOR(T, &) \
3293 RVEC_EXTERN_BINARY_OPERATOR(T, |) \
3294 RVEC_EXTERN_BINARY_OPERATOR(T, ^) \
3295 RVEC_EXTERN_ASSIGN_OPERATOR(T, +=) \
3296 RVEC_EXTERN_ASSIGN_OPERATOR(T, -=) \
3297 RVEC_EXTERN_ASSIGN_OPERATOR(T, *=) \
3298 RVEC_EXTERN_ASSIGN_OPERATOR(T, /=) \
3299 RVEC_EXTERN_ASSIGN_OPERATOR(T, %=) \
3300 RVEC_EXTERN_ASSIGN_OPERATOR(T, &=) \
3301 RVEC_EXTERN_ASSIGN_OPERATOR(T, |=) \
3302 RVEC_EXTERN_ASSIGN_OPERATOR(T, ^=) \
3303 RVEC_EXTERN_ASSIGN_OPERATOR(T, >>=) \
3304 RVEC_EXTERN_ASSIGN_OPERATOR(T, <<=) \
3305 RVEC_EXTERN_LOGICAL_OPERATOR(T, <) \
3306 RVEC_EXTERN_LOGICAL_OPERATOR(T, >) \
3307 RVEC_EXTERN_LOGICAL_OPERATOR(T, ==) \
3308 RVEC_EXTERN_LOGICAL_OPERATOR(T, !=) \
3309 RVEC_EXTERN_LOGICAL_OPERATOR(T, <=) \
3310 RVEC_EXTERN_LOGICAL_OPERATOR(T, >=) \
3311 RVEC_EXTERN_LOGICAL_OPERATOR(T, &&) \
3312 RVEC_EXTERN_LOGICAL_OPERATOR(T, ||)
3314RVEC_EXTERN_INTEGER_TEMPLATE(
char)
3315RVEC_EXTERN_INTEGER_TEMPLATE(
short)
3316RVEC_EXTERN_INTEGER_TEMPLATE(
int)
3317RVEC_EXTERN_INTEGER_TEMPLATE(
long)
3320RVEC_EXTERN_INTEGER_TEMPLATE(
unsigned char)
3321RVEC_EXTERN_INTEGER_TEMPLATE(
unsigned short)
3322RVEC_EXTERN_INTEGER_TEMPLATE(
unsigned int)
3323RVEC_EXTERN_INTEGER_TEMPLATE(
unsigned long)
3326RVEC_EXTERN_FLOAT_TEMPLATE(
float)
3327RVEC_EXTERN_FLOAT_TEMPLATE(
double)
3329#undef RVEC_EXTERN_UNARY_OPERATOR
3330#undef RVEC_EXTERN_BINARY_OPERATOR
3331#undef RVEC_EXTERN_ASSIGN_OPERATOR
3332#undef RVEC_EXTERN_LOGICAL_OPERATOR
3333#undef RVEC_EXTERN_INTEGER_TEMPLATE
3334#undef RVEC_EXTERN_FLOAT_TEMPLATE
3336#define RVEC_EXTERN_UNARY_FUNCTION(T, NAME, FUNC) \
3337 extern template RVec<PromoteType<T>> NAME(const RVec<T> &);
3339#define RVEC_EXTERN_STD_UNARY_FUNCTION(T, F) RVEC_EXTERN_UNARY_FUNCTION(T, F, std::F)
3341#define RVEC_EXTERN_BINARY_FUNCTION(T0, T1, NAME, FUNC) \
3342 extern template RVec<PromoteTypes<T0, T1>> NAME(const RVec<T0> &, const T1 &); \
3343 extern template RVec<PromoteTypes<T0, T1>> NAME(const T0 &, const RVec<T1> &); \
3344 extern template RVec<PromoteTypes<T0, T1>> NAME(const RVec<T0> &, const RVec<T1> &);
3346#define RVEC_EXTERN_STD_BINARY_FUNCTION(T, F) RVEC_EXTERN_BINARY_FUNCTION(T, T, F, std::F)
3348#define RVEC_EXTERN_STD_FUNCTIONS(T) \
3349 RVEC_EXTERN_STD_UNARY_FUNCTION(T, abs) \
3350 RVEC_EXTERN_STD_BINARY_FUNCTION(T, fdim) \
3351 RVEC_EXTERN_STD_BINARY_FUNCTION(T, fmod) \
3352 RVEC_EXTERN_STD_BINARY_FUNCTION(T, remainder) \
3353 RVEC_EXTERN_STD_UNARY_FUNCTION(T, exp) \
3354 RVEC_EXTERN_STD_UNARY_FUNCTION(T, exp2) \
3355 RVEC_EXTERN_STD_UNARY_FUNCTION(T, expm1) \
3356 RVEC_EXTERN_STD_UNARY_FUNCTION(T, log) \
3357 RVEC_EXTERN_STD_UNARY_FUNCTION(T, log10) \
3358 RVEC_EXTERN_STD_UNARY_FUNCTION(T, log2) \
3359 RVEC_EXTERN_STD_UNARY_FUNCTION(T, log1p) \
3360 RVEC_EXTERN_STD_BINARY_FUNCTION(T, pow) \
3361 RVEC_EXTERN_STD_UNARY_FUNCTION(T, sqrt) \
3362 RVEC_EXTERN_STD_UNARY_FUNCTION(T, cbrt) \
3363 RVEC_EXTERN_STD_BINARY_FUNCTION(T, hypot) \
3364 RVEC_EXTERN_STD_UNARY_FUNCTION(T, sin) \
3365 RVEC_EXTERN_STD_UNARY_FUNCTION(T, cos) \
3366 RVEC_EXTERN_STD_UNARY_FUNCTION(T, tan) \
3367 RVEC_EXTERN_STD_UNARY_FUNCTION(T, asin) \
3368 RVEC_EXTERN_STD_UNARY_FUNCTION(T, acos) \
3369 RVEC_EXTERN_STD_UNARY_FUNCTION(T, atan) \
3370 RVEC_EXTERN_STD_BINARY_FUNCTION(T, atan2) \
3371 RVEC_EXTERN_STD_UNARY_FUNCTION(T, sinh) \
3372 RVEC_EXTERN_STD_UNARY_FUNCTION(T, cosh) \
3373 RVEC_EXTERN_STD_UNARY_FUNCTION(T, tanh) \
3374 RVEC_EXTERN_STD_UNARY_FUNCTION(T, asinh) \
3375 RVEC_EXTERN_STD_UNARY_FUNCTION(T, acosh) \
3376 RVEC_EXTERN_STD_UNARY_FUNCTION(T, atanh) \
3377 RVEC_EXTERN_STD_UNARY_FUNCTION(T, floor) \
3378 RVEC_EXTERN_STD_UNARY_FUNCTION(T, ceil) \
3379 RVEC_EXTERN_STD_UNARY_FUNCTION(T, trunc) \
3380 RVEC_EXTERN_STD_UNARY_FUNCTION(T, round) \
3381 RVEC_EXTERN_STD_UNARY_FUNCTION(T, erf) \
3382 RVEC_EXTERN_STD_UNARY_FUNCTION(T, erfc) \
3383 RVEC_EXTERN_STD_UNARY_FUNCTION(T, lgamma) \
3384 RVEC_EXTERN_STD_UNARY_FUNCTION(T, tgamma) \
3386RVEC_EXTERN_STD_FUNCTIONS(
float)
3387RVEC_EXTERN_STD_FUNCTIONS(
double)
3388#undef RVEC_EXTERN_STD_UNARY_FUNCTION
3389#undef RVEC_EXTERN_STD_BINARY_FUNCTION
3390#undef RVEC_EXTERN_STD_UNARY_FUNCTIONS
3394#define RVEC_EXTERN_VDT_UNARY_FUNCTION(T, F) RVEC_EXTERN_UNARY_FUNCTION(T, F, vdt::F)
3396RVEC_EXTERN_VDT_UNARY_FUNCTION(
float, fast_expf)
3397RVEC_EXTERN_VDT_UNARY_FUNCTION(
float, fast_logf)
3398RVEC_EXTERN_VDT_UNARY_FUNCTION(
float, fast_sinf)
3399RVEC_EXTERN_VDT_UNARY_FUNCTION(
float, fast_cosf)
3400RVEC_EXTERN_VDT_UNARY_FUNCTION(
float, fast_tanf)
3401RVEC_EXTERN_VDT_UNARY_FUNCTION(
float, fast_asinf)
3402RVEC_EXTERN_VDT_UNARY_FUNCTION(
float, fast_acosf)
3403RVEC_EXTERN_VDT_UNARY_FUNCTION(
float, fast_atanf)
3405RVEC_EXTERN_VDT_UNARY_FUNCTION(
double, fast_exp)
3406RVEC_EXTERN_VDT_UNARY_FUNCTION(
double, fast_log)
3407RVEC_EXTERN_VDT_UNARY_FUNCTION(
double, fast_sin)
3408RVEC_EXTERN_VDT_UNARY_FUNCTION(
double, fast_cos)
3409RVEC_EXTERN_VDT_UNARY_FUNCTION(
double, fast_tan)
3410RVEC_EXTERN_VDT_UNARY_FUNCTION(
double, fast_asin)
3411RVEC_EXTERN_VDT_UNARY_FUNCTION(
double, fast_acos)
3412RVEC_EXTERN_VDT_UNARY_FUNCTION(
double, fast_atan)
#define R__unlikely(expr)
#define R__RVEC_NODISCARD
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
TBuffer & operator<<(TBuffer &buf, const Tmpl *obj)
#define R__CLING_PTRCHECK(ONOFF)
static Double_t Product(const Double_t *x, const Float_t *y)
Product.
Int_t Compare(const void *item1, const void *item2)
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t r
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h length
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
Option_t Option_t TPoint TPoint const char x2
Option_t Option_t TPoint TPoint const char x1
Option_t Option_t TPoint TPoint const char y2
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
Option_t Option_t TPoint TPoint const char y1
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void assign(size_type NumElts, const T &Elt)
typename SuperClass::iterator iterator
typename SuperClass::size_type size_type
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
iterator insert(iterator I, T &&Elt)
void assign(std::initializer_list< T > IL)
typename SuperClass::const_iterator const_iterator
void resize(size_type N, const T &NV)
void reserve(size_type N)
iterator insert(iterator I, ItTy From, ItTy To)
reference emplace_back(ArgTypes &&...Args)
void assign(in_iter in_start, in_iter in_end)
iterator insert(iterator I, const T &Elt)
iterator insert(iterator I, size_type NumToInsert, const T &Elt)
RVecImpl & operator=(const RVecImpl &RHS)
iterator erase(const_iterator CS, const_iterator CE)
typename SuperClass::reference reference
void append(size_type NumInputs, const T &Elt)
Append NumInputs copies of Elt to the end.
iterator erase(const_iterator CI)
RVecImpl & operator=(RVecImpl &&RHS)
void pop_back_n(size_type NumItems)
RVecImpl(const RVecImpl &)=delete
void append(std::initializer_list< T > IL)
void insert(iterator I, std::initializer_list< T > IL)
This is all the stuff common to all SmallVectors.
SmallVectorBase(void *FirstEl, size_t TotalCapacity)
static constexpr size_t SizeTypeMax()
The maximum value of the Size_T used.
Size_T fCapacity
Always >= -1. fCapacity == -1 indicates the RVec is in "memory adoption" mode.
bool Owns() const
If false, the RVec is in "memory adoption" mode, i.e. it is acting as a view on a memory buffer it do...
size_t capacity() const noexcept
void set_size(size_t N)
Set the array size to N, which the current array must have enough capacity for.
typename SuperClass::iterator iterator
void grow(size_t MinSize=0)
Double the size of the allocated memory, guaranteeing space for at least one more element or MinSize ...
typename SuperClass::size_type size_type
typename SuperClass::reference reference
void push_back(const T &Elt)
static void uninitialized_move(It1 I, It1 E, It2 Dest)
Move the range [I, E) onto the uninitialized memory starting with "Dest", constructing elements into ...
SmallVectorTemplateBase(size_t Size)
typename SuperClass::const_iterator const_iterator
static void uninitialized_copy(T1 *I, T1 *E, T2 *Dest, typename std::enable_if< std::is_same< typename std::remove_const< T1 >::type, T2 >::value >::type *=nullptr)
Copy the range [I, E) onto the uninitialized memory starting with "Dest", constructing elements into ...
static void destroy_range(T *, T *)
static void uninitialized_copy(It1 I, It1 E, It2 Dest)
Copy the range [I, E) onto the uninitialized memory starting with "Dest", constructing elements into ...
SmallVectorTemplateBase<TriviallyCopyable = false> - This is where we put method implementations that...
void push_back(const T &Elt)
void grow(size_t MinSize=0)
Grow the allocated memory (without initializing new elements), doubling the size of the allocated mem...
static void uninitialized_move(It1 I, It1 E, It2 Dest)
Move the range [I, E) into the uninitialized memory starting with "Dest", constructing elements as ne...
SmallVectorTemplateBase(size_t Size)
static void destroy_range(T *S, T *E)
static void uninitialized_copy(It1 I, It1 E, It2 Dest)
Copy the range [I, E) onto the uninitialized memory starting with "Dest", constructing elements as ne...
This is the part of SmallVectorTemplateBase which does not depend on whether the type T is a POD.
size_type max_size() const noexcept
const_iterator cbegin() const noexcept
void grow_pod(size_t MinSize, size_t TSize)
ptrdiff_t difference_type
reverse_iterator rbegin() noexcept
const_iterator cend() const noexcept
const_reference back() const
void resetToSmall()
Put this vector in a state of being small.
iterator begin() noexcept
std::reverse_iterator< iterator > reverse_iterator
const T & const_reference
bool isSmall() const
Return true if this is a smallvector which has not had dynamic memory allocated for it.
const_reverse_iterator crend() const noexcept
const_iterator end() const noexcept
SmallVectorTemplateCommon(size_t Size)
const_reverse_iterator crbegin() const noexcept
pointer data() noexcept
Return a pointer to the vector's buffer, even if empty().
size_t capacity_in_bytes() const
reverse_iterator rend() noexcept
const_reverse_iterator rbegin() const noexcept
const_reference front() const
size_type size_in_bytes() const
std::reverse_iterator< const_iterator > const_reverse_iterator
size_t capacity() const noexcept
const_iterator begin() const noexcept
const_pointer data() const noexcept
Return a pointer to the vector's buffer, even if empty().
void * getFirstEl() const
Find the address of the first element.
const_reverse_iterator rend() const noexcept
RVecN(Detail::VecOps::RVecImpl< T > &&RHS)
reference operator[](size_type idx)
typename Internal::VecOps::SmallVectorTemplateCommon< T >::const_reference const_reference
RVecN operator[](const RVecN< V, M > &conds) const
RVecN(std::initializer_list< T > IL)
const_reference at(size_type pos) const
RVecN & operator=(Detail::VecOps::RVecImpl< T > &&RHS)
RVecN & operator=(RVecN &&RHS)
typename Internal::VecOps::SmallVectorTemplateCommon< T >::size_type size_type
value_type at(size_type pos, value_type fallback) const
No exception thrown. The user specifies the desired value in case the RVecN is shorter than pos.
RVecN & operator=(std::initializer_list< T > IL)
RVecN & operator=(const RVecN &RHS)
RVecN(const std::vector< T > &RHS)
RVecN(size_t Size, const T &Value)
reference at(size_type pos)
value_type at(size_type pos, value_type fallback)
No exception thrown. The user specifies the desired value in case the RVecN is shorter than pos.
typename Internal::VecOps::SmallVectorTemplateCommon< T >::reference reference
typename Internal::VecOps::SmallVectorTemplateCommon< T >::value_type value_type
const_reference operator[](size_type idx) const
A "std::vector"-like collection of values implementing handy operation to analyse them.
RVec(RVecN< T, N > &&RHS)
typename SuperClass::reference reference
RVec(const RVecN< T, N > &RHS)
RVec(size_t Size, const T &Value)
RVec & operator=(RVec &&RHS)
RVec operator[](const RVec< V > &conds) const
RVec(std::initializer_list< T > IL)
typename SuperClass::const_reference const_reference
RVec(const std::vector< T > &RHS)
typename SuperClass::size_type size_type
RVec(Detail::VecOps::RVecImpl< T > &&RHS)
typename SuperClass::value_type value_type
RVec & operator=(const RVec &RHS)
Type
enumeration specifying the integration types.
RVec< T > Reverse(const RVec< T > &v)
Return copy of reversed vector.
RVec< T > Intersect(const RVec< T > &v1, const RVec< T > &v2, bool v2_is_sorted=false)
Return the intersection of elements of two RVecs.
RVec< typename RVec< T >::size_type > Nonzero(const RVec< T > &v)
Return the indices of the elements which are not zero.
#define RVEC_UNARY_OPERATOR(OP)
#define RVEC_ASSIGNMENT_OPERATOR(OP)
RVec< typename RVec< T >::size_type > StableArgsort(const RVec< T > &v)
Return an RVec of indices that sort the input RVec while keeping the order of equal elements.
RVec< Common_t > Concatenate(const RVec< T0 > &v0, const RVec< T1 > &v1)
Return the concatenation of two RVecs.
T Sum(const RVec< T > &v, const T zero=T(0))
Sum elements of an RVec.
RVec< Common_t > InvariantMasses(const RVec< T0 > &pt1, const RVec< T1 > &eta1, const RVec< T2 > &phi1, const RVec< T3 > &mass1, const RVec< T4 > &pt2, const RVec< T5 > &eta2, const RVec< T6 > &phi2, const RVec< T7 > &mass2)
Return the invariant mass of two particles given the collections of the quantities transverse momentu...
RVec< T > Take(const RVec< T > &v, const RVec< typename RVec< T >::size_type > &i)
Return elements of a vector at given indices.
RVec< T > Construct(const RVec< Args_t > &... args)
Build an RVec of objects starting from RVecs of input to their constructors.
#define RVEC_STD_BINARY_FUNCTION(F)
#define RVEC_BINARY_OPERATOR(OP)
RVec< T > Drop(const RVec< T > &v, RVec< typename RVec< T >::size_type > idxs)
Return a copy of the container without the elements at the specified indices.
size_t CapacityInBytes(const RVecN< T, N > &X)
#define RVEC_LOGICAL_OPERATOR(OP)
RVec< RVec< std::size_t > > Combinations(const std::size_t size1, const std::size_t size2)
Return the indices that represent all combinations of the elements of two RVecs.
#define RVEC_STD_UNARY_FUNCTION(F)
RVec< typename RVec< T >::size_type > Enumerate(const RVec< T > &v)
For any Rvec v produce another RVec with entries starting from 0, and incrementing by 1 until a N = v...
auto Map(Args &&... args)
Create new collection applying a callable to the elements of the input collection.
RVec< T > Where(const RVec< int > &c, const RVec< T > &v1, const RVec< T > &v2)
Return the elements of v1 if the condition c is true and v2 if the condition c is false.
auto Any(const RVec< T > &v) -> decltype(v[0]==true)
Return true if any of the elements equates to true, return false otherwise.
RVec< typename RVec< T >::size_type > Argsort(const RVec< T > &v)
Return an RVec of indices that sort the input RVec.
std::size_t ArgMin(const RVec< T > &v)
Get the index of the smallest element of an RVec In case of multiple occurrences of the minimum value...
RVec< T > StableSort(const RVec< T > &v)
Return copy of RVec with elements sorted in ascending order while keeping the order of equal elements...
double Var(const RVec< T > &v)
Get the variance of the elements of an RVec.
RVec< T > Filter(const RVec< T > &v, F &&f)
Create a new collection with the elements passing the filter expressed by the predicate.
std::size_t ArgMax(const RVec< T > &v)
Get the index of the greatest element of an RVec In case of multiple occurrences of the maximum value...
bool IsSmall(const ROOT::VecOps::RVec< T > &v)
bool IsAdopting(const ROOT::VecOps::RVec< T > &v)
auto MapImpl(F &&f, RVecs &&... vs) -> RVec< decltype(f(vs[0]...))>
void ResetView(RVec< T > &v, T *addr, std::size_t sz)
An unsafe function to reset the buffer for which this RVec is acting as a view.
uint64_t NextPowerOf2(uint64_t A)
Return the next power of two (in 64-bits) that is strictly greater than A.
constexpr bool All(const bool *vals, std::size_t size)
std::size_t GetVectorsSize(const std::string &id, const RVec< T > &... vs)
void UninitializedValueConstruct(ForwardIt first, ForwardIt last)
auto MapFromTuple(Tuple_t &&t, std::index_sequence< Is... >) -> decltype(MapImpl(std::get< std::tuple_size< Tuple_t >::value - 1 >(t), std::get< Is >(t)...))
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...
The size of the inline storage of an RVec.
Used to figure out the offset of the first element of an RVec.
Storage for the SmallVector elements.