2323namespace Rcpp {
2424namespace internal {
2525
26- // we rely on the presence of unsigned long long types, since we
27- // want to compare specific bit patterns, but we can't explicitly
28- // assign a hex to a double storage.
29-
30- #ifdef RCPP_HAS_LONG_LONG_TYPES
31-
32- #ifdef HAS_STATIC_ASSERT
33- static_assert (
34- sizeof (rcpp_ulong_long_type) == sizeof (double ),
35- " unsigned long long and double have same size"
36- );
37- #endif
38-
39- // motivation: on 32bit architectures, we only see 'LargeNA'
40- // as defined ahead; on 64bit architectures, R defaults to
41- // 'SmallNA' for R_NaReal, but this can get promoted to 'LargeNA'
42- // if a certain operation can create a 'signalling' NA, e.g. NA_real_+1
43- static const rcpp_ulong_long_type SmallNA = 0x7FF00000000007A2 ;
44- static const rcpp_ulong_long_type LargeNA = 0x7FF80000000007A2 ;
45-
46- struct NACanChange {
47- enum { value = sizeof (void *) == 8 };
48- };
49-
50- template <bool NACanChange>
51- bool Rcpp_IsNA__impl (double );
52-
53- template <>
54- inline bool Rcpp_IsNA__impl<true >(double x) {
55- return memcmp (
56- (void *) &x,
57- (void *) &SmallNA,
58- sizeof (double )
59- ) == 0 or memcmp (
60- (void *) &x,
61- (void *) &LargeNA,
62- sizeof (double )
63- ) == 0 ;
64- }
65-
66- template <>
67- inline bool Rcpp_IsNA__impl<false >(double x) {
68- return memcmp (
69- (void *) &x,
70- (void *) &LargeNA,
71- sizeof (double )
72- ) == 0 ;
73- }
74-
75- inline bool Rcpp_IsNA (double x) {
76- return Rcpp_IsNA__impl< NACanChange::value >(x);
77- }
78-
79- inline bool Rcpp_IsNaN (double x) {
80- return R_IsNaN (x);
81- }
82-
83- #else
84-
85- // fallback when we don't have unsigned long long
86-
8726inline bool Rcpp_IsNA (double x) {
8827 return R_IsNA (x);
8928}
@@ -92,7 +31,5 @@ inline bool Rcpp_IsNaN(double x) {
9231 return R_IsNaN (x);
9332}
9433
95- #endif
96-
9734}
9835}
0 commit comments