Skip to content

Commit 9f961e7

Browse files
committed
directly exclude InputParameter types to avoid self-referencing DataFrame_Impl, which doesn't play well with older gcc, probably clang either
1 parent ce61982 commit 9f961e7

3 files changed

Lines changed: 25 additions & 12 deletions

File tree

‎inst/include/Rcpp/DataFrame.h‎

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,12 @@ namespace Rcpp{
4747
set__(other) ;
4848
}
4949

50-
// enabled only when T doesn't already provide its own conversion
51-
// so this doesn't compete with that conversion, while still accepting
52-
// anything wrap()-able, including third-party types (e.g. arma::mat)
53-
template <typename T,
54-
typename std::enable_if<
55-
!std::is_convertible<T, DataFrame_Impl<StoragePolicy>>::value,
56-
int>::type = 0>
50+
// enabled for everything except the InputParameter family (which
51+
// each offer their own operator T() conversion), so this doesn't
52+
// compete with that conversion, while still accepting anything
53+
// wrap()-able, including third-party types (e.g. arma::mat)
54+
template <typename T, typename std::enable_if<
55+
!traits::is_input_parameter<T>::value, int>::type = 0>
5756
DataFrame_Impl( const T& obj ) ;
5857

5958
DataFrame_Impl& operator=( DataFrame_Impl& other){

‎inst/include/Rcpp/InputParameter.h‎

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
//
33
// InputParameter.h: Rcpp R/C++ interface class library --
44
//
5-
// Copyright (C) 2013 Dirk Eddelbuettel and Romain Francois
5+
// Copyright (C) 2013 - 2025 Dirk Eddelbuettel and Romain Francois
6+
// Copyright (C) 2026 Dirk Eddelbuettel, Romain Francois and Iñaki Ucar
67
//
78
// This file is part of Rcpp.
89
//
@@ -94,6 +95,21 @@ namespace Rcpp {
9495
struct input_parameter<const T&> {
9596
typedef typename Rcpp::ConstReferenceInputParameter<T> type ;
9697
} ;
98+
99+
// detects the InputParameter family, which each offer their own
100+
// operator T() converting to whatever type they wrap. Generic
101+
// wrap()-based converting constructors (e.g. DataFrame_Impl) use this
102+
// to exclude these types, so that they don't compete with them
103+
template <typename T>
104+
struct is_input_parameter : false_type {};
105+
template <typename T>
106+
struct is_input_parameter<InputParameter<T>> : true_type {};
107+
template <typename T>
108+
struct is_input_parameter<ReferenceInputParameter<T>> : true_type {};
109+
template <typename T>
110+
struct is_input_parameter<ConstInputParameter<T>> : true_type {};
111+
template <typename T>
112+
struct is_input_parameter<ConstReferenceInputParameter<T>> : true_type {};
97113
}
98114

99115
}

‎inst/include/Rcpp/api/meat/DataFrame.h‎

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,8 @@
2222
namespace Rcpp{
2323

2424
template <template <class> class StoragePolicy>
25-
template <class T,
26-
typename std::enable_if<
27-
!std::is_convertible<T, DataFrame_Impl<StoragePolicy> >::value,
28-
int>::type>
25+
template <class T, typename std::enable_if<
26+
!traits::is_input_parameter<T>::value, int>::type>
2927
DataFrame_Impl<StoragePolicy>::DataFrame_Impl( const T& obj){
3028
set__(Shield<SEXP>(wrap(obj)));
3129
}

0 commit comments

Comments
 (0)