Skip to content

Commit c97c502

Browse files
committed
almost there with newer cpp methods
1 parent 90b1418 commit c97c502

File tree

2 files changed

+47
-0
lines changed

2 files changed

+47
-0
lines changed

inst/include/cpp4r/R.hpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,21 @@ inline bool r_env_has(SEXP env, SEXP sym) {
119119
template <typename T>
120120
inline T na();
121121

122+
// Progressive C++ optimization: Use if constexpr in C++17+ for zero-overhead type dispatch
123+
#if CPP4R_HAS_CXX17
124+
template <typename T>
125+
CPP4R_HOT inline bool is_na(const T& value) {
126+
// C++17+: Use if constexpr - compiler only compiles the taken branch
127+
if constexpr (std::is_same<typename std::decay<T>::type, double>::value) {
128+
return ISNA(value); // Fast R macro for doubles
129+
} else if constexpr (std::is_same<typename std::decay<T>::type, int>::value) {
130+
return value == NA_INTEGER; // Direct comparison for integers
131+
} else {
132+
return value == na<T>(); // Generic fallback
133+
}
134+
}
135+
#else
136+
// C++11/14: Use SFINAE (slower compilation, same runtime performance)
122137
template <typename T>
123138
CPP4R_HOT inline typename std::enable_if<!std::is_same<typename std::decay<T>::type, double>::value,
124139
bool>::type
@@ -132,5 +147,6 @@ CPP4R_HOT inline typename std::enable_if<std::is_same<typename std::decay<T>::ty
132147
is_na(const T& value) {
133148
return ISNA(value);
134149
}
150+
#endif
135151

136152
} // namespace cpp4r

inst/include/cpp4r/r_vector_impl.hpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,12 +261,23 @@ template <typename T>
261261
inline SEXP r_vector<T>::valid_type(SEXP x) {
262262
const SEXPTYPE type = get_sexptype();
263263

264+
#if CPP4R_HAS_CXX20
265+
// C++20: Use standard [[unlikely]] attribute for error paths
266+
if (x == nullptr) [[unlikely]] {
267+
throw type_error(type, NILSXP);
268+
}
269+
if (detail::r_typeof(x) != type) [[unlikely]] {
270+
throw type_error(type, detail::r_typeof(x));
271+
}
272+
#else
273+
// C++11-17: Use __builtin_expect
264274
if (CPP4R_UNLIKELY(x == nullptr)) {
265275
throw type_error(type, NILSXP);
266276
}
267277
if (CPP4R_UNLIKELY(detail::r_typeof(x) != type)) {
268278
throw type_error(type, detail::r_typeof(x));
269279
}
280+
#endif
270281

271282
return x;
272283
}
@@ -319,9 +330,17 @@ r_vector<T>::const_iterator::const_iterator(const r_vector* data, R_xlen_t pos)
319330
template <typename T>
320331
CPP4R_ALWAYS_INLINE typename r_vector<T>::const_iterator& r_vector<T>::const_iterator::operator++() {
321332
++pos_;
333+
#if CPP4R_HAS_CXX20
334+
// C++20: Use standard [[unlikely]] attribute (better understood by modern optimizers)
335+
if (use_buf(data_->is_altrep()) && pos_ >= block_start_ + length_) [[unlikely]] {
336+
fill_buf(pos_);
337+
}
338+
#else
339+
// C++11-17: Use __builtin_expect
322340
if (CPP4R_UNLIKELY(use_buf(data_->is_altrep()) && pos_ >= block_start_ + length_)) {
323341
fill_buf(pos_);
324342
}
343+
#endif
325344
return *this;
326345
}
327346

@@ -398,13 +417,25 @@ inline typename r_vector<T>::const_iterator r_vector<T>::find(
398417

399418
template <typename T>
400419
CPP4R_ALWAYS_INLINE T r_vector<T>::const_iterator::operator*() const {
420+
#if CPP4R_HAS_CXX20
421+
// C++20: Use standard [[unlikely]] attribute
422+
if (use_buf(data_->is_altrep())) [[unlikely]] {
423+
// Use pre-loaded buffer for compatible ALTREP types
424+
return static_cast<T>(buf_[pos_ - block_start_]);
425+
} else {
426+
// Otherwise pass through to normal retrieval method (common case)
427+
return data_->operator[](pos_);
428+
}
429+
#else
430+
// C++11-17: Use __builtin_expect
401431
if (CPP4R_UNLIKELY(use_buf(data_->is_altrep()))) {
402432
// Use pre-loaded buffer for compatible ALTREP types
403433
return static_cast<T>(buf_[pos_ - block_start_]);
404434
} else {
405435
// Otherwise pass through to normal retrieval method (common case)
406436
return data_->operator[](pos_);
407437
}
438+
#endif
408439
}
409440

410441
template <typename T>

0 commit comments

Comments
 (0)