Skip to content

Commit ca1a13b

Browse files
author
Daniel C. Dillon
committed
Added Rcpp::algorithm::ctype "type trait" to decay any type to one of the primitive arithmetic types or to std::string and applied this to the current algorithms.
1 parent fc65cda commit ca1a13b

File tree

1 file changed

+104
-80
lines changed

1 file changed

+104
-80
lines changed

inst/include/Rcpp/algorithm.h

Lines changed: 104 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,92 @@ namespace helpers {
4747
static inline RCPP_CONSTEXPR T ONE() { return rtype_helper< typename traits::remove_const_and_reference< T >::type >::ONE(); }
4848
};
4949

50+
typedef struct {char a[1];} CTYPE_CHAR;
51+
typedef struct {char a[2];} CTYPE_SHORT;
52+
typedef struct {char a[3];} CTYPE_INT;
53+
typedef struct {char a[4];} CTYPE_LONG;
54+
typedef struct {char a[5];} CTYPE_LONG_LONG;
55+
typedef struct {char a[6];} CTYPE_FLOAT;
56+
typedef struct {char a[7];} CTYPE_DOUBLE;
57+
typedef struct {char a[8];} CTYPE_LONG_DOUBLE;
58+
typedef struct {char a[9];} CTYPE_STRING;
59+
typedef struct {char a[10];} CTYPE_UNSIGNED_CHAR;
60+
typedef struct {char a[11];} CTYPE_UNSIGNED_SHORT;
61+
typedef struct {char a[12];} CTYPE_UNSIGNED_INT;
62+
typedef struct {char a[13];} CTYPE_UNSIGNED_LONG;
63+
typedef struct {char a[14];} CTYPE_UNSIGNED_LONG_LONG;
64+
typedef struct {char a[128];} CTYPE_UNKNOWN;
65+
66+
template< std::size_t I >
67+
struct ctype_helper { };
68+
69+
template<>
70+
struct ctype_helper< sizeof(CTYPE_CHAR) > { typedef char type; };
71+
72+
template<>
73+
struct ctype_helper< sizeof(CTYPE_SHORT) > { typedef short type; };
74+
75+
template<>
76+
struct ctype_helper< sizeof(CTYPE_INT) > { typedef int type; };
77+
78+
template<>
79+
struct ctype_helper< sizeof(CTYPE_LONG) > { typedef long type; };
80+
81+
template<>
82+
struct ctype_helper< sizeof(CTYPE_LONG_LONG) > { typedef long long type; };
83+
84+
template<>
85+
struct ctype_helper< sizeof(CTYPE_FLOAT) > { typedef float type; };
86+
87+
template<>
88+
struct ctype_helper< sizeof(CTYPE_DOUBLE) > { typedef double type; };
89+
90+
template<>
91+
struct ctype_helper< sizeof(CTYPE_LONG_DOUBLE) > { typedef long double type; };
92+
93+
template<>
94+
struct ctype_helper< sizeof(CTYPE_STRING) > { typedef std::string type; };
95+
96+
template<>
97+
struct ctype_helper< sizeof(CTYPE_UNSIGNED_CHAR) > { typedef unsigned char type; };
98+
99+
template<>
100+
struct ctype_helper< sizeof(CTYPE_UNSIGNED_SHORT) > { typedef unsigned short type; };
101+
102+
template<>
103+
struct ctype_helper< sizeof(CTYPE_UNSIGNED_INT) > { typedef unsigned int type; };
104+
105+
template<>
106+
struct ctype_helper< sizeof(CTYPE_UNSIGNED_LONG) > { typedef unsigned long type; };
107+
108+
template<>
109+
struct ctype_helper< sizeof(CTYPE_UNSIGNED_LONG_LONG) > { typedef unsigned long long type; };
110+
111+
112+
template< typename T >
113+
struct ctype
114+
{
115+
static CTYPE_CHAR test(const char &);
116+
static CTYPE_SHORT test(const short &);
117+
static CTYPE_INT test(const int &);
118+
static CTYPE_LONG test(const long &);
119+
static CTYPE_LONG_LONG test(const long long &);
120+
static CTYPE_FLOAT test(const float &);
121+
static CTYPE_DOUBLE test(const double &);
122+
static CTYPE_LONG_DOUBLE test(const long double &);
123+
static CTYPE_STRING test(const std::string &);
124+
static CTYPE_UNSIGNED_CHAR test(const unsigned char &);
125+
static CTYPE_UNSIGNED_SHORT test(const unsigned short &);
126+
static CTYPE_UNSIGNED_INT test(const unsigned int &);
127+
static CTYPE_UNSIGNED_LONG test(const unsigned long &);
128+
static CTYPE_UNSIGNED_LONG_LONG test(const unsigned long long &);
129+
static CTYPE_UNKNOWN test(...);
130+
131+
static T make();
132+
133+
typedef typename ctype_helper< sizeof(test(make())) >::type type;
134+
};
135+
50136
struct log {
51137
template< typename T >
52138
inline double operator()(T val) {
@@ -82,9 +168,9 @@ namespace helpers {
82168
} // namespace helpers
83169

84170
template< typename InputIterator >
85-
typename std::iterator_traits< InputIterator >::value_type sum(InputIterator begin, InputIterator end) {
171+
typename helpers::ctype< typename std::iterator_traits< InputIterator >::value_type >::type sum(InputIterator begin, InputIterator end) {
86172

87-
typedef typename std::iterator_traits< InputIterator >::value_type value_type;
173+
typedef typename helpers::ctype< typename std::iterator_traits< InputIterator >::value_type >::type value_type;
88174
typedef typename helpers::rtype< value_type > rtype;
89175

90176
if (begin != end) {
@@ -105,9 +191,9 @@ typename std::iterator_traits< InputIterator >::value_type sum(InputIterator beg
105191
}
106192

107193
template< typename InputIterator >
108-
typename std::iterator_traits< InputIterator >::value_type sum_nona(InputIterator begin, InputIterator end) {
194+
typename helpers::ctype< typename std::iterator_traits< InputIterator >::value_type >::type sum_nona(InputIterator begin, InputIterator end) {
109195

110-
typedef typename std::iterator_traits< InputIterator >::value_type value_type;
196+
typedef typename helpers::ctype< typename std::iterator_traits< InputIterator >::value_type >::type value_type;
111197
typedef typename helpers::rtype< value_type > rtype;
112198

113199
if (begin != end) {
@@ -124,9 +210,9 @@ typename std::iterator_traits< InputIterator >::value_type sum_nona(InputIterato
124210
}
125211

126212
template< typename InputIterator >
127-
typename std::iterator_traits< InputIterator >::value_type prod(InputIterator begin, InputIterator end) {
213+
typename helpers::ctype< typename std::iterator_traits< InputIterator >::value_type >::type prod(InputIterator begin, InputIterator end) {
128214

129-
typedef typename std::iterator_traits< InputIterator >::value_type value_type;
215+
typedef typename helpers::ctype< typename std::iterator_traits< InputIterator >::value_type >::type value_type;
130216
typedef typename helpers::rtype< value_type > rtype;
131217

132218
if (begin != end) {
@@ -147,9 +233,9 @@ typename std::iterator_traits< InputIterator >::value_type prod(InputIterator be
147233
}
148234

149235
template< typename InputIterator >
150-
typename std::iterator_traits< InputIterator >::value_type prod_nona(InputIterator begin, InputIterator end) {
236+
typename helpers::ctype< typename std::iterator_traits< InputIterator >::value_type >::type prod_nona(InputIterator begin, InputIterator end) {
151237

152-
typedef typename std::iterator_traits< InputIterator >::value_type value_type;
238+
typedef typename helpers::ctype< typename std::iterator_traits< InputIterator >::value_type >::type value_type;
153239
typedef typename helpers::rtype< value_type > rtype;
154240

155241
if (begin != end) {
@@ -166,8 +252,8 @@ typename std::iterator_traits< InputIterator >::value_type prod_nona(InputIterat
166252
}
167253

168254
template< typename InputIterator >
169-
typename std::iterator_traits< InputIterator >::value_type max(InputIterator begin, InputIterator end) {
170-
typedef typename std::iterator_traits< InputIterator >::value_type value_type;
255+
typename helpers::ctype< typename std::iterator_traits< InputIterator >::value_type >::type max(InputIterator begin, InputIterator end) {
256+
typedef typename helpers::ctype< typename std::iterator_traits< InputIterator >::value_type >::type value_type;
171257
typedef typename helpers::rtype< value_type > rtype;
172258

173259
if (begin != end) {
@@ -188,8 +274,8 @@ typename std::iterator_traits< InputIterator >::value_type max(InputIterator beg
188274
}
189275

190276
template< typename InputIterator >
191-
typename std::iterator_traits< InputIterator >::value_type max_nona(InputIterator begin, InputIterator end) {
192-
typedef typename std::iterator_traits< InputIterator >::value_type value_type;
277+
typename helpers::ctype< typename std::iterator_traits< InputIterator >::value_type >::type max_nona(InputIterator begin, InputIterator end) {
278+
typedef typename helpers::ctype< typename std::iterator_traits< InputIterator >::value_type >::type value_type;
193279
typedef typename helpers::rtype< value_type > rtype;
194280

195281
if (begin != end) {
@@ -206,8 +292,8 @@ typename std::iterator_traits< InputIterator >::value_type max_nona(InputIterato
206292
}
207293

208294
template< typename InputIterator >
209-
typename std::iterator_traits< InputIterator >::value_type min(InputIterator begin, InputIterator end) {
210-
typedef typename std::iterator_traits< InputIterator >::value_type value_type;
295+
typename helpers::ctype< typename std::iterator_traits< InputIterator >::value_type >::type min(InputIterator begin, InputIterator end) {
296+
typedef typename helpers::ctype< typename std::iterator_traits< InputIterator >::value_type >::type value_type;
211297
typedef typename helpers::rtype< value_type > rtype;
212298

213299
if (begin != end) {
@@ -228,8 +314,8 @@ typename std::iterator_traits< InputIterator >::value_type min(InputIterator beg
228314
}
229315

230316
template< typename InputIterator >
231-
typename std::iterator_traits< InputIterator >::value_type min_nona(InputIterator begin, InputIterator end) {
232-
typedef typename std::iterator_traits< InputIterator >::value_type value_type;
317+
typename helpers::ctype< typename std::iterator_traits< InputIterator >::value_type >::type min_nona(InputIterator begin, InputIterator end) {
318+
typedef typename helpers::ctype< typename std::iterator_traits< InputIterator >::value_type >::type value_type;
233319
typedef typename helpers::rtype< value_type > rtype;
234320

235321
if (begin != end) {
@@ -247,7 +333,7 @@ typename std::iterator_traits< InputIterator >::value_type min_nona(InputIterato
247333

248334
// for REALSXP
249335
template< typename InputIterator >
250-
typename traits::enable_if< traits::same_type< typename std::iterator_traits< InputIterator >::value_type, double >::value, double >::type
336+
typename traits::enable_if< traits::same_type< typename helpers::ctype< typename std::iterator_traits< InputIterator >::value_type >::type, double >::value, double >::type
251337
mean(InputIterator begin, InputIterator end)
252338
{
253339
if (begin != end)
@@ -273,7 +359,7 @@ mean(InputIterator begin, InputIterator end)
273359

274360
// for LGLSXP and INTSXP
275361
template< typename InputIterator >
276-
typename traits::enable_if< traits::same_type< typename std::iterator_traits< InputIterator >::value_type, int >::value, double >::type
362+
typename traits::enable_if< traits::same_type< typename helpers::ctype< typename std::iterator_traits< InputIterator >::value_type >::type, int >::value, double >::type
277363
mean(InputIterator begin, InputIterator end)
278364
{
279365
if (begin != end)
@@ -313,68 +399,6 @@ void sqrt(InputIterator begin, InputIterator end, OutputIterator out) {
313399
std::transform(begin, end, out, helpers::sqrt());
314400
}
315401

316-
typedef struct {char a[1];} CAN_BE_ONE;
317-
typedef struct {char a[2];} CAN_BE_TWO;
318-
typedef struct {char a[3];} CAN_BE_THREE;
319-
typedef struct {char a[4];} CAN_BE_FOUR;
320-
typedef struct {char a[5];} CAN_BE_FIVE;
321-
typedef struct {char a[6];} CAN_BE_SIX;
322-
typedef struct {char a[7];} CAN_BE_SEVEN;
323-
typedef struct {char a[8];} CAN_BE_EIGHT;
324-
typedef struct {char a[9];} CAN_BE_NINE;
325-
typedef struct {char a[128];} CAN_BE_UNKNOWN;
326-
327-
template< std::size_t I >
328-
struct ctype_helper { };
329-
330-
template<>
331-
struct ctype_helper< sizeof(CAN_BE_ONE) > { typedef char type; };
332-
333-
template<>
334-
struct ctype_helper< sizeof(CAN_BE_TWO) > { typedef short type; };
335-
336-
template<>
337-
struct ctype_helper< sizeof(CAN_BE_THREE) > { typedef int type; };
338-
339-
template<>
340-
struct ctype_helper< sizeof(CAN_BE_FOUR) > { typedef long type; };
341-
342-
template<>
343-
struct ctype_helper< sizeof(CAN_BE_FIVE) > { typedef long long type; };
344-
345-
template<>
346-
struct ctype_helper< sizeof(CAN_BE_SIX) > { typedef float type; };
347-
348-
template<>
349-
struct ctype_helper< sizeof(CAN_BE_SEVEN) > { typedef double type; };
350-
351-
template<>
352-
struct ctype_helper< sizeof(CAN_BE_EIGHT) > { typedef long double type; };
353-
354-
template<>
355-
struct ctype_helper< sizeof(CAN_BE_NINE) > { typedef std::string type; };
356-
357-
358-
template< typename T >
359-
struct ctype
360-
{
361-
static CAN_BE_ONE test(const char &);
362-
static CAN_BE_TWO test(const short &);
363-
static CAN_BE_THREE test(const int &);
364-
static CAN_BE_FOUR test(const long &);
365-
static CAN_BE_FIVE test(const long long &);
366-
static CAN_BE_SIX test(const float &);
367-
static CAN_BE_SEVEN test(const double &);
368-
static CAN_BE_EIGHT test(const long double &);
369-
static CAN_BE_NINE test(const std::string &);
370-
static CAN_BE_UNKNOWN test(...);
371-
372-
static T make();
373-
374-
typedef typename ctype_helper< sizeof(test(make())) >::type type;
375-
};
376-
377-
378402
} // namespace algorithm
379403
} // namespace Rcpp
380404

0 commit comments

Comments
 (0)