-
Notifications
You must be signed in to change notification settings - Fork 13
/
scalar.hpp
198 lines (169 loc) · 6.26 KB
/
scalar.hpp
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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
#ifndef RCPPSIMDJSON__DESERIALIZE__SCALAR_HPP
#define RCPPSIMDJSON__DESERIALIZE__SCALAR_HPP
#include "Type_Doctor.hpp"
namespace rcppsimdjson {
namespace deserialize {
/*
* Check for `null`s and return the appropriate `NA`s when found.
*/
static inline constexpr bool HAS_NULLS = true;
/*
* No `null`s present, so skip checking for them.
*/
static inline constexpr bool NO_NULLS = false;
template <typename in_T, rcpp_T R_Type>
inline auto get_scalar_(simdjson::dom::element) noexcept(noxcpt<R_Type>());
template <typename in_T, rcpp_T R_Type, bool has_null>
inline auto get_scalar(simdjson::dom::element element) noexcept(noxcpt<R_Type>()) {
if constexpr (has_null) {
return element.is_null() ? na_val<R_Type>() : get_scalar_<in_T, R_Type>(element);
} else {
return get_scalar_<in_T, R_Type>(element);
}
}
// bool ============================================================================================
// return Rcpp::String
template <>
inline auto
get_scalar_<bool, rcpp_T::chr>(simdjson::dom::element element) noexcept(noxcpt<rcpp_T::chr>()) {
return bool(element) ? Rcpp::String("TRUE") : Rcpp::String("FALSE");
}
// return double
template <>
inline auto
get_scalar_<bool, rcpp_T::dbl>(simdjson::dom::element element) noexcept(noxcpt<rcpp_T::dbl>()) {
return bool(element) ? 1.0 : 0.0;
}
// return int64_t
template <>
inline auto
get_scalar_<bool, rcpp_T::i64>(simdjson::dom::element element) noexcept(noxcpt<rcpp_T::i64>()) {
return bool(element) ? static_cast<int64_t>(1LL) : static_cast<int64_t>(0LL);
}
// return int
template <>
inline auto
get_scalar_<bool, rcpp_T::i32>(simdjson::dom::element element) noexcept(noxcpt<rcpp_T::i32>()) {
return bool(element) ? 1 : 0;
}
// return "bool"
template <>
inline auto
get_scalar_<bool, rcpp_T::lgl>(simdjson::dom::element element) noexcept(noxcpt<rcpp_T::lgl>()) {
return bool(element);
}
// int64_t =========================================================================================
// return Rcpp::String
template <>
inline auto
get_scalar_<int64_t, rcpp_T::chr>(simdjson::dom::element element) noexcept(noxcpt<rcpp_T::chr>()) {
return Rcpp::String(std::to_string(int64_t(element)));
}
// return double
template <>
inline auto
get_scalar_<int64_t, rcpp_T::dbl>(simdjson::dom::element element) noexcept(noxcpt<rcpp_T::dbl>()) {
return double(element);
}
// return int64_t
template <>
inline auto
get_scalar_<int64_t, rcpp_T::i64>(simdjson::dom::element element) noexcept(noxcpt<rcpp_T::i64>()) {
return int64_t(element);
}
// return int
template <>
inline auto
get_scalar_<int64_t, rcpp_T::i32>(simdjson::dom::element element) noexcept(noxcpt<rcpp_T::i32>()) {
return static_cast<int>(int64_t(element));
}
// double ==========================================================================================
// return Rcpp::String
template <>
inline auto
get_scalar_<double, rcpp_T::chr>(simdjson::dom::element element) noexcept(noxcpt<rcpp_T::chr>()) {
auto out = std::to_string(double(element));
out.erase(out.find_last_not_of('0') + 2, std::string::npos);
return Rcpp::String(out);
}
// return double
template <>
inline auto
get_scalar_<double, rcpp_T::dbl>(simdjson::dom::element element) noexcept(noxcpt<rcpp_T::dbl>()) {
return double(element);
}
// std::string (really std::string_view) ===========================================================
// return Rcpp::String
template <>
inline auto get_scalar_<std::string, rcpp_T::chr>(simdjson::dom::element element) noexcept(
noxcpt<rcpp_T::chr>()) {
return Rcpp::String(std::string(std::string_view(element)));
}
// uint64_t ========================================================================================
// return Rcpp::String
template <>
inline auto
get_scalar_<uint64_t, rcpp_T::chr>(simdjson::dom::element element) noexcept(noxcpt<rcpp_T::chr>()) {
return Rcpp::String(std::to_string(uint64_t(element)));
}
// dispatchers =====================================================================================
template <int RTYPE>
inline auto get_scalar_dispatch(simdjson::dom::element) noexcept(noxcpt<RTYPE>());
template <>
inline auto get_scalar_dispatch<STRSXP>(simdjson::dom::element element) noexcept(false) {
switch (element.type()) {
case simdjson::dom::element_type::STRING:
return get_scalar<std::string, rcpp_T::chr, NO_NULLS>(element);
case simdjson::dom::element_type::DOUBLE:
return get_scalar<double, rcpp_T::chr, NO_NULLS>(element);
case simdjson::dom::element_type::INT64:
return get_scalar<int64_t, rcpp_T::chr, NO_NULLS>(element);
case simdjson::dom::element_type::BOOL:
return get_scalar<bool, rcpp_T::chr, NO_NULLS>(element);
case simdjson::dom::element_type::UINT64:
return get_scalar<uint64_t, rcpp_T::chr, NO_NULLS>(element);
default:
return Rcpp::String(NA_STRING);
}
}
template <>
inline auto
get_scalar_dispatch<REALSXP>(simdjson::dom::element element) noexcept(RCPPSIMDJSON_NO_EXCEPTIONS) {
switch (element.type()) {
case simdjson::dom::element_type::DOUBLE:
return get_scalar<double, rcpp_T::dbl, NO_NULLS>(element);
case simdjson::dom::element_type::INT64:
return get_scalar<int64_t, rcpp_T::dbl, NO_NULLS>(element);
case simdjson::dom::element_type::BOOL:
return get_scalar<bool, rcpp_T::dbl, NO_NULLS>(element);
default:
return NA_REAL;
}
}
template <>
inline auto
get_scalar_dispatch<INTSXP>(simdjson::dom::element element) noexcept(RCPPSIMDJSON_NO_EXCEPTIONS) {
switch (element.type()) {
case simdjson::dom::element_type::INT64:
return get_scalar<int64_t, rcpp_T::i32, NO_NULLS>(element);
case simdjson::dom::element_type::BOOL:
return get_scalar<bool, rcpp_T::i32, HAS_NULLS>(element);
default:
return NA_INTEGER;
}
}
// # nocov start
template <>
inline auto
get_scalar_dispatch<LGLSXP>(simdjson::dom::element element) noexcept(RCPPSIMDJSON_NO_EXCEPTIONS) {
switch (element.type()) {
case simdjson::dom::element_type::BOOL:
return get_scalar<bool, rcpp_T::i32, NO_NULLS>(element);
default:
return NA_LOGICAL;
}
}
// # nocov end
} // namespace deserialize
} // namespace rcppsimdjson
#endif