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 < stdexcept>
7- #include < string> // for string, basic_string
8- #include < type_traits> // for decay, enable_if, is_same, is_convertible
8+ #include < string> // for string, basic_string
9+ #include < type_traits> // for decay, enable_if, is_same, is_convertible
10+ #include < unordered_map> // for std::unordered_map
11+ #include < vector> // for std::vector
912
1013#include " cpp11/R.hpp" // for SEXP, SEXPREC, Rf_xlength, R_xlen_t
1114#include " cpp11/protect.hpp" // for stop, protect, safe, protect::function
@@ -243,7 +246,7 @@ enable_if_integral<T, SEXP> as_sexp(const Container& from) {
243246}
244247
245248inline SEXP as_sexp (std::initializer_list<int > from) {
246- return as_sexp< std::initializer_list <int >> (from);
249+ return as_sexp ( std::vector <int >(from) );
247250}
248251
249252template <typename Container, typename T = typename Container::value_type,
@@ -261,7 +264,7 @@ enable_if_floating_point<T, SEXP> as_sexp(const Container& from) {
261264}
262265
263266inline SEXP as_sexp (std::initializer_list<double > from) {
264- return as_sexp< std::initializer_list <double >> (from);
267+ return as_sexp ( std::vector <double >(from) );
265268}
266269
267270template <typename Container, typename T = typename Container::value_type,
@@ -279,7 +282,7 @@ enable_if_bool<T, SEXP> as_sexp(const Container& from) {
279282}
280283
281284inline SEXP as_sexp (std::initializer_list<bool > from) {
282- return as_sexp< std::initializer_list <bool >> (from);
285+ return as_sexp ( std::vector <bool >(from) );
283286}
284287
285288namespace detail {
@@ -325,12 +328,81 @@ enable_if_c_string<T, SEXP> as_sexp(const Container& from) {
325328}
326329
327330inline SEXP as_sexp (std::initializer_list<const char *> from) {
328- return as_sexp< std::initializer_list <const char *>> (from);
331+ return as_sexp ( std::vector <const char *>(from) );
329332}
330333
331334template <typename T, typename = disable_if_r_string<T>>
332335enable_if_convertible_to_sexp<T, SEXP> as_sexp (const T& from) {
333336 return from;
334337}
335338
339+ // Pacha: Specialization for std::map
340+ // NOTE: I did not use templates to avoid clashes with doubles/function/etc.
341+ inline SEXP as_sexp (const std::map<std::string, SEXP>& map) {
342+ R_xlen_t size = map.size ();
343+ SEXP result = PROTECT (Rf_allocVector (VECSXP, size));
344+ SEXP names = PROTECT (Rf_allocVector (STRSXP, size));
345+
346+ auto it = map.begin ();
347+ for (R_xlen_t i = 0 ; i < size; ++i, ++it) {
348+ SET_VECTOR_ELT (result, i, it->second );
349+ SET_STRING_ELT (names, i, Rf_mkCharCE (it->first .c_str (), CE_UTF8));
350+ }
351+
352+ Rf_setAttrib (result, R_NamesSymbol, names);
353+ UNPROTECT (2 );
354+ return result;
355+ }
356+
357+ // Specialization for std::map<double, int>
358+ inline SEXP as_sexp (const std::map<double , int >& map) {
359+ R_xlen_t size = map.size ();
360+ SEXP result = PROTECT (Rf_allocVector (VECSXP, size));
361+ SEXP names = PROTECT (Rf_allocVector (REALSXP, size));
362+
363+ auto it = map.begin ();
364+ for (R_xlen_t i = 0 ; i < size; ++i, ++it) {
365+ SET_VECTOR_ELT (result, i, Rf_ScalarInteger (it->second ));
366+ REAL (names)[i] = it->first ;
367+ }
368+
369+ Rf_setAttrib (result, R_NamesSymbol, names);
370+ UNPROTECT (2 );
371+ return result;
372+ }
373+
374+ // Pacha: Specialization for std::unordered_map
375+ inline SEXP as_sexp (const std::unordered_map<std::string, SEXP>& map) {
376+ R_xlen_t size = map.size ();
377+ SEXP result = PROTECT (Rf_allocVector (VECSXP, size));
378+ SEXP names = PROTECT (Rf_allocVector (STRSXP, size));
379+
380+ auto it = map.begin ();
381+ for (R_xlen_t i = 0 ; i < size; ++i, ++it) {
382+ SET_VECTOR_ELT (result, i, it->second );
383+ SET_STRING_ELT (names, i, Rf_mkCharCE (it->first .c_str (), CE_UTF8));
384+ }
385+
386+ Rf_setAttrib (result, R_NamesSymbol, names);
387+ UNPROTECT (2 );
388+ return result;
389+ }
390+
391+ // Specialization for std::unordered_map<double, int>
392+ inline SEXP as_sexp (const std::unordered_map<double , int >& map) {
393+ R_xlen_t size = map.size ();
394+ SEXP result = PROTECT (Rf_allocVector (VECSXP, size));
395+ SEXP names = PROTECT (Rf_allocVector (REALSXP, size));
396+
397+ auto it = map.begin ();
398+ for (R_xlen_t i = 0 ; i < size; ++i, ++it) {
399+ SET_VECTOR_ELT (result, i, Rf_ScalarInteger (it->second ));
400+ REAL (names)[i] = it->first ;
401+ }
402+
403+ Rf_setAttrib (result, R_NamesSymbol, names);
404+ UNPROTECT (2 );
405+ return result;
406+ }
407+
336408} // namespace cpp11
0 commit comments