Skip to content

Commit

Permalink
Add variadic templates for Language,Vector,InternalStdFunction
Browse files Browse the repository at this point in the history
  • Loading branch information
andrjohns committed May 18, 2024
1 parent c287298 commit c102a00
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 2 deletions.
18 changes: 18 additions & 0 deletions inst/include/Rcpp/InternalFunctionWithStdFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,26 @@
namespace Rcpp {

namespace InternalFunctionWithStdFunction {
#if defined(HAS_VARIADIC_TEMPLATES) || defined(RCPP_USING_CXX11)
template<int...> struct index_sequence {};

template<int N, int... Is>
struct make_index_sequence : make_index_sequence<N-1, N-1, Is...> {};

template<int... Is>
struct make_index_sequence<0, Is...> : index_sequence<Is...> {};

template <typename RESULT_TYPE, typename... Us, int... Is>
RESULT_TYPE call_impl(const std::function<RESULT_TYPE(Us...)> &fun, SEXP* args, index_sequence<Is...>) {
return fun((typename traits::input_parameter<Us>::type(args[Is]))...);
}
template <typename RESULT_TYPE, typename... Us>
RESULT_TYPE call(const std::function<RESULT_TYPE(Us...)> &fun, SEXP* args) {
return call_impl(fun, args, make_index_sequence<sizeof...(Us)>{});
}
#else
#include <Rcpp/generated/InternalFunctionWithStdFunction_call.h>
#endif

template <typename RESULT_TYPE, typename... Args>
class CppFunctionBaseFromStdFunction : public CppFunctionBase {
Expand Down
14 changes: 13 additions & 1 deletion inst/include/Rcpp/Language.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,19 @@ namespace Rcpp{
* 0.0 is wrapped as a numeric vector using wrap( const& double )
* ...
*/
#include <Rcpp/generated/Language__ctors.h>
#if defined(HAS_VARIADIC_TEMPLATES) || defined(RCPP_USING_CXX11)
template <typename... T>
Language_Impl( const std::string& symbol, const T&... t) {
Storage::set__( pairlist(Rf_install( symbol.c_str() ), t...) );
}

template <typename... T>
Language_Impl( const Function& function, const T&... t) {
Storage::set__( pairlist( function, t...) );
}
#else
#include <Rcpp/generated/Language__ctors.h>
#endif

/**
* sets the symbol of the call
Expand Down
14 changes: 14 additions & 0 deletions inst/include/Rcpp/traits/named_object.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
#ifndef Rcpp__traits__named_object__h
#define Rcpp__traits__named_object__h

#include <type_traits>

namespace Rcpp{
class Argument ;

Expand Down Expand Up @@ -63,6 +65,18 @@ template <typename T> struct is_named : public false_type{};
template <typename T> struct is_named< named_object<T> > : public true_type {};
template <> struct is_named< Rcpp::Argument > : public true_type {};


template <typename... T> struct is_any_named : public false_type {};
template <typename T> struct is_any_named<T> : public is_named<T>::type {};

template <typename T, typename... TArgs>
struct is_any_named<T, TArgs...>
: public std::conditional<
is_any_named<T>::value,
std::true_type,
is_any_named<TArgs...>>::type {};


} // namespace traits
} // namespace Rcpp

Expand Down
50 changes: 49 additions & 1 deletion inst/include/Rcpp/vector/Vector.h
Original file line number Diff line number Diff line change
Expand Up @@ -1122,7 +1122,55 @@ class Vector :
return Vector( 0 ) ;
}

#include <Rcpp/generated/Vector__create.h>
#if defined(HAS_VARIADIC_TEMPLATES) || defined(RCPP_USING_CXX11)
public:
template <typename... T>
static Vector create(const T&... t){
return create__dispatch( typename traits::integral_constant<bool,
traits::is_any_named<T...>::value
>::type(), t... ) ;
}

private:
template <typename... T>
static Vector create__dispatch(traits::false_type, const T&... t){
Vector res(sizeof...(T)) ;
iterator it(res.begin());
create_dispatch_impl(it, t...);
return res;
}
template <typename... T>
static Vector create__dispatch( traits::true_type, const T&... t) {
Vector res(sizeof...(T)) ;
Shield<SEXP> names(::Rf_allocVector(STRSXP, sizeof...(T)));
int index = 0;
iterator it(res.begin());
replace_element_impl(it, names, index, t...);
res.attr("names") = names;
return res;
}
template <typename T>
static void create_dispatch_impl(iterator& it, const T& t) {
*it = converter_type::get(t);
}

template <typename T, typename... TArgs>
static void create_dispatch_impl(iterator& it, const T& t, const TArgs&... args) {
*it = converter_type::get(t);
create_dispatch_impl(++it, args...);
}
template <typename T>
static void replace_element_impl(iterator& it, Shield<SEXP>& names, int& index, const T& t) {
replace_element(it, names, index, t);
}
template <typename T, typename... TArgs>
static void replace_element_impl(iterator& it, Shield<SEXP>& names, int& index, const T& t, const TArgs&... args) {
replace_element(it, names, index, t);
replace_element_impl(++it, names, ++index, args...);
}
#else
#include <Rcpp/generated/Vector__create.h>
#endif

public:

Expand Down

0 comments on commit c102a00

Please sign in to comment.