Skip to content

Commit 119bc75

Browse files
drop the .copy_constructor declaration. The availability of a copy
constructor is now automatic with the `has_copy_constructor` trait.
1 parent 2319554 commit 119bc75

File tree

7 files changed

+70
-25
lines changed

7 files changed

+70
-25
lines changed

inst/NEWS.Rd

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,7 @@
1717
\item Changes in Rcpp Modules:
1818
\itemize{
1919
\item New function \code{copy} to invoke the copy constructor of a
20-
C++ class that has been exposed by modules. \code{copy} only
21-
works if the copy constructor has been declared by the
22-
\code{copy\_constructor} module declaration.
20+
C++ class that has been exposed by modules.
2321
}
2422
}
2523
}

inst/include/Rcpp/module/class.h

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,21 @@
2222
#ifndef Rcpp_Module_CLASS_h
2323
#define Rcpp_Module_CLASS_h
2424

25+
template <typename Class, bool ok>
26+
struct CopyConstructor {
27+
static Class* get( Class* obj ){
28+
return new Class(*obj) ;
29+
}
30+
} ;
31+
32+
template <typename Class>
33+
struct CopyConstructor<Class,false> {
34+
static Class* get( Class* obj){
35+
stop("no copy constructor available") ;
36+
return obj ;
37+
}
38+
} ;
39+
2540
template <typename Class>
2641
class class_ : public class_Base {
2742
public:
@@ -60,8 +75,7 @@
6075
constructors(),
6176
factories(),
6277
class_pointer(0),
63-
typeinfo_name(""),
64-
has_copy_constructor(false)
78+
typeinfo_name("")
6579
{
6680
class_pointer = get_instance() ;
6781
}
@@ -112,11 +126,6 @@
112126
return constructor( docstring, valid ) ;
113127
}
114128

115-
self& copy_constructor(){
116-
class_pointer->has_copy_constructor = true ;
117-
return *this ;
118-
}
119-
120129
#include <Rcpp/module/Module_generated_class_constructor.h>
121130
#include <Rcpp/module/Module_generated_class_factory.h>
122131

@@ -156,12 +165,8 @@
156165

157166
SEXP invoke_copy_constructor( SEXP object ){
158167
BEGIN_RCPP
159-
160-
if( !has_copy_constructor )
161-
stop("copy constructor not exposed") ;
162-
163168
XP xp(object) ;
164-
return internal::make_new_object<Class>( new Class(*xp) ) ;
169+
return internal::make_new_object<Class>( CopyConstructor< Class, traits::has_copy_constructor<Class>::value >::get(xp) ) ;
165170
END_RCPP
166171
}
167172

@@ -493,8 +498,7 @@
493498
vec_signed_factory factories ;
494499
self* class_pointer ;
495500
std::string typeinfo_name ;
496-
bool has_copy_constructor ;
497-
501+
498502
class_( ) : class_Base(), vec_methods(), properties(), specials(0), constructors(), factories() {};
499503

500504

inst/include/Rcpp/module/class_Base.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ class class_Base {
3737

3838
virtual void run_finalizer(SEXP){ }
3939

40-
virtual SEXP invoke_copy_constructor(SEXP) = 0 ;
4140
virtual bool has_default_constructor(){ return false ; }
4241
virtual bool has_method( const std::string& ){
4342
return false ;
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8 -*-
2+
//
3+
// Copyright (C) 2016 Romain Francois
4+
//
5+
// This file is part of Rcpp.
6+
//
7+
// Rcpp is free software: you can redistribute it and/or modify it
8+
// under the terms of the GNU General Public License as published by
9+
// the Free Software Foundation, either version 2 of the License, or
10+
// (at your option) any later version.
11+
//
12+
// Rcpp is distributed in the hope that it will be useful, but
13+
// WITHOUT ANY WARRANTY; without even the implied warranty of
14+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
// GNU General Public License for more details.
16+
//
17+
// You should have received a copy of the GNU General Public License
18+
// along with Rcpp. If not, see <http://www.gnu.org/licenses/>.
19+
20+
#ifndef Rcpp__traits__has_copy_constructor__h
21+
#define Rcpp__traits__has_copy_constructor__h
22+
23+
namespace Rcpp{
24+
namespace traits{
25+
26+
template<typename T>
27+
class _has_copy_constructor_helper : __sfinae_types {
28+
template<typename U> struct _Wrap_type { };
29+
30+
template<typename U>
31+
static __one __test(U);
32+
33+
template<typename U>
34+
static __two __test(...);
35+
36+
public:
37+
static const bool value = sizeof(__test<T>(0)) == 1;
38+
};
39+
40+
template<typename T> struct has_copy_constructor :
41+
integral_constant<bool,_has_copy_constructor_helper<T>::value> { };
42+
43+
} // traits
44+
} // Rcpp
45+
46+
#endif

inst/include/Rcpp/traits/traits.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
//
44
// traits.h: Rcpp R/C++ interface class library -- traits to help wrap
55
//
6-
// Copyright (C) 2012 - 2013 Dirk Eddelbuettel and Romain Francois
6+
// Copyright (C) 2012 - 2016 Dirk Eddelbuettel and Romain Francois
77
//
88
// This file is part of Rcpp.
99
//
@@ -44,6 +44,7 @@ struct int2type { enum { value = I }; };
4444
#include <Rcpp/traits/named_object.h>
4545
#include <Rcpp/traits/is_convertible.h>
4646
#include <Rcpp/traits/has_iterator.h>
47+
#include <Rcpp/traits/has_copy_constructor.h>
4748
#include <Rcpp/traits/expands_to_logical.h>
4849
#include <Rcpp/traits/matrix_interface.h>
4950
#include <Rcpp/traits/is_sugar_expression.h>
@@ -77,4 +78,3 @@ struct int2type { enum { value = I }; };
7778
#include <Rcpp/traits/is_primitive.h>
7879

7980
#endif
80-

inst/unitTests/cpp/Module.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,6 @@ RCPP_MODULE(demoModule) {
204204

205205
class_<ModuleCopyConstructor>( "ModuleCopyConstructor")
206206
.constructor<int>()
207-
.copy_constructor()
208207
.field( "x", &ModuleCopyConstructor::x)
209208
;
210209
}

man/copy.Rd

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
Invokes the copy constructor of the C++ class
55
}
66
\description{
7-
Invokes the copy constructor of the C++ class if it has
8-
been registered through the \code{.copy_constructor}
9-
module declaration
7+
Invokes the copy constructor of the C++ class. The function
8+
fails if the underlying class does not have a copy
9+
constructor.
1010
}
1111
\usage{
1212
copy(obj)
@@ -37,7 +37,6 @@
3737
RCPP_MODULE(test){
3838
class_<Foo>("Foo")
3939
.constructor<int>()
40-
.copy_constructor()
4140
.field( "x", &Foo::x)
4241
;
4342
}

0 commit comments

Comments
 (0)