You are viewing a plain text version of this content. The canonical link for it is here.
Posted to github@arrow.apache.org by GitBox <gi...@apache.org> on 2020/08/03 11:10:30 UTC

[GitHub] [arrow] jimhester commented on a change in pull request #7819: ARROW-9405: [R] Switch to cpp11

jimhester commented on a change in pull request #7819:
URL: https://github.com/apache/arrow/pull/7819#discussion_r464346839



##########
File path: r/src/arrow_rcpp.h
##########
@@ -67,120 +71,150 @@ struct ns {
 }  // namespace arrow
 
 namespace Rcpp {
-namespace internal {
+using NumericVector_ = Rcpp::Vector<REALSXP, Rcpp::NoProtectStorage>;
+using IntegerVector_ = Rcpp::Vector<INTSXP, Rcpp::NoProtectStorage>;
+using LogicalVector_ = Rcpp::Vector<LGLSXP, Rcpp::NoProtectStorage>;
+using StringVector_ = Rcpp::Vector<STRSXP, Rcpp::NoProtectStorage>;
+using CharacterVector_ = StringVector_;
+using RawVector_ = Rcpp::Vector<RAWSXP, Rcpp::NoProtectStorage>;
+using List_ = Rcpp::Vector<VECSXP, Rcpp::NoProtectStorage>;
+}  // namespace Rcpp
+
+namespace cpp11 {
+
+template <typename E>
+typename std::enable_if<std::is_enum<E>::value, E>::type as_cpp(SEXP from) {
+  return E(cpp11::as_cpp<int>(from));
+}
+
+}  // namespace cpp11
+
+namespace arrow {
+namespace r {
 
 template <typename Pointer>
-Pointer r6_to_smart_pointer(SEXP self) {
+Pointer r6_to_pointer(SEXP self) {
   return reinterpret_cast<Pointer>(
       R_ExternalPtrAddr(Rf_findVarInFrame(self, arrow::r::symbols::xp)));
 }
 
-}  // namespace internal
-
-template <typename T>
-class ConstReferenceSmartPtrInputParameter {
+template <typename T, template <class> class SmartPtr>
+class ConstRefSmartPtrInput {
  public:
-  using const_reference = const T&;
+  using const_reference = const SmartPtr<T>&;
 
-  explicit ConstReferenceSmartPtrInputParameter(SEXP self)
-      : ptr(internal::r6_to_smart_pointer<const T*>(self)) {}
+  explicit ConstRefSmartPtrInput(SEXP self)
+      : ptr(r6_to_pointer<const SmartPtr<T>*>(self)) {}
 
   inline operator const_reference() { return *ptr; }
 
  private:
-  const T* ptr;
+  // this class host
+  const SmartPtr<T>* ptr;
 };
 
-template <typename T>
-class ConstReferenceVectorSmartPtrInputParameter {
+template <typename T, template <class> class SmartPtr>
+class ConstRefVectorSmartPtrInput {
  public:
-  using const_reference = const std::vector<T>&;
+  using const_reference = const std::vector<SmartPtr<T>>&;
 
-  explicit ConstReferenceVectorSmartPtrInputParameter(SEXP self) : vec() {
+  explicit ConstRefVectorSmartPtrInput(SEXP self) : vec() {
     R_xlen_t n = XLENGTH(self);
     for (R_xlen_t i = 0; i < n; i++) {
-      vec.push_back(*internal::r6_to_smart_pointer<const T*>(VECTOR_ELT(self, i)));
+      vec.push_back(*r6_to_pointer<const SmartPtr<T>*>(VECTOR_ELT(self, i)));
     }
   }
 
   inline operator const_reference() { return vec; }
 
  private:
-  std::vector<T> vec;
+  std::vector<SmartPtr<T>> vec;
 };
 
-namespace traits {
-
 template <typename T>
-struct input_parameter<const std::shared_ptr<T>&> {
-  typedef typename Rcpp::ConstReferenceSmartPtrInputParameter<std::shared_ptr<T>> type;
+class default_input {
+ public:
+  default_input(SEXP from) : from_(from) {}
+
+  inline operator T() const { return cpp11::as_cpp<T>(from_); }
+
+ private:
+  SEXP from_;
 };
 
 template <typename T>
-struct input_parameter<const std::unique_ptr<T>&> {
-  typedef typename Rcpp::ConstReferenceSmartPtrInputParameter<std::unique_ptr<T>> type;
+class const_reference_input {
+ public:
+  const_reference_input(SEXP from) : obj_(cpp11::as_cpp<T>(from)) {}
+
+  using const_reference = const T&;
+  inline operator const_reference() const { return obj_; }
+
+ private:
+  T obj_;
 };
 
 template <typename T>
-struct input_parameter<const std::vector<std::shared_ptr<T>>&> {
-  typedef typename Rcpp::ConstReferenceVectorSmartPtrInputParameter<std::shared_ptr<T>>
-      type;
+struct input {
+  using type = default_input<T>;
 };
 
-struct wrap_type_shared_ptr_tag {};
-struct wrap_type_unique_ptr_tag {};
-
 template <typename T>
-struct wrap_type_traits<std::shared_ptr<T>> {
-  using wrap_category = wrap_type_shared_ptr_tag;
+struct input<const T&> {
+  using type = const_reference_input<typename std::decay<T>::type>;
 };
 
 template <typename T>
-struct wrap_type_traits<std::unique_ptr<T>> {
-  using wrap_category = wrap_type_unique_ptr_tag;
+struct input<const std::shared_ptr<T>&> {
+  using type = ConstRefSmartPtrInput<T, std::shared_ptr>;
 };
 
-}  // namespace traits
-
-namespace internal {
+template <typename T>
+using default_unique_ptr = std::unique_ptr<T, std::default_delete<T>>;
 
 template <typename T>
-inline SEXP wrap_dispatch(const T& x, Rcpp::traits::wrap_type_shared_ptr_tag);
+struct input<const std::unique_ptr<T>&> {
+  using type = ConstRefSmartPtrInput<T, default_unique_ptr>;
+};
 
 template <typename T>
-inline SEXP wrap_dispatch(const T& x, Rcpp::traits::wrap_type_unique_ptr_tag);
+struct input<const std::vector<std::shared_ptr<T>>&> {
+  using type = ConstRefVectorSmartPtrInput<T, std::shared_ptr>;
+};
 
-}  // namespace internal
-}  // namespace Rcpp
+}  // namespace r
+}  // namespace arrow
 
-#include <Rcpp.h>
+namespace cpp11 {
 
-namespace Rcpp {
-namespace internal {
+template <typename T>
+using is_shared_ptr = typename std::enable_if<
+    std::is_same<std::shared_ptr<typename T::element_type>, T>::value, T>::type;
 
 template <typename T>
-inline SEXP wrap_dispatch(const T& x, Rcpp::traits::wrap_type_shared_ptr_tag) {
-  return Rcpp::XPtr<std::shared_ptr<typename T::element_type>>(
-      new std::shared_ptr<typename T::element_type>(x));
+is_shared_ptr<T> as_cpp(SEXP from) {

Review comment:
       Sure, that would be great. The issue for this is https://github.com/r-lib/cpp11/issues/66.
   
   Sorry for the late reply, I didn't see this particular mention until just now.




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org