22
33#include < cmath> // for modf
44#include < initializer_list> // for initializer_list
5+ #include < map> // for std::map
56#include < memory> // for std::shared_ptr, std::weak_ptr, std::unique_ptr
67#include < complex>
78#include < stdexcept>
8- #include < string> // for string, basic_string
9- #include < type_traits> // for decay, enable_if, is_same, is_convertible
9+ #include < string> // for string, basic_string
10+ #include < type_traits> // for decay, enable_if, is_same, is_convertible
11+ #include < unordered_map> // for std::unordered_map
12+ #include < vector> // for std::vector
1013
1114#include " cpp11/R.hpp" // for SEXP, SEXPREC, Rf_xlength, R_xlen_t
1215#include " cpp11/protect.hpp" // for stop, protect, safe, protect::function
@@ -277,7 +280,7 @@ enable_if_integral<T, SEXP> as_sexp(const Container& from) {
277280}
278281
279282inline SEXP as_sexp (std::initializer_list<int > from) {
280- return as_sexp< std::initializer_list <int >> (from);
283+ return as_sexp ( std::vector <int >(from) );
281284}
282285
283286template <typename Container, typename T = typename Container::value_type,
@@ -296,7 +299,7 @@ enable_if_floating_point<T, SEXP> as_sexp(const Container& from) {
296299}
297300
298301inline SEXP as_sexp (std::initializer_list<double > from) {
299- return as_sexp< std::initializer_list <double >> (from);
302+ return as_sexp ( std::vector <double >(from) );
300303}
301304
302305template <typename Container, typename T = typename Container::value_type,
@@ -315,7 +318,7 @@ enable_if_bool<T, SEXP> as_sexp(const Container& from) {
315318}
316319
317320inline SEXP as_sexp (std::initializer_list<bool > from) {
318- return as_sexp< std::initializer_list <bool >> (from);
321+ return as_sexp ( std::vector <bool >(from) );
319322}
320323
321324namespace detail {
@@ -361,12 +364,81 @@ enable_if_c_string<T, SEXP> as_sexp(const Container& from) {
361364}
362365
363366inline SEXP as_sexp (std::initializer_list<const char *> from) {
364- return as_sexp< std::initializer_list <const char *>> (from);
367+ return as_sexp ( std::vector <const char *>(from) );
365368}
366369
367370template <typename T, typename = disable_if_r_string<T>>
368371enable_if_convertible_to_sexp<T, SEXP> as_sexp (const T& from) {
369372 return from;
370373}
371374
375+ // Pacha: Specialization for std::map
376+ // NOTE: I did not use templates to avoid clashes with doubles/function/etc.
377+ inline SEXP as_sexp (const std::map<std::string, SEXP>& map) {
378+ R_xlen_t size = map.size ();
379+ SEXP result = PROTECT (Rf_allocVector (VECSXP, size));
380+ SEXP names = PROTECT (Rf_allocVector (STRSXP, size));
381+
382+ auto it = map.begin ();
383+ for (R_xlen_t i = 0 ; i < size; ++i, ++it) {
384+ SET_VECTOR_ELT (result, i, it->second );
385+ SET_STRING_ELT (names, i, Rf_mkCharCE (it->first .c_str (), CE_UTF8));
386+ }
387+
388+ Rf_setAttrib (result, R_NamesSymbol, names);
389+ UNPROTECT (2 );
390+ return result;
391+ }
392+
393+ // Specialization for std::map<double, int>
394+ inline SEXP as_sexp (const std::map<double , int >& map) {
395+ R_xlen_t size = map.size ();
396+ SEXP result = PROTECT (Rf_allocVector (VECSXP, size));
397+ SEXP names = PROTECT (Rf_allocVector (REALSXP, size));
398+
399+ auto it = map.begin ();
400+ for (R_xlen_t i = 0 ; i < size; ++i, ++it) {
401+ SET_VECTOR_ELT (result, i, Rf_ScalarInteger (it->second ));
402+ REAL (names)[i] = it->first ;
403+ }
404+
405+ Rf_setAttrib (result, R_NamesSymbol, names);
406+ UNPROTECT (2 );
407+ return result;
408+ }
409+
410+ // Pacha: Specialization for std::unordered_map
411+ inline SEXP as_sexp (const std::unordered_map<std::string, SEXP>& map) {
412+ R_xlen_t size = map.size ();
413+ SEXP result = PROTECT (Rf_allocVector (VECSXP, size));
414+ SEXP names = PROTECT (Rf_allocVector (STRSXP, size));
415+
416+ auto it = map.begin ();
417+ for (R_xlen_t i = 0 ; i < size; ++i, ++it) {
418+ SET_VECTOR_ELT (result, i, it->second );
419+ SET_STRING_ELT (names, i, Rf_mkCharCE (it->first .c_str (), CE_UTF8));
420+ }
421+
422+ Rf_setAttrib (result, R_NamesSymbol, names);
423+ UNPROTECT (2 );
424+ return result;
425+ }
426+
427+ // Specialization for std::unordered_map<double, int>
428+ inline SEXP as_sexp (const std::unordered_map<double , int >& map) {
429+ R_xlen_t size = map.size ();
430+ SEXP result = PROTECT (Rf_allocVector (VECSXP, size));
431+ SEXP names = PROTECT (Rf_allocVector (REALSXP, size));
432+
433+ auto it = map.begin ();
434+ for (R_xlen_t i = 0 ; i < size; ++i, ++it) {
435+ SET_VECTOR_ELT (result, i, Rf_ScalarInteger (it->second ));
436+ REAL (names)[i] = it->first ;
437+ }
438+
439+ Rf_setAttrib (result, R_NamesSymbol, names);
440+ UNPROTECT (2 );
441+ return result;
442+ }
443+
372444} // namespace cpp11
0 commit comments