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);
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(std::move(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(std::move(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(std::move(msg));
1302 return this->operator[](pos);
1310 return this->operator[](pos);
1318 return this->operator[](pos);
1491template <
typename T>
1492class R__CLING_PTRCHECK(off)
RVec :
public RVecN<T, Internal::VecOps::RVecInlineStorageSize<T>::value> {
1495 friend void Internal::VecOps::ResetView<>(
RVec<T> &
v, T *addr, std::size_t sz);
1502 using SuperClass::begin;
1503 using SuperClass::size;
1511 template <
typename ItTy,
1512 typename =
typename std::enable_if<std::is_convertible<
1513 typename std::iterator_traits<ItTy>::iterator_category, std::input_iterator_tag>
::value>
::type>
1524 SuperClass::operator=(RHS);
1532 SuperClass::operator=(std::move(RHS));
1538 template <
unsigned N>
1541 template <
unsigned N>
1549 template <typename U, typename = std::enable_if<std::is_convertible<T, U>::value>>
1552 return RVec<U>(this->begin(), this->end());
1555 using SuperClass::operator[];
1557 template <typename V, typename = std::enable_if<std::is_convertible<V, bool>::value>>
1560 return RVec(SuperClass::operator[](conds));
1563 using SuperClass::at;
1565 friend bool ROOT::Detail::VecOps::IsSmall<T>(
const RVec<T> &
v);
1567 friend bool ROOT::Detail::VecOps::IsAdopting<T>(
const RVec<T> &
v);
1570template <
typename T,
unsigned N>
1573 return X.capacity_in_bytes();
1579#define RVEC_UNARY_OPERATOR(OP) \
1580template <typename T> \
1581RVec<T> operator OP(const RVec<T> &v) \
1584 for (auto &x : ret) \
1593#undef RVEC_UNARY_OPERATOR
1599#define ERROR_MESSAGE(OP) \
1600 "Cannot call operator " #OP " on vectors of different sizes."
1602#define RVEC_BINARY_OPERATOR(OP) \
1603template <typename T0, typename T1> \
1604auto operator OP(const RVec<T0> &v, const T1 &y) \
1605 -> RVec<decltype(v[0] OP y)> \
1607 RVec<decltype(v[0] OP y)> ret(v.size()); \
1608 auto op = [&y](const T0 &x) { return x OP y; }; \
1609 std::transform(v.begin(), v.end(), ret.begin(), op); \
1613template <typename T0, typename T1> \
1614auto operator OP(const T0 &x, const RVec<T1> &v) \
1615 -> RVec<decltype(x OP v[0])> \
1617 RVec<decltype(x OP v[0])> ret(v.size()); \
1618 auto op = [&x](const T1 &y) { return x OP y; }; \
1619 std::transform(v.begin(), v.end(), ret.begin(), op); \
1623template <typename T0, typename T1> \
1624auto operator OP(const RVec<T0> &v0, const RVec<T1> &v1) \
1625 -> RVec<decltype(v0[0] OP v1[0])> \
1627 if (v0.size() != v1.size()) \
1628 throw std::runtime_error(ERROR_MESSAGE(OP)); \
1630 RVec<decltype(v0[0] OP v1[0])> ret(v0.size()); \
1631 auto op = [](const T0 &x, const T1 &y) { return x OP y; }; \
1632 std::transform(v0.begin(), v0.end(), v1.begin(), ret.begin(), op); \
1644#undef RVEC_BINARY_OPERATOR
1650#define RVEC_ASSIGNMENT_OPERATOR(OP) \
1651template <typename T0, typename T1> \
1652RVec<T0>& operator OP(RVec<T0> &v, const T1 &y) \
1654 auto op = [&y](T0 &x) { return x OP y; }; \
1655 std::transform(v.begin(), v.end(), v.begin(), op); \
1659template <typename T0, typename T1> \
1660RVec<T0>& operator OP(RVec<T0> &v0, const RVec<T1> &v1) \
1662 if (v0.size() != v1.size()) \
1663 throw std::runtime_error(ERROR_MESSAGE(OP)); \
1665 auto op = [](T0 &x, const T1 &y) { return x OP y; }; \
1666 std::transform(v0.begin(), v0.end(), v1.begin(), v0.begin(), op); \
1680#undef RVEC_ASSIGNMENT_OPERATOR
1686#define RVEC_LOGICAL_OPERATOR(OP) \
1687template <typename T0, typename T1> \
1688auto operator OP(const RVec<T0> &v, const T1 &y) \
1691 RVec<int> ret(v.size()); \
1692 auto op = [y](const T0 &x) -> int { return x OP y; }; \
1693 std::transform(v.begin(), v.end(), ret.begin(), op); \
1697template <typename T0, typename T1> \
1698auto operator OP(const T0 &x, const RVec<T1> &v) \
1701 RVec<int> ret(v.size()); \
1702 auto op = [x](const T1 &y) -> int { return x OP y; }; \
1703 std::transform(v.begin(), v.end(), ret.begin(), op); \
1707template <typename T0, typename T1> \
1708auto operator OP(const RVec<T0> &v0, const RVec<T1> &v1) \
1711 if (v0.size() != v1.size()) \
1712 throw std::runtime_error(ERROR_MESSAGE(OP)); \
1714 RVec<int> ret(v0.size()); \
1715 auto op = [](const T0 &x, const T1 &y) -> int { return x OP y; }; \
1716 std::transform(v0.begin(), v0.end(), v1.begin(), ret.begin(), op); \
1728#undef RVEC_LOGICAL_OPERATOR
1735template <
typename T>
struct PromoteTypeImpl;
1737template <>
struct PromoteTypeImpl<float> {
using Type = float; };
1738template <>
struct PromoteTypeImpl<
double> {
using Type =
double; };
1739template <>
struct PromoteTypeImpl<long
double> {
using Type =
long double; };
1741template <
typename T>
struct PromoteTypeImpl {
using Type =
double; };
1743template <
typename T>
1744using PromoteType =
typename PromoteTypeImpl<T>::Type;
1746template <
typename U,
typename V>
1747using PromoteTypes =
decltype(PromoteType<U>() + PromoteType<V>());
1751#define RVEC_UNARY_FUNCTION(NAME, FUNC) \
1752 template <typename T> \
1753 RVec<PromoteType<T>> NAME(const RVec<T> &v) \
1755 RVec<PromoteType<T>> ret(v.size()); \
1756 auto f = [](const T &x) { return FUNC(x); }; \
1757 std::transform(v.begin(), v.end(), ret.begin(), f); \
1761#define RVEC_BINARY_FUNCTION(NAME, FUNC) \
1762 template <typename T0, typename T1> \
1763 RVec<PromoteTypes<T0, T1>> NAME(const T0 &x, const RVec<T1> &v) \
1765 RVec<PromoteTypes<T0, T1>> ret(v.size()); \
1766 auto f = [&x](const T1 &y) { return FUNC(x, y); }; \
1767 std::transform(v.begin(), v.end(), ret.begin(), f); \
1771 template <typename T0, typename T1> \
1772 RVec<PromoteTypes<T0, T1>> NAME(const RVec<T0> &v, const T1 &y) \
1774 RVec<PromoteTypes<T0, T1>> ret(v.size()); \
1775 auto f = [&y](const T1 &x) { return FUNC(x, y); }; \
1776 std::transform(v.begin(), v.end(), ret.begin(), f); \
1780 template <typename T0, typename T1> \
1781 RVec<PromoteTypes<T0, T1>> NAME(const RVec<T0> &v0, const RVec<T1> &v1) \
1783 if (v0.size() != v1.size()) \
1784 throw std::runtime_error(ERROR_MESSAGE(NAME)); \
1786 RVec<PromoteTypes<T0, T1>> ret(v0.size()); \
1787 auto f = [](const T0 &x, const T1 &y) { return FUNC(x, y); }; \
1788 std::transform(v0.begin(), v0.end(), v1.begin(), ret.begin(), f); \
1792#define RVEC_STD_UNARY_FUNCTION(F) RVEC_UNARY_FUNCTION(F, std::F)
1793#define RVEC_STD_BINARY_FUNCTION(F) RVEC_BINARY_FUNCTION(F, std::F)
1840#undef RVEC_STD_UNARY_FUNCTION
1847#define RVEC_VDT_UNARY_FUNCTION(F) RVEC_UNARY_FUNCTION(F, vdt::F)
1849RVEC_VDT_UNARY_FUNCTION(fast_expf)
1850RVEC_VDT_UNARY_FUNCTION(fast_logf)
1851RVEC_VDT_UNARY_FUNCTION(fast_sinf)
1852RVEC_VDT_UNARY_FUNCTION(fast_cosf)
1853RVEC_VDT_UNARY_FUNCTION(fast_tanf)
1854RVEC_VDT_UNARY_FUNCTION(fast_asinf)
1855RVEC_VDT_UNARY_FUNCTION(fast_acosf)
1856RVEC_VDT_UNARY_FUNCTION(fast_atanf)
1858RVEC_VDT_UNARY_FUNCTION(fast_exp)
1859RVEC_VDT_UNARY_FUNCTION(fast_log)
1860RVEC_VDT_UNARY_FUNCTION(fast_sin)
1861RVEC_VDT_UNARY_FUNCTION(fast_cos)
1862RVEC_VDT_UNARY_FUNCTION(fast_tan)
1863RVEC_VDT_UNARY_FUNCTION(fast_asin)
1864RVEC_VDT_UNARY_FUNCTION(fast_acos)
1865RVEC_VDT_UNARY_FUNCTION(fast_atan)
1866#undef RVEC_VDT_UNARY_FUNCTION
1870#undef RVEC_UNARY_FUNCTION
1885template <
typename T,
typename V>
1888 if (
v0.size() !=
v1.size())
1889 throw std::runtime_error(
"Cannot compute inner product of vectors of different sizes");
1890 return std::inner_product(
v0.begin(),
v0.end(),
v1.begin(),
decltype(
v0[0] *
v1[0])(0));
1916template <
typename T>
1919 return std::accumulate(
v.begin(),
v.end(), zero);
1924 return std::accumulate(
v.begin(),
v.end(), zero);
1928template <
typename T>
1931 return std::accumulate(
v.begin(),
v.end(), init, std::multiplies<T>());
1946template <
typename T>
1949 if (
v.empty())
return 0.;
1978template <
typename T,
typename R = T>
1981 if (
v.empty())
return zero;
1982 return Sum(
v, zero) /
v.size();
1995template <
typename T>
1998 return *std::max_element(
v.begin(),
v.end());
2011template <
typename T>
2014 return *std::min_element(
v.begin(),
v.end());
2029template <
typename T>
2032 return std::distance(
v.begin(), std::max_element(
v.begin(),
v.end()));
2047template <
typename T>
2050 return std::distance(
v.begin(), std::min_element(
v.begin(),
v.end()));
2064template <
typename T>
2067 const std::size_t
size =
v.size();
2068 if (
size < std::size_t(2))
return 0.;
2069 T sum_squares(0), squared_sum(0);
2070 auto pred = [&sum_squares, &squared_sum](
const T&
x) {sum_squares+=
x*
x; squared_sum+=
x;};
2071 std::for_each(
v.begin(),
v.end(), pred);
2072 squared_sum *= squared_sum;
2074 return 1. / (dsize - 1.) * (sum_squares - squared_sum / dsize );
2088template <
typename T>
2091 return std::sqrt(
Var(
v));
2112template <
typename... Args>
2125 constexpr auto nArgs =
sizeof...(Args);
2128 "Map: the first N-1 arguments must be RVecs or references to RVecs");
2131 std::make_index_sequence<
sizeof...(args) - 1>());
2144template <
typename T,
typename F>
2147 const auto thisSize =
v.size();
2150 for (
auto &&val :
v) {
2152 w.emplace_back(val);
2167template <
typename T>
2171 if (
static_cast<bool>(
e) ==
true)
2186template <
typename T>
2190 if (
static_cast<bool>(
e) ==
false)
2195template <
typename T>
2212template <
typename T>
2218 std::sort(i.
begin(), i.
end(), [&
v](size_type i1, size_type i2) { return v[i1] < v[i2]; });
2233template <
typename T,
typename Compare>
2240 [&
v, &
c](size_type i1, size_type i2) { return c(v[i1], v[i2]); });
2257template <
typename T>
2263 std::stable_sort(i.
begin(), i.
end(), [&
v](size_type i1, size_type i2) { return v[i1] < v[i2]; });
2280template <
typename T,
typename Compare>
2286 std::stable_sort(i.
begin(), i.
end(), [&
v, &
c](size_type i1, size_type i2) { return c(v[i1], v[i2]); });
2301template <
typename T>
2305 const size_type isize = i.size();
2307 for (size_type k = 0; k < isize; k++)
2313template <
typename T>
2317 const size_type isize = i.size();
2319 for (size_type k = 0; k < isize; k++)
2344template <
typename T>
2348 const size_type
size =
v.size();
2349 const size_type absn = std::abs(
n);
2351 const auto msg = std::to_string(absn) +
" elements requested from Take but input contains only " +
2352 std::to_string(
size) +
" elements.";
2353 throw std::runtime_error(msg);
2357 for (size_type k = 0; k < absn; k++)
2358 r[k] =
v[
size - absn + k];
2360 for (size_type k = 0; k < absn; k++)
2385template <
typename T>
2389 const size_type
size =
v.size();
2390 const size_type absn = std::abs(
n);
2402 const auto num_to_fill = absn -
size;
2410template <
typename T>
2414 std::sort(idxs.begin(), idxs.end());
2415 idxs.erase(std::unique(idxs.begin(), idxs.end()), idxs.end());
2418 if (
v.size() > idxs.size())
2419 r.reserve(
v.size() - idxs.size());
2421 auto discardIt = idxs.begin();
2423 for (sz_t i = 0u; i <
v.size(); ++i) {
2424 if (discardIt != idxs.end() && i == *discardIt)
2427 r.emplace_back(
v[i]);
2443template <
typename T>
2447 std::reverse(
r.begin(),
r.end());
2464template <
typename T>
2468 std::sort(
r.begin(),
r.end());
2489template <
typename T,
typename Compare>
2493 std::sort(
r.begin(),
r.end(), std::forward<Compare>(
c));
2513template <
typename T>
2517 std::stable_sort(
r.begin(),
r.end());
2549template <
typename T,
typename Compare>
2553 std::stable_sort(
r.begin(),
r.end(), std::forward<Compare>(
c));
2571 using size_type = std::size_t;
2573 r[0].resize(size1*size2);
2574 r[1].resize(size1*size2);
2576 for(size_type i=0; i<size1; i++) {
2577 for(size_type j=0; j<size2; j++) {
2600template <
typename T1,
typename T2>
2625template <
typename T>
2629 const size_type s =
v.size();
2631 throw std::runtime_error(
"Cannot make unique combinations of size " + std::to_string(
n) +
2632 " from vector of size " + std::to_string(s) +
".");
2636 for(size_type k=0; k<s; k++)
2639 const auto innersize = [=] {
2640 size_type inners = s -
n + 1;
2641 for (size_type
m = s -
n + 2;
m <= s; ++
m)
2644 size_type factn = 1;
2645 for (size_type i = 2; i <=
n; ++i)
2653 size_type inneridx = 0;
2654 for (size_type k = 0; k <
n; k++)
2659 bool run_through =
true;
2663 run_through =
false;
2671 for (
long j=i+1; j<(long)
n; j++)
2673 for (size_type k = 0; k <
n; k++)
2689template <
typename T>
2694 const auto size =
v.size();
2696 for(size_type i=0; i<
size; i++) {
2720template <
typename T>
2724 if (!v2_is_sorted) v2_sorted = Sort(
v2);
2725 const auto v2_begin = v2_is_sorted ?
v2.begin() : v2_sorted.
begin();
2726 const auto v2_end = v2_is_sorted ?
v2.end() : v2_sorted.
end();
2728 const auto size =
v1.size();
2731 for(size_type i=0; i<
size; i++) {
2732 if (std::binary_search(v2_begin, v2_end,
v1[i])) {
2733 r.emplace_back(
v1[i]);
2754template <
typename T>
2758 const size_type
size =
c.size();
2761 for (size_type i=0; i<
size; i++) {
2762 r.emplace_back(
c[i] != 0 ?
v1[i] :
v2[i]);
2782template <
typename T>
2786 const size_type
size =
c.size();
2789 for (size_type i=0; i<
size; i++) {
2790 r.emplace_back(
c[i] != 0 ?
v1[i] :
v2);
2810template <
typename T>
2814 const size_type
size =
c.size();
2817 for (size_type i=0; i<
size; i++) {
2818 r.emplace_back(
c[i] != 0 ?
v1 :
v2[i]);
2836template <
typename T>
2840 const size_type
size =
c.size();
2843 for (size_type i=0; i<
size; i++) {
2844 r.emplace_back(
c[i] != 0 ?
v1 :
v2);
2859template <typename T0, typename T1, typename Common_t = typename std::common_type<T0, T1>::type>
2864 std::copy(
v0.begin(),
v0.end(), std::back_inserter(res));
2865 std::copy(
v1.begin(),
v1.end(), std::back_inserter(res));
2875template <
typename T>
2878 static_assert(std::is_floating_point<T>::value,
2879 "DeltaPhi must be called with floating point values.");
2880 auto r = std::fmod(
v2 -
v1, 2.0 *
c);
2896template <
typename T>
2900 const size_type
size =
v1.size();
2902 for (size_type i = 0; i <
size; i++) {
2903 r[i] = DeltaPhi(
v1[i],
v2[i],
c);
2914template <
typename T>
2918 const size_type
size =
v1.size();
2920 for (size_type i = 0; i <
size; i++) {
2921 r[i] = DeltaPhi(
v1[i],
v2,
c);
2932template <
typename T>
2936 const size_type
size =
v2.size();
2938 for (size_type i = 0; i <
size; i++) {
2939 r[i] = DeltaPhi(
v1,
v2[i],
c);
2951template <
typename T>
2954 const auto dphi = DeltaPhi(phi1, phi2,
c);
2955 return (eta1 - eta2) * (eta1 - eta2) + dphi * dphi;
2965template <
typename T>
2968 return sqrt(DeltaR2(eta1, eta2, phi1, phi2,
c));
2978template <
typename T>
2979T DeltaR(T eta1, T eta2, T phi1, T phi2,
const T
c =
M_PI)
2981 const auto dphi = DeltaPhi(phi1, phi2,
c);
2982 return std::sqrt((eta1 - eta2) * (eta1 - eta2) + dphi * dphi);
2990template <
typename T>
3002 for (std::size_t i = 0u; i <
size; ++i) {
3004 const auto x1 = pt1[i] * std::cos(phi1[i]);
3005 const auto y1 = pt1[i] * std::sin(phi1[i]);
3006 const auto z1 = pt1[i] * std::sinh(eta1[i]);
3007 const auto e1 = std::sqrt(
x1 *
x1 +
y1 *
y1 + z1 * z1 + mass1[i] * mass1[i]);
3009 const auto x2 = pt2[i] * std::cos(phi2[i]);
3010 const auto y2 = pt2[i] * std::sin(phi2[i]);
3011 const auto z2 = pt2[i] * std::sinh(eta2[i]);
3012 const auto e2 = std::sqrt(
x2 *
x2 +
y2 *
y2 + z2 * z2 + mass2[i] * mass2[i]);
3015 const auto e = e1 + e2;
3016 const auto x =
x1 +
x2;
3017 const auto y =
y1 +
y2;
3018 const auto z = z1 + z2;
3020 inv_masses[i] = std::sqrt(
e *
e -
x *
x -
y *
y - z * z);
3032template <
typename T>
3035 const std::size_t
size =
pt.size();
3044 for (std::size_t i = 0u; i <
size; ++ i) {
3046 const auto x =
pt[i] * std::cos(phi[i]);
3048 const auto y =
pt[i] * std::sin(phi[i]);
3050 const auto z =
pt[i] * std::sinh(eta[i]);
3052 const auto e = std::sqrt(
x *
x +
y *
y + z * z + mass[i] * mass[i]);
3057 return std::sqrt(e_sum * e_sum - x_sum * x_sum - y_sum * y_sum - z_sum * z_sum);
3078template <
typename T,
typename... Args_t>
3084 for (
auto i = 0UL; i <
size; ++i) {
3098template <
typename T>
3101 const auto size =
v.size();
3104 for (
auto i = 0UL; i <
size; ++i) {
3121 for (
auto i = 0UL; i <
length; ++i) {
3132 ret.
reserve(begin < end ? end - begin : 0u);
3133 for (
auto i = begin; i < end; ++i)
3154 throw std::runtime_error(
"Range: the stride must not be zero");
3157 float ret_cap = std::ceil(
static_cast<float>(end-begin) / stride);
3163 ret.
reserve(
static_cast<size_t>(ret_cap));
3166 for (
auto i = begin; i < end; i+=stride)
3171 for (
auto i = begin; i > end; i+=stride)
3183 constexpr bool mustConvert = std::is_same<char, T>::value || std::is_same<signed char, T>::value ||
3184 std::is_same<unsigned char, T>::value || std::is_same<wchar_t, T>::value ||
3185 std::is_same<char16_t, T>::value || std::is_same<char32_t, T>::value;
3186 using Print_t =
typename std::conditional<mustConvert, long long int, T>::type;
3188 auto size =
v.size();
3190 for (std::size_t i = 0; i <
size - 1; ++i) {
3191 os << (Print_t)
v[i] <<
", ";
3193 os << (Print_t)
v[
size - 1];
3199#if (_VECOPS_USE_EXTERN_TEMPLATES)
3201#define RVEC_EXTERN_UNARY_OPERATOR(T, OP) \
3202 extern template RVec<T> operator OP<T>(const RVec<T> &);
3204#define RVEC_EXTERN_BINARY_OPERATOR(T, OP) \
3205 extern template auto operator OP<T, T>(const T &x, const RVec<T> &v) \
3206 -> RVec<decltype(x OP v[0])>; \
3207 extern template auto operator OP<T, T>(const RVec<T> &v, const T &y) \
3208 -> RVec<decltype(v[0] OP y)>; \
3209 extern template auto operator OP<T, T>(const RVec<T> &v0, const RVec<T> &v1)\
3210 -> RVec<decltype(v0[0] OP v1[0])>;
3212#define RVEC_EXTERN_ASSIGN_OPERATOR(T, OP) \
3213 extern template RVec<T> &operator OP<T, T>(RVec<T> &, const T &); \
3214 extern template RVec<T> &operator OP<T, T>(RVec<T> &, const RVec<T> &);
3216#define RVEC_EXTERN_LOGICAL_OPERATOR(T, OP) \
3217 extern template RVec<int> operator OP<T, T>(const RVec<T> &, const T &); \
3218 extern template RVec<int> operator OP<T, T>(const T &, const RVec<T> &); \
3219 extern template RVec<int> operator OP<T, T>(const RVec<T> &, const RVec<T> &);
3221#define RVEC_EXTERN_FLOAT_TEMPLATE(T) \
3222 extern template class RVec<T>; \
3223 RVEC_EXTERN_UNARY_OPERATOR(T, +) \
3224 RVEC_EXTERN_UNARY_OPERATOR(T, -) \
3225 RVEC_EXTERN_UNARY_OPERATOR(T, !) \
3226 RVEC_EXTERN_BINARY_OPERATOR(T, +) \
3227 RVEC_EXTERN_BINARY_OPERATOR(T, -) \
3228 RVEC_EXTERN_BINARY_OPERATOR(T, *) \
3229 RVEC_EXTERN_BINARY_OPERATOR(T, /) \
3230 RVEC_EXTERN_ASSIGN_OPERATOR(T, +=) \
3231 RVEC_EXTERN_ASSIGN_OPERATOR(T, -=) \
3232 RVEC_EXTERN_ASSIGN_OPERATOR(T, *=) \
3233 RVEC_EXTERN_ASSIGN_OPERATOR(T, /=) \
3234 RVEC_EXTERN_LOGICAL_OPERATOR(T, <) \
3235 RVEC_EXTERN_LOGICAL_OPERATOR(T, >) \
3236 RVEC_EXTERN_LOGICAL_OPERATOR(T, ==) \
3237 RVEC_EXTERN_LOGICAL_OPERATOR(T, !=) \
3238 RVEC_EXTERN_LOGICAL_OPERATOR(T, <=) \
3239 RVEC_EXTERN_LOGICAL_OPERATOR(T, >=) \
3240 RVEC_EXTERN_LOGICAL_OPERATOR(T, &&) \
3241 RVEC_EXTERN_LOGICAL_OPERATOR(T, ||)
3243#define RVEC_EXTERN_INTEGER_TEMPLATE(T) \
3244 extern template class RVec<T>; \
3245 RVEC_EXTERN_UNARY_OPERATOR(T, +) \
3246 RVEC_EXTERN_UNARY_OPERATOR(T, -) \
3247 RVEC_EXTERN_UNARY_OPERATOR(T, ~) \
3248 RVEC_EXTERN_UNARY_OPERATOR(T, !) \
3249 RVEC_EXTERN_BINARY_OPERATOR(T, +) \
3250 RVEC_EXTERN_BINARY_OPERATOR(T, -) \
3251 RVEC_EXTERN_BINARY_OPERATOR(T, *) \
3252 RVEC_EXTERN_BINARY_OPERATOR(T, /) \
3253 RVEC_EXTERN_BINARY_OPERATOR(T, %) \
3254 RVEC_EXTERN_BINARY_OPERATOR(T, &) \
3255 RVEC_EXTERN_BINARY_OPERATOR(T, |) \
3256 RVEC_EXTERN_BINARY_OPERATOR(T, ^) \
3257 RVEC_EXTERN_ASSIGN_OPERATOR(T, +=) \
3258 RVEC_EXTERN_ASSIGN_OPERATOR(T, -=) \
3259 RVEC_EXTERN_ASSIGN_OPERATOR(T, *=) \
3260 RVEC_EXTERN_ASSIGN_OPERATOR(T, /=) \
3261 RVEC_EXTERN_ASSIGN_OPERATOR(T, %=) \
3262 RVEC_EXTERN_ASSIGN_OPERATOR(T, &=) \
3263 RVEC_EXTERN_ASSIGN_OPERATOR(T, |=) \
3264 RVEC_EXTERN_ASSIGN_OPERATOR(T, ^=) \
3265 RVEC_EXTERN_ASSIGN_OPERATOR(T, >>=) \
3266 RVEC_EXTERN_ASSIGN_OPERATOR(T, <<=) \
3267 RVEC_EXTERN_LOGICAL_OPERATOR(T, <) \
3268 RVEC_EXTERN_LOGICAL_OPERATOR(T, >) \
3269 RVEC_EXTERN_LOGICAL_OPERATOR(T, ==) \
3270 RVEC_EXTERN_LOGICAL_OPERATOR(T, !=) \
3271 RVEC_EXTERN_LOGICAL_OPERATOR(T, <=) \
3272 RVEC_EXTERN_LOGICAL_OPERATOR(T, >=) \
3273 RVEC_EXTERN_LOGICAL_OPERATOR(T, &&) \
3274 RVEC_EXTERN_LOGICAL_OPERATOR(T, ||)
3276RVEC_EXTERN_INTEGER_TEMPLATE(
char)
3277RVEC_EXTERN_INTEGER_TEMPLATE(
short)
3278RVEC_EXTERN_INTEGER_TEMPLATE(
int)
3279RVEC_EXTERN_INTEGER_TEMPLATE(
long)
3282RVEC_EXTERN_INTEGER_TEMPLATE(
unsigned char)
3283RVEC_EXTERN_INTEGER_TEMPLATE(
unsigned short)
3284RVEC_EXTERN_INTEGER_TEMPLATE(
unsigned int)
3285RVEC_EXTERN_INTEGER_TEMPLATE(
unsigned long)
3288RVEC_EXTERN_FLOAT_TEMPLATE(
float)
3289RVEC_EXTERN_FLOAT_TEMPLATE(
double)
3291#undef RVEC_EXTERN_UNARY_OPERATOR
3292#undef RVEC_EXTERN_BINARY_OPERATOR
3293#undef RVEC_EXTERN_ASSIGN_OPERATOR
3294#undef RVEC_EXTERN_LOGICAL_OPERATOR
3295#undef RVEC_EXTERN_INTEGER_TEMPLATE
3296#undef RVEC_EXTERN_FLOAT_TEMPLATE
3298#define RVEC_EXTERN_UNARY_FUNCTION(T, NAME, FUNC) \
3299 extern template RVec<PromoteType<T>> NAME(const RVec<T> &);
3301#define RVEC_EXTERN_STD_UNARY_FUNCTION(T, F) RVEC_EXTERN_UNARY_FUNCTION(T, F, std::F)
3303#define RVEC_EXTERN_BINARY_FUNCTION(T0, T1, NAME, FUNC) \
3304 extern template RVec<PromoteTypes<T0, T1>> NAME(const RVec<T0> &, const T1 &); \
3305 extern template RVec<PromoteTypes<T0, T1>> NAME(const T0 &, const RVec<T1> &); \
3306 extern template RVec<PromoteTypes<T0, T1>> NAME(const RVec<T0> &, const RVec<T1> &);
3308#define RVEC_EXTERN_STD_BINARY_FUNCTION(T, F) RVEC_EXTERN_BINARY_FUNCTION(T, T, F, std::F)
3310#define RVEC_EXTERN_STD_FUNCTIONS(T) \
3311 RVEC_EXTERN_STD_UNARY_FUNCTION(T, abs) \
3312 RVEC_EXTERN_STD_BINARY_FUNCTION(T, fdim) \
3313 RVEC_EXTERN_STD_BINARY_FUNCTION(T, fmod) \
3314 RVEC_EXTERN_STD_BINARY_FUNCTION(T, remainder) \
3315 RVEC_EXTERN_STD_UNARY_FUNCTION(T, exp) \
3316 RVEC_EXTERN_STD_UNARY_FUNCTION(T, exp2) \
3317 RVEC_EXTERN_STD_UNARY_FUNCTION(T, expm1) \
3318 RVEC_EXTERN_STD_UNARY_FUNCTION(T, log) \
3319 RVEC_EXTERN_STD_UNARY_FUNCTION(T, log10) \
3320 RVEC_EXTERN_STD_UNARY_FUNCTION(T, log2) \
3321 RVEC_EXTERN_STD_UNARY_FUNCTION(T, log1p) \
3322 RVEC_EXTERN_STD_BINARY_FUNCTION(T, pow) \
3323 RVEC_EXTERN_STD_UNARY_FUNCTION(T, sqrt) \
3324 RVEC_EXTERN_STD_UNARY_FUNCTION(T, cbrt) \
3325 RVEC_EXTERN_STD_BINARY_FUNCTION(T, hypot) \
3326 RVEC_EXTERN_STD_UNARY_FUNCTION(T, sin) \
3327 RVEC_EXTERN_STD_UNARY_FUNCTION(T, cos) \
3328 RVEC_EXTERN_STD_UNARY_FUNCTION(T, tan) \
3329 RVEC_EXTERN_STD_UNARY_FUNCTION(T, asin) \
3330 RVEC_EXTERN_STD_UNARY_FUNCTION(T, acos) \
3331 RVEC_EXTERN_STD_UNARY_FUNCTION(T, atan) \
3332 RVEC_EXTERN_STD_BINARY_FUNCTION(T, atan2) \
3333 RVEC_EXTERN_STD_UNARY_FUNCTION(T, sinh) \
3334 RVEC_EXTERN_STD_UNARY_FUNCTION(T, cosh) \
3335 RVEC_EXTERN_STD_UNARY_FUNCTION(T, tanh) \
3336 RVEC_EXTERN_STD_UNARY_FUNCTION(T, asinh) \
3337 RVEC_EXTERN_STD_UNARY_FUNCTION(T, acosh) \
3338 RVEC_EXTERN_STD_UNARY_FUNCTION(T, atanh) \
3339 RVEC_EXTERN_STD_UNARY_FUNCTION(T, floor) \
3340 RVEC_EXTERN_STD_UNARY_FUNCTION(T, ceil) \
3341 RVEC_EXTERN_STD_UNARY_FUNCTION(T, trunc) \
3342 RVEC_EXTERN_STD_UNARY_FUNCTION(T, round) \
3343 RVEC_EXTERN_STD_UNARY_FUNCTION(T, erf) \
3344 RVEC_EXTERN_STD_UNARY_FUNCTION(T, erfc) \
3345 RVEC_EXTERN_STD_UNARY_FUNCTION(T, lgamma) \
3346 RVEC_EXTERN_STD_UNARY_FUNCTION(T, tgamma) \
3348RVEC_EXTERN_STD_FUNCTIONS(
float)
3349RVEC_EXTERN_STD_FUNCTIONS(
double)
3350#undef RVEC_EXTERN_STD_UNARY_FUNCTION
3351#undef RVEC_EXTERN_STD_BINARY_FUNCTION
3352#undef RVEC_EXTERN_STD_UNARY_FUNCTIONS
3356#define RVEC_EXTERN_VDT_UNARY_FUNCTION(T, F) RVEC_EXTERN_UNARY_FUNCTION(T, F, vdt::F)
3358RVEC_EXTERN_VDT_UNARY_FUNCTION(
float, fast_expf)
3359RVEC_EXTERN_VDT_UNARY_FUNCTION(
float, fast_logf)
3360RVEC_EXTERN_VDT_UNARY_FUNCTION(
float, fast_sinf)
3361RVEC_EXTERN_VDT_UNARY_FUNCTION(
float, fast_cosf)
3362RVEC_EXTERN_VDT_UNARY_FUNCTION(
float, fast_tanf)
3363RVEC_EXTERN_VDT_UNARY_FUNCTION(
float, fast_asinf)
3364RVEC_EXTERN_VDT_UNARY_FUNCTION(
float, fast_acosf)
3365RVEC_EXTERN_VDT_UNARY_FUNCTION(
float, fast_atanf)
3367RVEC_EXTERN_VDT_UNARY_FUNCTION(
double, fast_exp)
3368RVEC_EXTERN_VDT_UNARY_FUNCTION(
double, fast_log)
3369RVEC_EXTERN_VDT_UNARY_FUNCTION(
double, fast_sin)
3370RVEC_EXTERN_VDT_UNARY_FUNCTION(
double, fast_cos)
3371RVEC_EXTERN_VDT_UNARY_FUNCTION(
double, fast_tan)
3372RVEC_EXTERN_VDT_UNARY_FUNCTION(
double, fast_asin)
3373RVEC_EXTERN_VDT_UNARY_FUNCTION(
double, fast_acos)
3374RVEC_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.
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]...))>
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)...))
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.