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
534 new (
static_cast<void *
>(std::addressof(*
first)))
typename std::iterator_traits<ForwardIt>::value_type();
536 std::uninitialized_value_construct(
first, last);
560 explicit RVecImpl(
unsigned N) :
ROOT::Internal::VecOps::SmallVectorTemplateBase<T>(
N) {}
569 if (!this->isSmall() && this->Owns())
577 this->destroy_range(this->begin(), this->end());
580 this->resetToSmall();
586 if (N < this->
size()) {
588 this->destroy_range(this->begin() +
N, this->end());
590 }
else if (
N > this->
size()) {
591 if (this->capacity() <
N)
593 for (
auto I = this->end(), E = this->begin() +
N;
I != E; ++
I)
601 if (N < this->
size()) {
603 this->destroy_range(this->begin() +
N, this->end());
605 }
else if (
N > this->
size()) {
606 if (this->capacity() <
N)
608 std::uninitialized_fill(this->end(), this->begin() +
N, NV);
615 if (this->capacity() <
N)
621 if (this->
size() < NumItems) {
622 throw std::runtime_error(
"Popping back more elements than those available.");
625 this->destroy_range(this->end() - NumItems, this->end());
626 this->set_size(this->
size() - NumItems);
631 T Result = ::std::move(this->back());
639 template <
typename in_iter,
640 typename =
typename std::enable_if<std::is_convertible<
641 typename std::iterator_traits<in_iter>::iterator_category, std::input_iterator_tag>
::value>
::type>
642 void append(in_iter in_start, in_iter in_end)
644 size_type NumInputs = std::distance(in_start, in_end);
645 if (NumInputs > this->capacity() - this->
size())
646 this->grow(this->
size() + NumInputs);
648 this->uninitialized_copy(in_start, in_end, this->end());
649 this->set_size(this->
size() + NumInputs);
655 if (NumInputs > this->capacity() - this->
size())
656 this->grow(this->
size() + NumInputs);
658 std::uninitialized_fill_n(this->end(), NumInputs, Elt);
659 this->set_size(this->
size() + NumInputs);
662 void append(std::initializer_list<T> IL) {
append(IL.begin(), IL.end()); }
671 if (this->capacity() < NumElts)
673 this->set_size(NumElts);
674 std::uninitialized_fill(this->begin(), this->end(), Elt);
677 template <
typename in_iter,
678 typename =
typename std::enable_if<std::is_convertible<
679 typename std::iterator_traits<in_iter>::iterator_category, std::input_iterator_tag>
::value>
::type>
680 void assign(in_iter in_start, in_iter in_end)
683 append(in_start, in_end);
697 if (I < this->begin() ||
I >= this->end()) {
698 throw std::runtime_error(
"The iterator passed to `erase` is out of bounds.");
703 std::move(
I + 1, this->end(),
I);
715 if (S < this->begin() || E > this->end() || S > E) {
716 throw std::runtime_error(
"Invalid start/end pair passed to `erase` (out of bounds or start > end).");
721 iterator I = std::move(E, this->end(), S);
724 this->destroy_range(
I, this->end());
725 this->set_size(
I - this->begin());
731 if (
I == this->end()) {
732 this->push_back(::std::move(Elt));
733 return this->end() - 1;
736 if (I < this->begin() ||
I > this->end()) {
737 throw std::runtime_error(
"The iterator passed to `insert` is out of bounds.");
740 if (this->
size() >= this->capacity()) {
741 size_t EltNo =
I - this->begin();
743 I = this->begin() + EltNo;
746 ::new ((
void *)this->end()) T(::std::move(this->back()));
748 std::move_backward(
I, this->end() - 1, this->end());
749 this->set_size(this->
size() + 1);
754 if (
I <= EltPtr && EltPtr < this->end())
757 *
I = ::std::move(*EltPtr);
763 if (
I == this->end()) {
764 this->push_back(Elt);
765 return this->end() - 1;
768 if (I < this->begin() ||
I > this->end()) {
769 throw std::runtime_error(
"The iterator passed to `insert` is out of bounds.");
772 if (this->
size() >= this->capacity()) {
773 size_t EltNo =
I - this->begin();
775 I = this->begin() + EltNo;
777 ::new ((
void *)this->end()) T(std::move(this->back()));
779 std::move_backward(
I, this->end() - 1, this->end());
780 this->set_size(this->
size() + 1);
784 const T *EltPtr = &Elt;
785 if (
I <= EltPtr && EltPtr < this->end())
795 size_t InsertElt =
I - this->begin();
797 if (
I == this->end()) {
798 append(NumToInsert, Elt);
799 return this->begin() + InsertElt;
802 if (I < this->begin() ||
I > this->end()) {
803 throw std::runtime_error(
"The iterator passed to `insert` is out of bounds.");
807 reserve(this->
size() + NumToInsert);
810 I = this->begin() + InsertElt;
816 if (
size_t(this->end() -
I) >= NumToInsert) {
817 T *OldEnd = this->end();
818 append(std::move_iterator<iterator>(this->end() - NumToInsert), std::move_iterator<iterator>(this->end()));
821 std::move_backward(
I, OldEnd - NumToInsert, OldEnd);
823 std::fill_n(
I, NumToInsert, Elt);
831 T *OldEnd = this->end();
832 this->set_size(this->
size() + NumToInsert);
833 size_t NumOverwritten = OldEnd -
I;
834 this->uninitialized_move(
I, OldEnd, this->end() - NumOverwritten);
837 std::fill_n(
I, NumOverwritten, Elt);
840 std::uninitialized_fill_n(OldEnd, NumToInsert - NumOverwritten, Elt);
844 template <
typename ItTy,
845 typename =
typename std::enable_if<std::is_convertible<
846 typename std::iterator_traits<ItTy>::iterator_category, std::input_iterator_tag>
::value>
::type>
850 size_t InsertElt =
I - this->begin();
852 if (
I == this->end()) {
854 return this->begin() + InsertElt;
857 if (I < this->begin() ||
I > this->end()) {
858 throw std::runtime_error(
"The iterator passed to `insert` is out of bounds.");
861 size_t NumToInsert = std::distance(From, To);
864 reserve(this->
size() + NumToInsert);
867 I = this->begin() + InsertElt;
873 if (
size_t(this->end() -
I) >= NumToInsert) {
874 T *OldEnd = this->end();
875 append(std::move_iterator<iterator>(this->end() - NumToInsert), std::move_iterator<iterator>(this->end()));
878 std::move_backward(
I, OldEnd - NumToInsert, OldEnd);
880 std::copy(From, To,
I);
888 T *OldEnd = this->end();
889 this->set_size(this->
size() + NumToInsert);
890 size_t NumOverwritten = OldEnd -
I;
891 this->uninitialized_move(
I, OldEnd, this->end() - NumOverwritten);
894 for (T *J =
I; NumOverwritten > 0; --NumOverwritten) {
901 this->uninitialized_copy(From, To, OldEnd);
907 template <
typename... ArgTypes>
912 ::new ((
void *)this->end()) T(std::forward<ArgTypes>(Args)...);
913 this->set_size(this->
size() + 1);
929 if (!this->isSmall() && !RHS.
isSmall()) {
930 std::swap(this->fBeginX, RHS.
fBeginX);
932 std::swap(this->fCapacity, RHS.
fCapacity);
938 if (this->isSmall() && !RHS.
Owns()) {
940 temp = std::move(RHS);
941 RHS = std::move(*
this);
942 *
this = std::move(temp);
944 }
else if (RHS.
isSmall() && !this->Owns()) {
946 temp = std::move(*
this);
947 *
this = std::move(RHS);
948 RHS = std::move(temp);
952 if (RHS.
size() > this->capacity())
953 this->grow(RHS.
size());
958 size_t NumShared = this->
size();
959 if (NumShared > RHS.
size())
960 NumShared = RHS.
size();
961 for (
size_type i = 0; i != NumShared; ++i)
962 std::iter_swap(this->begin() + i, RHS.
begin() + i);
966 size_t EltDiff = this->
size() - RHS.
size();
967 this->uninitialized_copy(this->begin() + NumShared, this->end(), RHS.
end());
970 this->destroy_range(this->begin() + NumShared, this->end());
971 this->set_size(NumShared);
972 }
else if (RHS.
size() > this->size()) {
973 size_t EltDiff = RHS.
size() - this->
size();
974 this->uninitialized_copy(RHS.
begin() + NumShared, RHS.
end(), this->end());
975 this->set_size(this->
size() + EltDiff);
977 this->destroy_range(RHS.
begin() + NumShared, RHS.
end());
991 size_t RHSSize = RHS.
size();
992 size_t CurSize = this->
size();
993 if (CurSize >= RHSSize) {
997 NewEnd = std::copy(RHS.
begin(), RHS.
begin() + RHSSize, this->begin());
999 NewEnd = this->begin();
1003 this->destroy_range(NewEnd, this->end());
1006 this->set_size(RHSSize);
1014 if (this->capacity() < RHSSize) {
1017 this->destroy_range(this->begin(), this->end());
1021 this->grow(RHSSize);
1022 }
else if (CurSize) {
1024 std::copy(RHS.
begin(), RHS.
begin() + CurSize, this->begin());
1028 this->uninitialized_copy(RHS.
begin() + CurSize, RHS.
end(), this->begin() + CurSize);
1031 this->set_size(RHSSize);
1035template <
typename T>
1043 if (!RHS.isSmall()) {
1045 this->destroy_range(this->begin(), this->end());
1046 if (!this->isSmall())
1047 free(this->begin());
1049 this->fBeginX = RHS.fBeginX;
1050 this->
fSize = RHS.fSize;
1051 this->fCapacity = RHS.fCapacity;
1058 size_t RHSSize = RHS.size();
1059 size_t CurSize = this->
size();
1060 if (CurSize >= RHSSize) {
1064 NewEnd = std::move(RHS.begin(), RHS.end(), NewEnd);
1068 this->destroy_range(NewEnd, this->end());
1069 this->set_size(RHSSize);
1082 if (this->capacity() < RHSSize) {
1085 this->destroy_range(this->begin(), this->end());
1089 this->grow(RHSSize);
1090 }
else if (CurSize) {
1092 std::move(RHS.begin(), RHS.begin() + CurSize, this->begin());
1096 this->uninitialized_move(RHS.begin() + CurSize, RHS.end(), this->begin() + CurSize);
1099 this->set_size(RHSSize);
1105template <
typename T>
1111template <
typename T>
1138template <
typename T,
unsigned int N>
1147 this->destroy_range(this->begin(), this->end());
1151 explicit RVecN(
size_t Size,
const T &
Value) : Detail::VecOps::RVecImpl<T>(
N) { this->assign(Size,
Value); }
1153 explicit RVecN(
size_t Size) : Detail::VecOps::RVecImpl<T>(
N)
1161 template <
typename ItTy,
1162 typename =
typename std::enable_if<std::is_convertible<
1163 typename std::iterator_traits<ItTy>::iterator_category, std::input_iterator_tag>
::value>
::type>
1164 RVecN(ItTy S, ItTy E) : Detail::VecOps::RVecImpl<T>(
N)
1169 RVecN(std::initializer_list<T> IL) : Detail::VecOps::RVecImpl<T>(
N) { this->assign(IL); }
1195 RVecN(
const std::vector<T> &RHS) :
RVecN(RHS.begin(), RHS.end()) {}
1207 this->fCapacity = -1;
1231 return begin()[idx];
1236 return begin()[idx];
1239 template <typename V, unsigned M, typename = std::enable_if<std::is_convertible<V, bool>::value>>
1244 if (
n != this->
size()) {
1245 std::string msg =
"Cannot index RVecN of size " + std::to_string(this->
size()) +
1246 " with condition vector of different size (" + std::to_string(
n) +
").";
1247 throw std::runtime_error(std::move(msg));
1251 for (
auto c : conds)
1267 template <typename U, unsigned M, typename = std::enable_if<std::is_convertible<T, U>::value>>
1276 std::string msg =
"RVecN::at: size is " + std::to_string(this->
fSize) +
" but out-of-bounds index " +
1277 std::to_string(pos) +
" was requested.";
1278 throw std::out_of_range(std::move(msg));
1280 return this->operator[](pos);
1286 std::string msg =
"RVecN::at: size is " + std::to_string(this->
fSize) +
" but out-of-bounds index " +
1287 std::to_string(pos) +
" was requested.";
1288 throw std::out_of_range(std::move(msg));
1290 return this->operator[](pos);
1298 return this->operator[](pos);
1306 return this->operator[](pos);
1479template <
typename T>
1480class R__CLING_PTRCHECK(off)
RVec :
public RVecN<T, Internal::VecOps::RVecInlineStorageSize<T>::value> {
1487 using SuperClass::begin;
1488 using SuperClass::size;
1496 template <
typename ItTy,
1497 typename =
typename std::enable_if<std::is_convertible<
1498 typename std::iterator_traits<ItTy>::iterator_category, std::input_iterator_tag>
::value>
::type>
1509 SuperClass::operator=(RHS);
1517 SuperClass::operator=(std::move(RHS));
1523 template <
unsigned N>
1526 template <
unsigned N>
1534 template <typename U, typename = std::enable_if<std::is_convertible<T, U>::value>>
1537 return RVec<U>(this->begin(), this->end());
1540 using SuperClass::operator[];
1542 template <typename V, typename = std::enable_if<std::is_convertible<V, bool>::value>>
1545 return RVec(SuperClass::operator[](conds));
1548 using SuperClass::at;
1550 friend bool ROOT::Detail::VecOps::IsSmall<T>(
const RVec<T> &
v);
1552 friend bool ROOT::Detail::VecOps::IsAdopting<T>(
const RVec<T> &
v);
1555template <
typename T,
unsigned N>
1564#define RVEC_UNARY_OPERATOR(OP) \
1565template <typename T> \
1566RVec<T> operator OP(const RVec<T> &v) \
1569 for (auto &x : ret) \
1578#undef RVEC_UNARY_OPERATOR
1584#define ERROR_MESSAGE(OP) \
1585 "Cannot call operator " #OP " on vectors of different sizes."
1587#define RVEC_BINARY_OPERATOR(OP) \
1588template <typename T0, typename T1> \
1589auto operator OP(const RVec<T0> &v, const T1 &y) \
1590 -> RVec<decltype(v[0] OP y)> \
1592 RVec<decltype(v[0] OP y)> ret(v.size()); \
1593 auto op = [&y](const T0 &x) { return x OP y; }; \
1594 std::transform(v.begin(), v.end(), ret.begin(), op); \
1598template <typename T0, typename T1> \
1599auto operator OP(const T0 &x, const RVec<T1> &v) \
1600 -> RVec<decltype(x OP v[0])> \
1602 RVec<decltype(x OP v[0])> ret(v.size()); \
1603 auto op = [&x](const T1 &y) { return x OP y; }; \
1604 std::transform(v.begin(), v.end(), ret.begin(), op); \
1608template <typename T0, typename T1> \
1609auto operator OP(const RVec<T0> &v0, const RVec<T1> &v1) \
1610 -> RVec<decltype(v0[0] OP v1[0])> \
1612 if (v0.size() != v1.size()) \
1613 throw std::runtime_error(ERROR_MESSAGE(OP)); \
1615 RVec<decltype(v0[0] OP v1[0])> ret(v0.size()); \
1616 auto op = [](const T0 &x, const T1 &y) { return x OP y; }; \
1617 std::transform(v0.begin(), v0.end(), v1.begin(), ret.begin(), op); \
1629#undef RVEC_BINARY_OPERATOR
1635#define RVEC_ASSIGNMENT_OPERATOR(OP) \
1636template <typename T0, typename T1> \
1637RVec<T0>& operator OP(RVec<T0> &v, const T1 &y) \
1639 auto op = [&y](T0 &x) { return x OP y; }; \
1640 std::transform(v.begin(), v.end(), v.begin(), op); \
1644template <typename T0, typename T1> \
1645RVec<T0>& operator OP(RVec<T0> &v0, const RVec<T1> &v1) \
1647 if (v0.size() != v1.size()) \
1648 throw std::runtime_error(ERROR_MESSAGE(OP)); \
1650 auto op = [](T0 &x, const T1 &y) { return x OP y; }; \
1651 std::transform(v0.begin(), v0.end(), v1.begin(), v0.begin(), op); \
1665#undef RVEC_ASSIGNMENT_OPERATOR
1671#define RVEC_LOGICAL_OPERATOR(OP) \
1672template <typename T0, typename T1> \
1673auto operator OP(const RVec<T0> &v, const T1 &y) \
1676 RVec<int> ret(v.size()); \
1677 auto op = [y](const T0 &x) -> int { return x OP y; }; \
1678 std::transform(v.begin(), v.end(), ret.begin(), op); \
1682template <typename T0, typename T1> \
1683auto operator OP(const T0 &x, const RVec<T1> &v) \
1686 RVec<int> ret(v.size()); \
1687 auto op = [x](const T1 &y) -> int { return x OP y; }; \
1688 std::transform(v.begin(), v.end(), ret.begin(), op); \
1692template <typename T0, typename T1> \
1693auto operator OP(const RVec<T0> &v0, const RVec<T1> &v1) \
1696 if (v0.size() != v1.size()) \
1697 throw std::runtime_error(ERROR_MESSAGE(OP)); \
1699 RVec<int> ret(v0.size()); \
1700 auto op = [](const T0 &x, const T1 &y) -> int { return x OP y; }; \
1701 std::transform(v0.begin(), v0.end(), v1.begin(), ret.begin(), op); \
1713#undef RVEC_LOGICAL_OPERATOR
1720template <
typename T>
struct PromoteTypeImpl;
1722template <>
struct PromoteTypeImpl<float> {
using Type = float; };
1723template <>
struct PromoteTypeImpl<
double> {
using Type =
double; };
1724template <>
struct PromoteTypeImpl<long
double> {
using Type =
long double; };
1726template <
typename T>
struct PromoteTypeImpl {
using Type =
double; };
1728template <
typename T>
1729using PromoteType =
typename PromoteTypeImpl<T>::Type;
1731template <
typename U,
typename V>
1732using PromoteTypes =
decltype(PromoteType<U>() + PromoteType<V>());
1736#define RVEC_UNARY_FUNCTION(NAME, FUNC) \
1737 template <typename T> \
1738 RVec<PromoteType<T>> NAME(const RVec<T> &v) \
1740 RVec<PromoteType<T>> ret(v.size()); \
1741 auto f = [](const T &x) { return FUNC(x); }; \
1742 std::transform(v.begin(), v.end(), ret.begin(), f); \
1746#define RVEC_BINARY_FUNCTION(NAME, FUNC) \
1747 template <typename T0, typename T1> \
1748 RVec<PromoteTypes<T0, T1>> NAME(const T0 &x, const RVec<T1> &v) \
1750 RVec<PromoteTypes<T0, T1>> ret(v.size()); \
1751 auto f = [&x](const T1 &y) { return FUNC(x, y); }; \
1752 std::transform(v.begin(), v.end(), ret.begin(), f); \
1756 template <typename T0, typename T1> \
1757 RVec<PromoteTypes<T0, T1>> NAME(const RVec<T0> &v, const T1 &y) \
1759 RVec<PromoteTypes<T0, T1>> ret(v.size()); \
1760 auto f = [&y](const T1 &x) { return FUNC(x, y); }; \
1761 std::transform(v.begin(), v.end(), ret.begin(), f); \
1765 template <typename T0, typename T1> \
1766 RVec<PromoteTypes<T0, T1>> NAME(const RVec<T0> &v0, const RVec<T1> &v1) \
1768 if (v0.size() != v1.size()) \
1769 throw std::runtime_error(ERROR_MESSAGE(NAME)); \
1771 RVec<PromoteTypes<T0, T1>> ret(v0.size()); \
1772 auto f = [](const T0 &x, const T1 &y) { return FUNC(x, y); }; \
1773 std::transform(v0.begin(), v0.end(), v1.begin(), ret.begin(), f); \
1777#define RVEC_STD_UNARY_FUNCTION(F) RVEC_UNARY_FUNCTION(F, std::F)
1778#define RVEC_STD_BINARY_FUNCTION(F) RVEC_BINARY_FUNCTION(F, std::F)
1825#undef RVEC_STD_UNARY_FUNCTION
1832#define RVEC_VDT_UNARY_FUNCTION(F) RVEC_UNARY_FUNCTION(F, vdt::F)
1834RVEC_VDT_UNARY_FUNCTION(fast_expf)
1835RVEC_VDT_UNARY_FUNCTION(fast_logf)
1836RVEC_VDT_UNARY_FUNCTION(fast_sinf)
1837RVEC_VDT_UNARY_FUNCTION(fast_cosf)
1838RVEC_VDT_UNARY_FUNCTION(fast_tanf)
1839RVEC_VDT_UNARY_FUNCTION(fast_asinf)
1840RVEC_VDT_UNARY_FUNCTION(fast_acosf)
1841RVEC_VDT_UNARY_FUNCTION(fast_atanf)
1843RVEC_VDT_UNARY_FUNCTION(fast_exp)
1844RVEC_VDT_UNARY_FUNCTION(fast_log)
1845RVEC_VDT_UNARY_FUNCTION(fast_sin)
1846RVEC_VDT_UNARY_FUNCTION(fast_cos)
1847RVEC_VDT_UNARY_FUNCTION(fast_tan)
1848RVEC_VDT_UNARY_FUNCTION(fast_asin)
1849RVEC_VDT_UNARY_FUNCTION(fast_acos)
1850RVEC_VDT_UNARY_FUNCTION(fast_atan)
1851#undef RVEC_VDT_UNARY_FUNCTION
1855#undef RVEC_UNARY_FUNCTION
1870template <
typename T,
typename V>
1873 if (
v0.size() !=
v1.size())
1874 throw std::runtime_error(
"Cannot compute inner product of vectors of different sizes");
1875 return std::inner_product(
v0.begin(),
v0.end(),
v1.begin(),
decltype(
v0[0] *
v1[0])(0));
1901template <
typename T>
1904 return std::accumulate(
v.begin(),
v.end(), zero);
1909 return std::accumulate(
v.begin(),
v.end(), zero);
1913template <
typename T>
1916 return std::accumulate(
v.begin(),
v.end(), init, std::multiplies<T>());
1931template <
typename T>
1934 if (
v.empty())
return 0.;
1963template <
typename T,
typename R = T>
1966 if (
v.empty())
return zero;
1967 return Sum(
v, zero) /
v.size();
1980template <
typename T>
1983 return *std::max_element(
v.begin(),
v.end());
1996template <
typename T>
1999 return *std::min_element(
v.begin(),
v.end());
2014template <
typename T>
2017 return std::distance(
v.begin(), std::max_element(
v.begin(),
v.end()));
2032template <
typename T>
2035 return std::distance(
v.begin(), std::min_element(
v.begin(),
v.end()));
2049template <
typename T>
2052 const std::size_t
size =
v.size();
2053 if (
size < std::size_t(2))
return 0.;
2054 T sum_squares(0), squared_sum(0);
2055 auto pred = [&sum_squares, &squared_sum](
const T&
x) {sum_squares+=
x*
x; squared_sum+=
x;};
2056 std::for_each(
v.begin(),
v.end(), pred);
2057 squared_sum *= squared_sum;
2059 return 1. / (dsize - 1.) * (sum_squares - squared_sum / dsize );
2073template <
typename T>
2076 return std::sqrt(
Var(
v));
2097template <
typename... Args>
2110 constexpr auto nArgs =
sizeof...(Args);
2113 "Map: the first N-1 arguments must be RVecs or references to RVecs");
2116 std::make_index_sequence<
sizeof...(args) - 1>());
2129template <
typename T,
typename F>
2132 const auto thisSize =
v.size();
2135 for (
auto &&val :
v) {
2137 w.emplace_back(val);
2152template <
typename T>
2156 if (
static_cast<bool>(
e) ==
true)
2171template <
typename T>
2175 if (
static_cast<bool>(
e) ==
false)
2180template <
typename T>
2197template <
typename T>
2203 std::sort(i.
begin(), i.
end(), [&
v](size_type i1, size_type i2) { return v[i1] < v[i2]; });
2218template <
typename T,
typename Compare>
2225 [&
v, &
c](size_type i1, size_type i2) { return c(v[i1], v[i2]); });
2242template <
typename T>
2248 std::stable_sort(i.
begin(), i.
end(), [&
v](size_type i1, size_type i2) { return v[i1] < v[i2]; });
2265template <
typename T,
typename Compare>
2271 std::stable_sort(i.
begin(), i.
end(), [&
v, &
c](size_type i1, size_type i2) { return c(v[i1], v[i2]); });
2286template <
typename T>
2290 const size_type isize = i.size();
2292 for (size_type k = 0; k < isize; k++)
2298template <
typename T>
2302 const size_type isize = i.size();
2304 for (size_type k = 0; k < isize; k++)
2332template <
typename T>
2336 const size_type
size =
v.size();
2337 const size_type absn = std::abs(
n);
2339 std::stringstream ss;
2340 ss <<
"Try to take " << absn <<
" elements but vector has only size " <<
size <<
".";
2341 throw std::runtime_error(ss.str());
2345 for (size_type k = 0; k < absn; k++)
2346 r[k] =
v[
size - absn + k];
2348 for (size_type k = 0; k < absn; k++)
2357template <
typename T>
2361 std::sort(idxs.begin(), idxs.end());
2362 idxs.erase(std::unique(idxs.begin(), idxs.end()), idxs.end());
2365 if (
v.size() > idxs.size())
2366 r.reserve(
v.size() - idxs.size());
2368 auto discardIt = idxs.begin();
2370 for (sz_t i = 0u; i <
v.size(); ++i) {
2371 if (discardIt != idxs.end() && i == *discardIt)
2374 r.emplace_back(
v[i]);
2390template <
typename T>
2394 std::reverse(
r.begin(),
r.end());
2411template <
typename T>
2415 std::sort(
r.begin(),
r.end());
2436template <
typename T,
typename Compare>
2440 std::sort(
r.begin(),
r.end(), std::forward<Compare>(
c));
2460template <
typename T>
2464 std::stable_sort(
r.begin(),
r.end());
2496template <
typename T,
typename Compare>
2500 std::stable_sort(
r.begin(),
r.end(), std::forward<Compare>(
c));
2518 using size_type = std::size_t;
2520 r[0].resize(size1*size2);
2521 r[1].resize(size1*size2);
2523 for(size_type i=0; i<size1; i++) {
2524 for(size_type j=0; j<size2; j++) {
2547template <
typename T1,
typename T2>
2572template <
typename T>
2576 const size_type s =
v.size();
2578 throw std::runtime_error(
"Cannot make unique combinations of size " + std::to_string(
n) +
2579 " from vector of size " + std::to_string(s) +
".");
2583 for(size_type k=0; k<s; k++)
2586 const auto innersize = [=] {
2587 size_type inners = s -
n + 1;
2588 for (size_type
m = s -
n + 2;
m <= s; ++
m)
2591 size_type factn = 1;
2592 for (size_type i = 2; i <=
n; ++i)
2600 size_type inneridx = 0;
2601 for (size_type k = 0; k <
n; k++)
2606 bool run_through =
true;
2610 run_through =
false;
2618 for (
long j=i+1; j<(long)
n; j++)
2620 for (size_type k = 0; k <
n; k++)
2636template <
typename T>
2641 const auto size =
v.size();
2643 for(size_type i=0; i<
size; i++) {
2667template <
typename T>
2671 if (!v2_is_sorted) v2_sorted = Sort(
v2);
2672 const auto v2_begin = v2_is_sorted ?
v2.begin() : v2_sorted.
begin();
2673 const auto v2_end = v2_is_sorted ?
v2.end() : v2_sorted.
end();
2675 const auto size =
v1.size();
2678 for(size_type i=0; i<
size; i++) {
2679 if (std::binary_search(v2_begin, v2_end,
v1[i])) {
2680 r.emplace_back(
v1[i]);
2701template <
typename T>
2705 const size_type
size =
c.size();
2708 for (size_type i=0; i<
size; i++) {
2709 r.emplace_back(
c[i] != 0 ?
v1[i] :
v2[i]);
2729template <
typename T>
2733 const size_type
size =
c.size();
2736 for (size_type i=0; i<
size; i++) {
2737 r.emplace_back(
c[i] != 0 ?
v1[i] :
v2);
2757template <
typename T>
2761 const size_type
size =
c.size();
2764 for (size_type i=0; i<
size; i++) {
2765 r.emplace_back(
c[i] != 0 ?
v1 :
v2[i]);
2783template <
typename T>
2787 const size_type
size =
c.size();
2790 for (size_type i=0; i<
size; i++) {
2791 r.emplace_back(
c[i] != 0 ?
v1 :
v2);
2806template <typename T0, typename T1, typename Common_t = typename std::common_type<T0, T1>::type>
2811 std::copy(
v0.begin(),
v0.end(), std::back_inserter(res));
2812 std::copy(
v1.begin(),
v1.end(), std::back_inserter(res));
2822template <
typename T>
2825 static_assert(std::is_floating_point<T>::value,
2826 "DeltaPhi must be called with floating point values.");
2827 auto r = std::fmod(
v2 -
v1, 2.0 *
c);
2843template <
typename T>
2847 const size_type
size =
v1.size();
2849 for (size_type i = 0; i <
size; i++) {
2850 r[i] = DeltaPhi(
v1[i],
v2[i],
c);
2861template <
typename T>
2865 const size_type
size =
v1.size();
2867 for (size_type i = 0; i <
size; i++) {
2868 r[i] = DeltaPhi(
v1[i],
v2,
c);
2879template <
typename T>
2883 const size_type
size =
v2.size();
2885 for (size_type i = 0; i <
size; i++) {
2886 r[i] = DeltaPhi(
v1,
v2[i],
c);
2898template <
typename T>
2901 const auto dphi = DeltaPhi(phi1, phi2,
c);
2902 return (eta1 - eta2) * (eta1 - eta2) + dphi * dphi;
2912template <
typename T>
2915 return sqrt(DeltaR2(eta1, eta2, phi1, phi2,
c));
2925template <
typename T>
2926T DeltaR(T eta1, T eta2, T phi1, T phi2,
const T
c =
M_PI)
2928 const auto dphi = DeltaPhi(phi1, phi2,
c);
2929 return std::sqrt((eta1 - eta2) * (eta1 - eta2) + dphi * dphi);
2937template <
typename T>
2949 for (std::size_t i = 0u; i <
size; ++i) {
2951 const auto x1 = pt1[i] * std::cos(phi1[i]);
2952 const auto y1 = pt1[i] * std::sin(phi1[i]);
2953 const auto z1 = pt1[i] * std::sinh(eta1[i]);
2954 const auto e1 = std::sqrt(
x1 *
x1 +
y1 *
y1 + z1 * z1 + mass1[i] * mass1[i]);
2956 const auto x2 = pt2[i] * std::cos(phi2[i]);
2957 const auto y2 = pt2[i] * std::sin(phi2[i]);
2958 const auto z2 = pt2[i] * std::sinh(eta2[i]);
2959 const auto e2 = std::sqrt(
x2 *
x2 +
y2 *
y2 + z2 * z2 + mass2[i] * mass2[i]);
2962 const auto e = e1 + e2;
2963 const auto x =
x1 +
x2;
2964 const auto y =
y1 +
y2;
2965 const auto z = z1 + z2;
2967 inv_masses[i] = std::sqrt(
e *
e -
x *
x -
y *
y - z * z);
2979template <
typename T>
2982 const std::size_t
size =
pt.size();
2991 for (std::size_t i = 0u; i <
size; ++ i) {
2993 const auto x =
pt[i] * std::cos(phi[i]);
2995 const auto y =
pt[i] * std::sin(phi[i]);
2997 const auto z =
pt[i] * std::sinh(eta[i]);
2999 const auto e = std::sqrt(
x *
x +
y *
y + z * z + mass[i] * mass[i]);
3004 return std::sqrt(e_sum * e_sum - x_sum * x_sum - y_sum * y_sum - z_sum * z_sum);
3025template <
typename T,
typename... Args_t>
3031 for (
auto i = 0UL; i <
size; ++i) {
3045template <
typename T>
3048 const auto size =
v.size();
3051 for (
auto i = 0UL; i <
size; ++i) {
3068 for (
auto i = 0UL; i <
length; ++i) {
3079 ret.
reserve(begin < end ? end - begin : 0u);
3080 for (
auto i = begin; i < end; ++i)
3091 constexpr bool mustConvert = std::is_same<char, T>::value || std::is_same<signed char, T>::value ||
3092 std::is_same<unsigned char, T>::value || std::is_same<wchar_t, T>::value ||
3093 std::is_same<char16_t, T>::value || std::is_same<char32_t, T>::value;
3094 using Print_t =
typename std::conditional<mustConvert, long long int, T>::type;
3096 auto size =
v.size();
3098 for (std::size_t i = 0; i <
size - 1; ++i) {
3099 os << (Print_t)
v[i] <<
", ";
3101 os << (Print_t)
v[
size - 1];
3107#if (_VECOPS_USE_EXTERN_TEMPLATES)
3109#define RVEC_EXTERN_UNARY_OPERATOR(T, OP) \
3110 extern template RVec<T> operator OP<T>(const RVec<T> &);
3112#define RVEC_EXTERN_BINARY_OPERATOR(T, OP) \
3113 extern template auto operator OP<T, T>(const T &x, const RVec<T> &v) \
3114 -> RVec<decltype(x OP v[0])>; \
3115 extern template auto operator OP<T, T>(const RVec<T> &v, const T &y) \
3116 -> RVec<decltype(v[0] OP y)>; \
3117 extern template auto operator OP<T, T>(const RVec<T> &v0, const RVec<T> &v1)\
3118 -> RVec<decltype(v0[0] OP v1[0])>;
3120#define RVEC_EXTERN_ASSIGN_OPERATOR(T, OP) \
3121 extern template RVec<T> &operator OP<T, T>(RVec<T> &, const T &); \
3122 extern template RVec<T> &operator OP<T, T>(RVec<T> &, const RVec<T> &);
3124#define RVEC_EXTERN_LOGICAL_OPERATOR(T, OP) \
3125 extern template RVec<int> operator OP<T, T>(const RVec<T> &, const T &); \
3126 extern template RVec<int> operator OP<T, T>(const T &, const RVec<T> &); \
3127 extern template RVec<int> operator OP<T, T>(const RVec<T> &, const RVec<T> &);
3129#define RVEC_EXTERN_FLOAT_TEMPLATE(T) \
3130 extern template class RVec<T>; \
3131 RVEC_EXTERN_UNARY_OPERATOR(T, +) \
3132 RVEC_EXTERN_UNARY_OPERATOR(T, -) \
3133 RVEC_EXTERN_UNARY_OPERATOR(T, !) \
3134 RVEC_EXTERN_BINARY_OPERATOR(T, +) \
3135 RVEC_EXTERN_BINARY_OPERATOR(T, -) \
3136 RVEC_EXTERN_BINARY_OPERATOR(T, *) \
3137 RVEC_EXTERN_BINARY_OPERATOR(T, /) \
3138 RVEC_EXTERN_ASSIGN_OPERATOR(T, +=) \
3139 RVEC_EXTERN_ASSIGN_OPERATOR(T, -=) \
3140 RVEC_EXTERN_ASSIGN_OPERATOR(T, *=) \
3141 RVEC_EXTERN_ASSIGN_OPERATOR(T, /=) \
3142 RVEC_EXTERN_LOGICAL_OPERATOR(T, <) \
3143 RVEC_EXTERN_LOGICAL_OPERATOR(T, >) \
3144 RVEC_EXTERN_LOGICAL_OPERATOR(T, ==) \
3145 RVEC_EXTERN_LOGICAL_OPERATOR(T, !=) \
3146 RVEC_EXTERN_LOGICAL_OPERATOR(T, <=) \
3147 RVEC_EXTERN_LOGICAL_OPERATOR(T, >=) \
3148 RVEC_EXTERN_LOGICAL_OPERATOR(T, &&) \
3149 RVEC_EXTERN_LOGICAL_OPERATOR(T, ||)
3151#define RVEC_EXTERN_INTEGER_TEMPLATE(T) \
3152 extern template class RVec<T>; \
3153 RVEC_EXTERN_UNARY_OPERATOR(T, +) \
3154 RVEC_EXTERN_UNARY_OPERATOR(T, -) \
3155 RVEC_EXTERN_UNARY_OPERATOR(T, ~) \
3156 RVEC_EXTERN_UNARY_OPERATOR(T, !) \
3157 RVEC_EXTERN_BINARY_OPERATOR(T, +) \
3158 RVEC_EXTERN_BINARY_OPERATOR(T, -) \
3159 RVEC_EXTERN_BINARY_OPERATOR(T, *) \
3160 RVEC_EXTERN_BINARY_OPERATOR(T, /) \
3161 RVEC_EXTERN_BINARY_OPERATOR(T, %) \
3162 RVEC_EXTERN_BINARY_OPERATOR(T, &) \
3163 RVEC_EXTERN_BINARY_OPERATOR(T, |) \
3164 RVEC_EXTERN_BINARY_OPERATOR(T, ^) \
3165 RVEC_EXTERN_ASSIGN_OPERATOR(T, +=) \
3166 RVEC_EXTERN_ASSIGN_OPERATOR(T, -=) \
3167 RVEC_EXTERN_ASSIGN_OPERATOR(T, *=) \
3168 RVEC_EXTERN_ASSIGN_OPERATOR(T, /=) \
3169 RVEC_EXTERN_ASSIGN_OPERATOR(T, %=) \
3170 RVEC_EXTERN_ASSIGN_OPERATOR(T, &=) \
3171 RVEC_EXTERN_ASSIGN_OPERATOR(T, |=) \
3172 RVEC_EXTERN_ASSIGN_OPERATOR(T, ^=) \
3173 RVEC_EXTERN_ASSIGN_OPERATOR(T, >>=) \
3174 RVEC_EXTERN_ASSIGN_OPERATOR(T, <<=) \
3175 RVEC_EXTERN_LOGICAL_OPERATOR(T, <) \
3176 RVEC_EXTERN_LOGICAL_OPERATOR(T, >) \
3177 RVEC_EXTERN_LOGICAL_OPERATOR(T, ==) \
3178 RVEC_EXTERN_LOGICAL_OPERATOR(T, !=) \
3179 RVEC_EXTERN_LOGICAL_OPERATOR(T, <=) \
3180 RVEC_EXTERN_LOGICAL_OPERATOR(T, >=) \
3181 RVEC_EXTERN_LOGICAL_OPERATOR(T, &&) \
3182 RVEC_EXTERN_LOGICAL_OPERATOR(T, ||)
3184RVEC_EXTERN_INTEGER_TEMPLATE(
char)
3185RVEC_EXTERN_INTEGER_TEMPLATE(
short)
3186RVEC_EXTERN_INTEGER_TEMPLATE(
int)
3187RVEC_EXTERN_INTEGER_TEMPLATE(
long)
3190RVEC_EXTERN_INTEGER_TEMPLATE(
unsigned char)
3191RVEC_EXTERN_INTEGER_TEMPLATE(
unsigned short)
3192RVEC_EXTERN_INTEGER_TEMPLATE(
unsigned int)
3193RVEC_EXTERN_INTEGER_TEMPLATE(
unsigned long)
3196RVEC_EXTERN_FLOAT_TEMPLATE(
float)
3197RVEC_EXTERN_FLOAT_TEMPLATE(
double)
3199#undef RVEC_EXTERN_UNARY_OPERATOR
3200#undef RVEC_EXTERN_BINARY_OPERATOR
3201#undef RVEC_EXTERN_ASSIGN_OPERATOR
3202#undef RVEC_EXTERN_LOGICAL_OPERATOR
3203#undef RVEC_EXTERN_INTEGER_TEMPLATE
3204#undef RVEC_EXTERN_FLOAT_TEMPLATE
3206#define RVEC_EXTERN_UNARY_FUNCTION(T, NAME, FUNC) \
3207 extern template RVec<PromoteType<T>> NAME(const RVec<T> &);
3209#define RVEC_EXTERN_STD_UNARY_FUNCTION(T, F) RVEC_EXTERN_UNARY_FUNCTION(T, F, std::F)
3211#define RVEC_EXTERN_BINARY_FUNCTION(T0, T1, NAME, FUNC) \
3212 extern template RVec<PromoteTypes<T0, T1>> NAME(const RVec<T0> &, const T1 &); \
3213 extern template RVec<PromoteTypes<T0, T1>> NAME(const T0 &, const RVec<T1> &); \
3214 extern template RVec<PromoteTypes<T0, T1>> NAME(const RVec<T0> &, const RVec<T1> &);
3216#define RVEC_EXTERN_STD_BINARY_FUNCTION(T, F) RVEC_EXTERN_BINARY_FUNCTION(T, T, F, std::F)
3218#define RVEC_EXTERN_STD_FUNCTIONS(T) \
3219 RVEC_EXTERN_STD_UNARY_FUNCTION(T, abs) \
3220 RVEC_EXTERN_STD_BINARY_FUNCTION(T, fdim) \
3221 RVEC_EXTERN_STD_BINARY_FUNCTION(T, fmod) \
3222 RVEC_EXTERN_STD_BINARY_FUNCTION(T, remainder) \
3223 RVEC_EXTERN_STD_UNARY_FUNCTION(T, exp) \
3224 RVEC_EXTERN_STD_UNARY_FUNCTION(T, exp2) \
3225 RVEC_EXTERN_STD_UNARY_FUNCTION(T, expm1) \
3226 RVEC_EXTERN_STD_UNARY_FUNCTION(T, log) \
3227 RVEC_EXTERN_STD_UNARY_FUNCTION(T, log10) \
3228 RVEC_EXTERN_STD_UNARY_FUNCTION(T, log2) \
3229 RVEC_EXTERN_STD_UNARY_FUNCTION(T, log1p) \
3230 RVEC_EXTERN_STD_BINARY_FUNCTION(T, pow) \
3231 RVEC_EXTERN_STD_UNARY_FUNCTION(T, sqrt) \
3232 RVEC_EXTERN_STD_UNARY_FUNCTION(T, cbrt) \
3233 RVEC_EXTERN_STD_BINARY_FUNCTION(T, hypot) \
3234 RVEC_EXTERN_STD_UNARY_FUNCTION(T, sin) \
3235 RVEC_EXTERN_STD_UNARY_FUNCTION(T, cos) \
3236 RVEC_EXTERN_STD_UNARY_FUNCTION(T, tan) \
3237 RVEC_EXTERN_STD_UNARY_FUNCTION(T, asin) \
3238 RVEC_EXTERN_STD_UNARY_FUNCTION(T, acos) \
3239 RVEC_EXTERN_STD_UNARY_FUNCTION(T, atan) \
3240 RVEC_EXTERN_STD_BINARY_FUNCTION(T, atan2) \
3241 RVEC_EXTERN_STD_UNARY_FUNCTION(T, sinh) \
3242 RVEC_EXTERN_STD_UNARY_FUNCTION(T, cosh) \
3243 RVEC_EXTERN_STD_UNARY_FUNCTION(T, tanh) \
3244 RVEC_EXTERN_STD_UNARY_FUNCTION(T, asinh) \
3245 RVEC_EXTERN_STD_UNARY_FUNCTION(T, acosh) \
3246 RVEC_EXTERN_STD_UNARY_FUNCTION(T, atanh) \
3247 RVEC_EXTERN_STD_UNARY_FUNCTION(T, floor) \
3248 RVEC_EXTERN_STD_UNARY_FUNCTION(T, ceil) \
3249 RVEC_EXTERN_STD_UNARY_FUNCTION(T, trunc) \
3250 RVEC_EXTERN_STD_UNARY_FUNCTION(T, round) \
3251 RVEC_EXTERN_STD_UNARY_FUNCTION(T, erf) \
3252 RVEC_EXTERN_STD_UNARY_FUNCTION(T, erfc) \
3253 RVEC_EXTERN_STD_UNARY_FUNCTION(T, lgamma) \
3254 RVEC_EXTERN_STD_UNARY_FUNCTION(T, tgamma) \
3256RVEC_EXTERN_STD_FUNCTIONS(
float)
3257RVEC_EXTERN_STD_FUNCTIONS(
double)
3258#undef RVEC_EXTERN_STD_UNARY_FUNCTION
3259#undef RVEC_EXTERN_STD_BINARY_FUNCTION
3260#undef RVEC_EXTERN_STD_UNARY_FUNCTIONS
3264#define RVEC_EXTERN_VDT_UNARY_FUNCTION(T, F) RVEC_EXTERN_UNARY_FUNCTION(T, F, vdt::F)
3266RVEC_EXTERN_VDT_UNARY_FUNCTION(
float, fast_expf)
3267RVEC_EXTERN_VDT_UNARY_FUNCTION(
float, fast_logf)
3268RVEC_EXTERN_VDT_UNARY_FUNCTION(
float, fast_sinf)
3269RVEC_EXTERN_VDT_UNARY_FUNCTION(
float, fast_cosf)
3270RVEC_EXTERN_VDT_UNARY_FUNCTION(
float, fast_tanf)
3271RVEC_EXTERN_VDT_UNARY_FUNCTION(
float, fast_asinf)
3272RVEC_EXTERN_VDT_UNARY_FUNCTION(
float, fast_acosf)
3273RVEC_EXTERN_VDT_UNARY_FUNCTION(
float, fast_atanf)
3275RVEC_EXTERN_VDT_UNARY_FUNCTION(
double, fast_exp)
3276RVEC_EXTERN_VDT_UNARY_FUNCTION(
double, fast_log)
3277RVEC_EXTERN_VDT_UNARY_FUNCTION(
double, fast_sin)
3278RVEC_EXTERN_VDT_UNARY_FUNCTION(
double, fast_cos)
3279RVEC_EXTERN_VDT_UNARY_FUNCTION(
double, fast_tan)
3280RVEC_EXTERN_VDT_UNARY_FUNCTION(
double, fast_asin)
3281RVEC_EXTERN_VDT_UNARY_FUNCTION(
double, fast_acos)
3282RVEC_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 true, the RVec is in "memory adoption" mode, i.e. it is acting as a view on a memory buffer it doe...
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.
RVec< T > InvariantMasses(const RVec< T > &pt1, const RVec< T > &eta1, const RVec< T > &phi1, const RVec< T > &mass1, const RVec< T > &pt2, const RVec< T > &eta2, const RVec< T > &phi2, const RVec< T > &mass2)
Return the invariant mass of two particles given the collections of the quantities transverse momentu...
T Sum(const RVec< T > &v, const T zero=T(0))
Sum elements of an RVec.
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]...))>
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)...))
This file contains a specialised ROOT message handler to test for diagnostic in unit tests.
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.