[Rcpp-commits] r4558 - in pkg/Rcpp: . R man
noreply at r-forge.r-project.org
noreply at r-forge.r-project.org
Sun Oct 6 23:54:18 CEST 2013
Author: jmc
Date: 2013-10-06 23:54:18 +0200 (Sun, 06 Oct 2013)
New Revision: 4558
Added:
pkg/Rcpp/R/exposeClass.R
pkg/Rcpp/man/exposeClass.Rd
Removed:
pkg/Rcpp/R/classModule.R
pkg/Rcpp/man/classModule.Rd
Modified:
pkg/Rcpp/ChangeLog
pkg/Rcpp/NAMESPACE
pkg/Rcpp/man/setRcppClass.Rd
Log:
Rename classModule to exposeClass; recommend it from setRcppClass.Rd
Modified: pkg/Rcpp/ChangeLog
===================================================================
--- pkg/Rcpp/ChangeLog 2013-10-04 02:28:55 UTC (rev 4557)
+++ pkg/Rcpp/ChangeLog 2013-10-06 21:54:18 UTC (rev 4558)
@@ -1,3 +1,12 @@
+2013-10-06 John M Chambers <jmc at r-project.org>
+
+ * NAMESPACE: change classModule to expose Class
+ * R/classModule.R: delete
+ * man/classModule.Rd: delete
+ * R/exposeClass.R: add
+ * man/exposeClass.Rd: add
+ * man/setRcppClass.Rd: update, clarify, recommend exposeClass()
+
2013-10-03 John M Chambers <jmc at r-project.org>
* R/classModule.R: new function to write module file for class
Modified: pkg/Rcpp/NAMESPACE
===================================================================
--- pkg/Rcpp/NAMESPACE 2013-10-04 02:28:55 UTC (rev 4557)
+++ pkg/Rcpp/NAMESPACE 2013-10-06 21:54:18 UTC (rev 4558)
@@ -20,8 +20,8 @@
setRcppClass,
loadRcppClass,
loadModule,
- classModule,
cppFunction,
+ exposeClass,
evalCpp,
sourceCpp,
compileAttributes,
Deleted: pkg/Rcpp/R/classModule.R
===================================================================
--- pkg/Rcpp/R/classModule.R 2013-10-04 02:28:55 UTC (rev 4557)
+++ pkg/Rcpp/R/classModule.R 2013-10-06 21:54:18 UTC (rev 4558)
@@ -1,197 +0,0 @@
-.stdHeader <- c(
- "#include <Rcpp.h>",
- "using namespace Rcpp ;"
- )
-
-.asString <- function(what) if(is.character(what)) what else deparse(what)
-
-.strings <- function(expr) {
- if(is.call(expr) && ! identical(expr[[1]], quote(`::`)))
- lapply(as.list(expr)[-1], .strings)
- else
- .asString(expr)
-}
-
-.specifyItems <- function(what) {
- what <- as.list(what)
- wn <- allNames(what)
- simple <- !nzchar(wn)
- ## todo: error checking here that unnamed elements are single strings
- wn[simple] <- as.character(what[simple])
- names(what) <- wn
- what[simple] <- list(character())
- what
-}
-
-.writeFieldFunction <- function(fldi, typei, CppClass, readOnly, ns, con){
- rootName <- paste0("field_", fldi)
- writeLines(sprintf(" %s %s_get(%s *obj) { return obj->%s; }\n",
- typei, rootName, CppClass, fldi), con)
- value <- "_get"
- if(!readOnly) {
- writeLines(sprintf(" void %s_set(%s *obj, %s value) { obj->%s = value; }\n",
- rootName, CppClass, typei, fldi), con)
- value <- c(value, "_set")
- }
- paste0(ns, "::field_", fldi, value)
-}
-
-.writeMethodFunction <- function(mdi, sigi, CppClass, ns, con) {
- mName <- paste0("method_", mdi)
- if(length(sigi) < 1)
- stop(gettextf("The type signature for method %s for class %s was of length 0: Must at least include the return type",
- mdi, CppClass))
- rtnType <- sigi[[1]]
- sigi <- sigi[-1]
- if(length(sigi)) {
- argNames <- paste0("a", seq_along(sigi))
- args <- paste(" ,", paste(sigi, argNames, collapse = ", "))
- }
- else argNames <- args <- ""
- writeLines(sprintf(" %s %s(%s *obj%s){ return obj->%s(%s); }\n",
- rtnType, mName, CppClass, args, mdi, argNames), con)
- paste0(ns, "::",mName)
-}
-
-classModule <- function(class, constructors, fields, methods,
- file = paste0(CppClass, "Module.cpp"),
- header = character(),
- module = paste0("class_",class), CppClass = class,
- readOnly = character(), rename = character(),
- Rfile = TRUE) {
- ## some argument checks
- ## TODO: checks on constructors, fields, methods
- if(length(readOnly)) {
- readOnly <- as.character(readOnly)
- if(!all(nzchar(readOnly)))
- stop("argument readOnly should be a vector of non-empty strings")
- }
- newnames <- allNames(rename)
- if(length(rename)) {
- if(!all(sapply(rename, function(x) is.character(x) && length(x) == 1 && nzchar(x))))
- stop("argument rename should be a vector of single, non-empty strings")
- if(!all(nzchar(newnames)))
- stop("all the elements of argument rename should be non-empty strings")
- }
- if(is.character(file)) {
- ## are we in a package directory? Writable, searchable src subdirectory:
- if(file.access("src",3)==0)
- cfile <- file.path("src", file)
- else
- cfile <- file
- con <- file(cfile, "w")
- on.exit({message(sprintf("Wrote C++ file \"%s\"", cfile)); close(con)})
- }
- else
- con <- file
- ## and for the R code:
- if(identical(Rfile, FALSE)) {}
- else {
- if(identical(Rfile, TRUE))
- Rfile <- sprintf("%sClass.R",class)
- if(is.character(Rfile)) {
- if(file.access("R",3)==0) # in a package directory
- Rfile <- file.path("R", Rfile)
- Rcon <- file(Rfile, "w")
- msg <- sprintf("Wrote R file \"%s\"",Rfile)
- on.exit({message(msg); close(Rcon)}, add = TRUE)
- }
- else
- Rcon <- Rfile
- Rfile <- TRUE
- }
- temp <- tempfile()
- mcon <- file(temp, "w")
- writeLines(.stdHeader, con)
- if(length(header))
- writeLines(header, con)
- writeLines(c("", sprintf("RCPP_MODULE(%s) {\n",module), ""), mcon)
- writeLines(sprintf(" class_<%s>(\"%s\")\n", CppClass, class), mcon)
-
- ## the constructors argument defines a list of vectors of types
- for( cons in constructors) {
- if(length(cons) > 1 ||
- (length(cons) == 1 && nzchar(cons) && !identical(cons, "void")))
- cons <- paste0("<", paste(cons, collapse = ","),">")
- else
- cons = ""
- writeLines(paste0(" .constructor",cons,"()"),mcon)
- }
- writeLines("", mcon)
- flds <- .specifyItems(fields)
- nm <- names(flds)
- rdOnly <- nm %in% readOnly
- macros <- ifelse(rdOnly, ".field_readonly", ".field")
- test <- nm %in% rename
- if(any(test))
- nm[test] <- newnames[match(nm[test], newnames)]
- ns <- NULL
- for(i in seq_along(nm)) {
- typei <- flds[[i]]
- nmi <- fldi <- nm[[i]]
- macroi <- macros[[i]]
- if(!length(typei) || identical(typei, "")) ## direct field
- writeLines(sprintf(" %s(\"%s\", &%s::%s)",
- macroi, nmi, CppClass, fldi), mcon)
- else { # create a free function, e.g. for an inherited field
- if(is.null(ns)) { # enclose in a namespace
- ns <- paste("module",class,"NS", sep = "_")
- writeLines(sprintf("\nnamespace %s {\n", ns),
- con)
- }
- fldFuns <- .writeFieldFunction(fldi, typei, CppClass, rdOnly[[i]], ns, con)
- if(rdOnly[[i]])
- ## NOTE: string 3rd arg. required by problem w. module parsing 10/3/13
- writeLines(sprintf(" .property(\"%s\", &%s, \"read-only field\")",
- nmi, fldFuns[[1]]), mcon)
- else
- writeLines(sprintf(" .property(\"%s\", &%s, &%s)",
- nmi, fldFuns[[1]], fldFuns[[2]]), mcon)
- }
- }
- writeLines("", mcon)
- sigs <- .specifyItems(methods)
- nm <- mds <- names(sigs)
- test <- nm %in% rename
- if(any(test))
- nm[test] <- newnames[match(nm[test], newnames)]
- for(i in seq_along(nm)) {
- sigi <- sigs[[i]]
- nmi <- nm[[i]]
- mdi <- mds[[i]]
- if(!length(sigi) || identical(sigi, "")) # direct method
- writeLines(sprintf(" .method(\"%s\", &%s::%s)",
- nmi, CppClass, mdi), mcon)
- else { # create a free function, e.g. for an inherited method
- if(is.null(ns)) { # enclose in a namespace
- ns <- paste("module",class,"NS", sep = "_")
- writeLines(sprintf("\nnamespace %s {\n", ns),
- con)
- }
- mFun <- .writeMethodFunction(mdi, sigi, CppClass, ns, con)
- writeLines(sprintf(" .method(\"%s\", &%s)",
- nmi, mFun), mcon)
- }
- }
-
- writeLines(" ;\n}", mcon)
- close(mcon)
- if(!is.null(ns))
- writeLines(sprintf("} // %s", ns), con) # close namespace
- writeLines(readLines(file(temp, "r")), con)
- if(Rfile) {
- if(missing(CppClass))
- CppString <- ""
- else
- CppString <- paste(",",dQuote(CppClass))
- if(missing(module))
- ModString <- ""
- else
- ModString <- paste(", module =", dQuote(module))
- writeLines(sprintf("%s <- setRcppClass(\"%s\"%s%s)",
- class, class, CppString,ModString), Rcon)
- }
-}
-
-
-
Added: pkg/Rcpp/R/exposeClass.R
===================================================================
--- pkg/Rcpp/R/exposeClass.R (rev 0)
+++ pkg/Rcpp/R/exposeClass.R 2013-10-06 21:54:18 UTC (rev 4558)
@@ -0,0 +1,197 @@
+.stdHeader <- c(
+ "#include <Rcpp.h>",
+ "using namespace Rcpp ;"
+ )
+
+.asString <- function(what) if(is.character(what)) what else deparse(what)
+
+.strings <- function(expr) {
+ if(is.call(expr) && ! identical(expr[[1]], quote(`::`)))
+ lapply(as.list(expr)[-1], .strings)
+ else
+ .asString(expr)
+}
+
+.specifyItems <- function(what) {
+ what <- as.list(what)
+ wn <- allNames(what)
+ simple <- !nzchar(wn)
+ ## todo: error checking here that unnamed elements are single strings
+ wn[simple] <- as.character(what[simple])
+ names(what) <- wn
+ what[simple] <- list(character())
+ what
+}
+
+.writeFieldFunction <- function(fldi, typei, CppClass, readOnly, ns, con){
+ rootName <- paste0("field_", fldi)
+ writeLines(sprintf(" %s %s_get(%s *obj) { return obj->%s; }\n",
+ typei, rootName, CppClass, fldi), con)
+ value <- "_get"
+ if(!readOnly) {
+ writeLines(sprintf(" void %s_set(%s *obj, %s value) { obj->%s = value; }\n",
+ rootName, CppClass, typei, fldi), con)
+ value <- c(value, "_set")
+ }
+ paste0(ns, "::field_", fldi, value)
+}
+
+.writeMethodFunction <- function(mdi, sigi, CppClass, ns, con) {
+ mName <- paste0("method_", mdi)
+ if(length(sigi) < 1)
+ stop(gettextf("The type signature for method %s for class %s was of length 0: Must at least include the return type",
+ mdi, CppClass))
+ rtnType <- sigi[[1]]
+ sigi <- sigi[-1]
+ if(length(sigi)) {
+ argNames <- paste0("a", seq_along(sigi))
+ args <- paste(" ,", paste(sigi, argNames, collapse = ", "))
+ }
+ else argNames <- args <- ""
+ writeLines(sprintf(" %s %s(%s *obj%s){ return obj->%s(%s); }\n",
+ rtnType, mName, CppClass, args, mdi, argNames), con)
+ paste0(ns, "::",mName)
+}
+
+exposeClass <- function(class, constructors, fields, methods,
+ file = paste0(CppClass, "Module.cpp"),
+ header = character(),
+ module = paste0("class_",class), CppClass = class,
+ readOnly = character(), rename = character(),
+ Rfile = TRUE) {
+ ## some argument checks
+ ## TODO: checks on constructors, fields, methods
+ if(length(readOnly)) {
+ readOnly <- as.character(readOnly)
+ if(!all(nzchar(readOnly)))
+ stop("argument readOnly should be a vector of non-empty strings")
+ }
+ newnames <- allNames(rename)
+ if(length(rename)) {
+ if(!all(sapply(rename, function(x) is.character(x) && length(x) == 1 && nzchar(x))))
+ stop("argument rename should be a vector of single, non-empty strings")
+ if(!all(nzchar(newnames)))
+ stop("all the elements of argument rename should be non-empty strings")
+ }
+ if(is.character(file)) {
+ ## are we in a package directory? Writable, searchable src subdirectory:
+ if(file.access("src",3)==0)
+ cfile <- file.path("src", file)
+ else
+ cfile <- file
+ con <- file(cfile, "w")
+ on.exit({message(sprintf("Wrote C++ file \"%s\"", cfile)); close(con)})
+ }
+ else
+ con <- file
+ ## and for the R code:
+ if(identical(Rfile, FALSE)) {}
+ else {
+ if(identical(Rfile, TRUE))
+ Rfile <- sprintf("%sClass.R",class)
+ if(is.character(Rfile)) {
+ if(file.access("R",3)==0) # in a package directory
+ Rfile <- file.path("R", Rfile)
+ Rcon <- file(Rfile, "w")
+ msg <- sprintf("Wrote R file \"%s\"",Rfile)
+ on.exit({message(msg); close(Rcon)}, add = TRUE)
+ }
+ else
+ Rcon <- Rfile
+ Rfile <- TRUE
+ }
+ temp <- tempfile()
+ mcon <- file(temp, "w")
+ writeLines(.stdHeader, con)
+ if(length(header))
+ writeLines(header, con)
+ writeLines(c("", sprintf("RCPP_MODULE(%s) {\n",module), ""), mcon)
+ writeLines(sprintf(" class_<%s>(\"%s\")\n", CppClass, class), mcon)
+
+ ## the constructors argument defines a list of vectors of types
+ for( cons in constructors) {
+ if(length(cons) > 1 ||
+ (length(cons) == 1 && nzchar(cons) && !identical(cons, "void")))
+ cons <- paste0("<", paste(cons, collapse = ","),">")
+ else
+ cons = ""
+ writeLines(paste0(" .constructor",cons,"()"),mcon)
+ }
+ writeLines("", mcon)
+ flds <- .specifyItems(fields)
+ nm <- names(flds)
+ rdOnly <- nm %in% readOnly
+ macros <- ifelse(rdOnly, ".field_readonly", ".field")
+ test <- nm %in% rename
+ if(any(test))
+ nm[test] <- newnames[match(nm[test], newnames)]
+ ns <- NULL
+ for(i in seq_along(nm)) {
+ typei <- flds[[i]]
+ nmi <- fldi <- nm[[i]]
+ macroi <- macros[[i]]
+ if(!length(typei) || identical(typei, "")) ## direct field
+ writeLines(sprintf(" %s(\"%s\", &%s::%s)",
+ macroi, nmi, CppClass, fldi), mcon)
+ else { # create a free function, e.g. for an inherited field
+ if(is.null(ns)) { # enclose in a namespace
+ ns <- paste("module",class,"NS", sep = "_")
+ writeLines(sprintf("\nnamespace %s {\n", ns),
+ con)
+ }
+ fldFuns <- .writeFieldFunction(fldi, typei, CppClass, rdOnly[[i]], ns, con)
+ if(rdOnly[[i]])
+ ## NOTE: string 3rd arg. required by problem w. module parsing 10/3/13
+ writeLines(sprintf(" .property(\"%s\", &%s, \"read-only field\")",
+ nmi, fldFuns[[1]]), mcon)
+ else
+ writeLines(sprintf(" .property(\"%s\", &%s, &%s)",
+ nmi, fldFuns[[1]], fldFuns[[2]]), mcon)
+ }
+ }
+ writeLines("", mcon)
+ sigs <- .specifyItems(methods)
+ nm <- mds <- names(sigs)
+ test <- nm %in% rename
+ if(any(test))
+ nm[test] <- newnames[match(nm[test], newnames)]
+ for(i in seq_along(nm)) {
+ sigi <- sigs[[i]]
+ nmi <- nm[[i]]
+ mdi <- mds[[i]]
+ if(!length(sigi) || identical(sigi, "")) # direct method
+ writeLines(sprintf(" .method(\"%s\", &%s::%s)",
+ nmi, CppClass, mdi), mcon)
+ else { # create a free function, e.g. for an inherited method
+ if(is.null(ns)) { # enclose in a namespace
+ ns <- paste("module",class,"NS", sep = "_")
+ writeLines(sprintf("\nnamespace %s {\n", ns),
+ con)
+ }
+ mFun <- .writeMethodFunction(mdi, sigi, CppClass, ns, con)
+ writeLines(sprintf(" .method(\"%s\", &%s)",
+ nmi, mFun), mcon)
+ }
+ }
+
+ writeLines(" ;\n}", mcon)
+ close(mcon)
+ if(!is.null(ns))
+ writeLines(sprintf("} // %s", ns), con) # close namespace
+ writeLines(readLines(file(temp, "r")), con)
+ if(Rfile) {
+ if(missing(CppClass))
+ CppString <- ""
+ else
+ CppString <- paste(",",dQuote(CppClass))
+ if(missing(module))
+ ModString <- ""
+ else
+ ModString <- paste(", module =", dQuote(module))
+ writeLines(sprintf("%s <- setRcppClass(\"%s\"%s%s)",
+ class, class, CppString,ModString), Rcon)
+ }
+}
+
+
+
Deleted: pkg/Rcpp/man/classModule.Rd
===================================================================
--- pkg/Rcpp/man/classModule.Rd 2013-10-04 02:28:55 UTC (rev 4557)
+++ pkg/Rcpp/man/classModule.Rd 2013-10-06 21:54:18 UTC (rev 4558)
@@ -1,205 +0,0 @@
-\name{classModule}
-\alias{classModule}
-\title{
-Create an Rcpp Module to Expose a C++ Class in R
-}
-\description{
-The arguments specify a C++ class and some combination of
-constructors, fields and methods to be shared with \R by creating a
-corresponding reference class in \R.
-The information needed in the call to \code{classModule()} is the
-simplest possible in order to create a C++ module for the class; for
-example, fields and methods in this class need only be identified by
-their name.
-Inherited fields and methods can also be included, but more
-information is needed.
-The function writes a C++ source file,
-containing a module definition to expose the class to
-\R, plus one line of \R source to create the corresponding reference
-class.
-}
-
-\usage{
-classModule(class, constructors = , fields = , methods = , file = ,
- header = , module = , CppClass = class, readOnly = , rename = ,
- Rfile = TRUE)
-}
-
-\arguments{
- \item{class}{
-The name of the class in \R. By default, this will be the same as the
-name of the class in C++, unless argument \code{CppClass} is supplied.
-}
- \item{constructors}{
-A list of the signatures for any of the class constructors to be
-called from \R. Each element of the list gives the data types in C++
-for the arguments to the corresponding constructor. See Details and
-the example.
-}
- \item{fields, methods}{
-The vector of names for the fields and for the methods to be exposed
-in \R. For inherited fields and methods, type information needs to be
-supplied; see the section \dQuote{Inherited Fields and Methods}.
-}
- \item{file}{
-Usually, the name for the file on which to write the C++ code, by default
-\code{paste0(CppClass, "Module.cpp")}.
-If the current working directory in \R is the top-level
-directory for a package, the function writes the file in the
-\code{"src"} subdirectory.
-Otherwise the file is written in the working directory.
-
-The argument may also be a connection, already open for writing.
-
-}
- \item{header}{
-Whatever lines of C++ header information are needed to include the
-definition of the class. Typically this includes a file from the
-package where we are writing the module definition, as in the example below.
-}
- \item{module}{
-The name for the Rcpp module, by default
-\code{paste0("class_",CppClass)}.
-}
- \item{CppClass}{
-The name for the class in C++. By default and usually, the intended
-class name in \R.
-}
- \item{readOnly}{
-Optional vector of field names. These fields will be created as
-read-only in the interface.
-}
- \item{rename}{
-Optional named character vector, used to name fields or methods
-differently in \R from their C++ name. The elements of the vector are
-the C++ names and the corresponding elements of \code{names(rename)}
-the desired names in \R. So \code{c(.age = "age")} renames the C++
-field or method \code{age} as \code{.age}.
-}
- \item{Rfile}{
-Controls the writing of a one-line \R command to create the reference
-class corresponding to the C++ module information. By default, this
-will be a file \code{paste0(class, "Class.R")}.
-If the working directory is an \R package source
-directory, the file will be written in the \code{R} subdirectory, otherwise in the working directory itself.
-
-Supplying a character string substitutes that file name for the
-default.
-
-The argument may also be a connection open for
-writing or \code{FALSE} to suppress writing the \R source altogether.
-}
-}
-
-\details{
-The file created by the call to these functions only depends on the
-information in the C++ class supplied. This file is intended to be
-part of the C++ source for an \R package. The file only needs to
-modified when the information changes, either because the class has
-changed or because you want to expose different information to \R. In
-that case you can either recall \code{classModule()} or edit the C++
-file created.
-
-The Rcpp Module mechanism has a number of other optional techniques,
-not covered by \code{classModule()}. These should be entered into the
-C++ file created. See the \dQuote{rcpp-modules} vignette with the
-package for current possibilities.
-
-For fields and methods specified directly in the C++ class,
-the fields and method arguments to \code{classModule()} are character vectors naming the
-corresponding members of the class. For module construction, the
-data types of directly specified fields and of the arguments for the methods are not
-needed.
-
-For \emph{inherited} fields or methods, data type information is
-needed. See the section \dQuote{Inherited Fields and Methods}.
-
-For exposing class constructors, the module needs to know the
-signatures of the constructors to be exposed; each signature is a
-character vector of the corresponding C++ data types.
-
-}
-
-\section{Inherited Fields and Methods}{
-If the C++ class inherits from one or more other classes, the standard
-Rcpp \code{Module} mechanism can not be used to expose inherited
-fields or methods.
-An indirect mechanism is used, generating free functions in C++ to
-expose the inherited members in \R.
-
-This mechanism requires data type information in the call to
-\code{classModule()}.
-This is provided by naming the corresponding element of the
-\code{fields} or \code{methods} argument with the name of the member.
-The actual element of the \code{fields} argument is then the single
-data type of the field.
-
-For the \code{methods} argument the argument will generally need to be
-a named list.
-The corresponding element of the list is the vector of data types for
-the return value and for the arguments, if any, to the method.
-For example, if C++ method \code{foo()} took a single argument of type
-\code{NumericVector} and returned a value of type \code{long}, the
-\code{methods} argument would be \code{list(foo = c("long",
- "NumericVector"))}.
-
-See the second example below.
-}
-\value{
-Nothing, called for its side effect.
-}
-\author{
- John Chambers
-}
-\seealso{
-\code{\link{setRcppClass}}, which must be called from some \R source
-in the package.
-}
-\examples{
-\dontrun{
-### Given the following C++ class, defined in file PopBD.h,
-### the call to classModule() shown below will write a file
-### src/PopBDModule.cpp containing a corresponding module definition.
-### class PopBD {
-### public:
-### PopBD(void);
-### PopBD(NumericVector initBirth, NumericVector initDeath);
-###
-### std::vector<double> birth;
-### std::vector<double> death;
-### std::vector<int> lineage;
-### std::vector<long> size;
-### void evolve(int);
-###
-### };
-### A file R/PopBDClass.R will be written containing the one line:
-### PopBD <- setRcppClass("PopBD")
-###
-### The call below exposes the lineage and size fields, read-only,
-### and the evolve() method.
-
-classModule("PopBD",
- constructors =
- list("", c("NumericVector", "NumericVector")),
- fields = c("lineage", "size"),
- methods = "evolve",
- header = '#include "PopBD.h"',
- readOnly = c("lineage", "size"))
-
-### Example with inheritance: the class PopCount inherits from
-### the previous class, and adds a method table(). It has the same
-### constructors as the previous class.
-### To expose the table() method, and the inherited evolve() method and size field:
-
-classModule("PopCount",
- constructors =
- list("", c("NumericVector", "NumericVector")),
- fields = c(size = "std::vector<long>"),
- methods = list("table", evolve = c("void", "int")),
- header = '#include "PopCount.h"',
- readOnly = "size")
-}
-}
-
-\keyword{ programming }
-\keyword{ classes }
Added: pkg/Rcpp/man/exposeClass.Rd
===================================================================
--- pkg/Rcpp/man/exposeClass.Rd (rev 0)
+++ pkg/Rcpp/man/exposeClass.Rd 2013-10-06 21:54:18 UTC (rev 4558)
@@ -0,0 +1,205 @@
+\name{exposeClass}
+\alias{exposeClass}
+\title{
+Create an Rcpp Module to Expose a C++ Class in R
+}
+\description{
+The arguments specify a C++ class and some combination of
+constructors, fields and methods to be shared with \R by creating a
+corresponding reference class in \R.
+The information needed in the call to \code{exposeClass()} is the
+simplest possible in order to create a C++ module for the class; for
+example, fields and methods in this class need only be identified by
+their name.
+Inherited fields and methods can also be included, but more
+information is needed.
+The function writes a C++ source file,
+containing a module definition to expose the class to
+\R, plus one line of \R source to create the corresponding reference
+class.
+}
+
+\usage{
+exposeClass(class, constructors = , fields = , methods = , file = ,
+ header = , module = , CppClass = class, readOnly = , rename = ,
+ Rfile = TRUE)
+}
+
+\arguments{
+ \item{class}{
+The name of the class in \R. By default, this will be the same as the
+name of the class in C++, unless argument \code{CppClass} is supplied.
+}
+ \item{constructors}{
+A list of the signatures for any of the class constructors to be
+called from \R. Each element of the list gives the data types in C++
+for the arguments to the corresponding constructor. See Details and
+the example.
+}
+ \item{fields, methods}{
+The vector of names for the fields and for the methods to be exposed
+in \R. For inherited fields and methods, type information needs to be
+supplied; see the section \dQuote{Inherited Fields and Methods}.
+}
+ \item{file}{
+Usually, the name for the file on which to write the C++ code, by default
+\code{paste0(CppClass, "Module.cpp")}.
+If the current working directory in \R is the top-level
+directory for a package, the function writes the file in the
+\code{"src"} subdirectory.
+Otherwise the file is written in the working directory.
+
+The argument may also be a connection, already open for writing.
+
+}
+ \item{header}{
+Whatever lines of C++ header information are needed to include the
+definition of the class. Typically this includes a file from the
+package where we are writing the module definition, as in the example below.
+}
+ \item{module}{
+The name for the Rcpp module, by default
+\code{paste0("class_",CppClass)}.
+}
+ \item{CppClass}{
+The name for the class in C++. By default and usually, the intended
+class name in \R.
+}
+ \item{readOnly}{
+Optional vector of field names. These fields will be created as
+read-only in the interface.
+}
+ \item{rename}{
+Optional named character vector, used to name fields or methods
+differently in \R from their C++ name. The elements of the vector are
+the C++ names and the corresponding elements of \code{names(rename)}
+the desired names in \R. So \code{c(.age = "age")} renames the C++
+field or method \code{age} as \code{.age}.
+}
+ \item{Rfile}{
+Controls the writing of a one-line \R command to create the reference
+class corresponding to the C++ module information. By default, this
+will be a file \code{paste0(class, "Class.R")}.
+If the working directory is an \R package source
+directory, the file will be written in the \code{R} subdirectory, otherwise in the working directory itself.
+
+Supplying a character string substitutes that file name for the
+default.
+
+The argument may also be a connection open for
+writing or \code{FALSE} to suppress writing the \R source altogether.
+}
+}
+
+\details{
+The file created by the call to these functions only depends on the
+information in the C++ class supplied. This file is intended to be
+part of the C++ source for an \R package. The file only needs to
+modified when the information changes, either because the class has
+changed or because you want to expose different information to \R. In
+that case you can either recall \code{exposeClass()} or edit the C++
+file created.
+
+The Rcpp Module mechanism has a number of other optional techniques,
+not covered by \code{exposeClass()}. These should be entered into the
+C++ file created. See the \dQuote{rcpp-modules} vignette with the
+package for current possibilities.
+
+For fields and methods specified directly in the C++ class,
+the fields and method arguments to \code{exposeClass()} are character vectors naming the
+corresponding members of the class. For module construction, the
+data types of directly specified fields and of the arguments for the methods are not
+needed.
+
+For \emph{inherited} fields or methods, data type information is
+needed. See the section \dQuote{Inherited Fields and Methods}.
+
+For exposing class constructors, the module needs to know the
+signatures of the constructors to be exposed; each signature is a
+character vector of the corresponding C++ data types.
+
+}
+
+\section{Inherited Fields and Methods}{
+If the C++ class inherits from one or more other classes, the standard
+Rcpp \code{Module} mechanism can not be used to expose inherited
+fields or methods.
+An indirect mechanism is used, generating free functions in C++ to
+expose the inherited members in \R.
+
+This mechanism requires data type information in the call to
+\code{exposeClass()}.
+This is provided by naming the corresponding element of the
+\code{fields} or \code{methods} argument with the name of the member.
+The actual element of the \code{fields} argument is then the single
+data type of the field.
+
+For the \code{methods} argument the argument will generally need to be
+a named list.
+The corresponding element of the list is the vector of data types for
+the return value and for the arguments, if any, to the method.
+For example, if C++ method \code{foo()} took a single argument of type
+\code{NumericVector} and returned a value of type \code{long}, the
+\code{methods} argument would be \code{list(foo = c("long",
+ "NumericVector"))}.
+
+See the second example below.
+}
+\value{
+Nothing, called for its side effect.
+}
+\author{
+ John Chambers
+}
+\seealso{
+\code{\link{setRcppClass}}, which must be called from some \R source
+in the package.
+}
+\examples{
+\dontrun{
+### Given the following C++ class, defined in file PopBD.h,
+### the call to exposeClass() shown below will write a file
+### src/PopBDModule.cpp containing a corresponding module definition.
+### class PopBD {
+### public:
+### PopBD(void);
+### PopBD(NumericVector initBirth, NumericVector initDeath);
+###
+### std::vector<double> birth;
+### std::vector<double> death;
+### std::vector<int> lineage;
+### std::vector<long> size;
+### void evolve(int);
+###
+### };
+### A file R/PopBDClass.R will be written containing the one line:
+### PopBD <- setRcppClass("PopBD")
+###
+### The call below exposes the lineage and size fields, read-only,
+### and the evolve() method.
+
+exposeClass("PopBD",
+ constructors =
+ list("", c("NumericVector", "NumericVector")),
+ fields = c("lineage", "size"),
+ methods = "evolve",
+ header = '#include "PopBD.h"',
+ readOnly = c("lineage", "size"))
+
+### Example with inheritance: the class PopCount inherits from
+### the previous class, and adds a method table(). It has the same
+### constructors as the previous class.
+### To expose the table() method, and the inherited evolve() method and size field:
+
+exposeClass("PopCount",
+ constructors =
+ list("", c("NumericVector", "NumericVector")),
+ fields = c(size = "std::vector<long>"),
+ methods = list("table", evolve = c("void", "int")),
+ header = '#include "PopCount.h"',
+ readOnly = "size")
+}
+}
+
+\keyword{ programming }
+\keyword{ classes }
Modified: pkg/Rcpp/man/setRcppClass.Rd
===================================================================
--- pkg/Rcpp/man/setRcppClass.Rd 2013-10-04 02:28:55 UTC (rev 4557)
+++ pkg/Rcpp/man/setRcppClass.Rd 2013-10-06 21:54:18 UTC (rev 4558)
@@ -6,11 +6,13 @@
Create a Class Extending a C++ Class
}
\description{
-A class is defined that includes the fields and methods of a C++ class
-defined, usually in this package. For most applications, it is
-recommended to call
-\code{\link{classModule}()} to write files in the package with a call to \code{setRcppClass()} and the
-C++ module code required. See Details.
+These routines create a class definition in \R for an exposed C++
+class, setting up and executing a load action to incorporate the C++
+pointer information.
+Neither function should normally need to be called directly; for most applications,
+a call to
+\code{\link{exposeClass}()} will create both C++ and \R code files to
+expose the C++ class.
}
\usage{
setRcppClass(Class, CppClass = , module = , fields = list(), contains = ,
@@ -33,12 +35,14 @@
have to be loaded separately; \code{setRcppClass()} will arrange to
[TRUNCATED]
To get the complete diff run:
svnlook diff /svnroot/rcpp -r 4558
More information about the Rcpp-commits
mailing list