-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathConvertUtils.cpp
More file actions
119 lines (93 loc) · 3.43 KB
/
ConvertUtils.cpp
File metadata and controls
119 lines (93 loc) · 3.43 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#include "CppConvert/ConvertUtils.h"
#include <numeric>
namespace CppConvert {
template <typename T>
void SetNames(SEXP res, T myMin, T myMax) {
cpp11::writable::r_vector<T> myNames((myMax - myMin) + 1);
std::iota(myNames.begin(), myNames.end(), myMin);
Rf_setAttrib(res, R_NamesSymbol, myNames);
}
template <typename T>
void SetNames(SEXP res, const std::vector<T> &myNums) {
cpp11::writable::r_vector<T> myNames(myNums);
Rf_setAttrib(res, R_NamesSymbol, myNames);
}
bool CheckNA(double val, VecType myType) {
if (myType == VecType::Integer) {
return (ISNAN(val) || val == NA_INTEGER);
} else {
return ISNAN(val);
}
}
template <typename T>
std::vector<T> GetNumVec(SEXP Rv) {
std::vector<T> v;
const int len = Rf_length(Rv);
if (TYPEOF(Rv) == REALSXP && len) {
double* dblRv = REAL(Rv);
v.assign(dblRv, dblRv + len);
} else if (len) {
int* intRv = INTEGER(Rv);
v.assign(intRv, intRv + len);
}
return v;
}
int rawExport(char* raw, mpz_t value, std::size_t totals) {
std::memset(raw, 0, totals);
int* r = (int*)raw;
r[0] = totals / intSize - 2;
r[1] = static_cast<int>(mpz_sgn(value));
mpz_export(&r[2], 0, 1, intSize, 0, 0, value);
return totals;
}
void QuickSort(std::vector<mpz_class> &arr, int left,
int right, std::vector<std::size_t> &lens) {
int i = left;
int j = right;
mpz_class pivot;
int mid = (left + right) / 2;
pivot = arr[mid];
/* partition */
while (i <= j) {
while (cmp(arr[i], pivot) < 0)
++i;
while (j >= 0 && cmp(arr[j], pivot) > 0)
--j;
if (i <= j && j >= 0) {
swap(arr[i], arr[j]);
std::swap(lens[i], lens[j]);
++i;
--j;
}
}
/* recursion */
if (left < j) QuickSort(arr, left, j, lens);
if (i < right) QuickSort(arr, i, right, lens);
}
SEXP GetCount(bool IsGmp, mpz_class numMpz, double numDbl) {
if (IsGmp) {
const std::size_t sizeNum = intSize *
(2 + (mpz_sizeinbase(numMpz.get_mpz_t(), 2) + numb - 1) / numb);
const std::size_t size = intSize + sizeNum;
cpp11::sexp ans = Rf_allocVector(RAWSXP, size);
char* rPos = (char*) RAW(ans);
((int*) rPos)[0] = 1; // first int is vector-size-header
// current position in rPos[] (starting after vector-size-header)
rawExport(&rPos[intSize], numMpz.get_mpz_t(), sizeNum);
Rf_setAttrib(ans, R_ClassSymbol, Rf_mkString("bigz"));
return(ans);
} else {
if (numDbl > std::numeric_limits<int>::max()) {
return Rf_ScalarReal(numDbl);
} else {
return Rf_ScalarInteger(static_cast<int>(numDbl));
}
}
}
}
template void CppConvert::SetNames(SEXP, double, double);
template void CppConvert::SetNames(SEXP, int, int);
template void CppConvert::SetNames(SEXP, const std::vector<double>&);
template void CppConvert::SetNames(SEXP, const std::vector<int>&);
template std::vector<double> CppConvert::GetNumVec(SEXP);
template std::vector<int> CppConvert::GetNumVec(SEXP);