Skip to content

Commit 3b85324

Browse files
committed
Merge remote-tracking branch 'origin/master' into feature/sourcecpp-local-includes
2 parents f7eff33 + e001313 commit 3b85324

File tree

4 files changed

+198
-29
lines changed

4 files changed

+198
-29
lines changed

ChangeLog

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
2015-02-17 JJ Allaire <[email protected]>
2+
3+
* vignettes/Rcpp-attributes.Rnw: Update attributes vignette
4+
with docs on new features,
5+
16
2015-02-14 JJ Allaire <[email protected]>
27

38
* src/attributes.cpp: Allow includes of local files

inst/NEWS.Rd

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
\item Version 3.2 of the Rtools is now correctly detected as well.
3030
\item Allow 'R' to come immediately after '***' for defining embedded R
3131
code chunks in sourceCpp.
32+
\item The attributes vignette has been updated with documentation
33+
on new features added over the past several releases.
3234
}
3335
}
3436
}

vignettes/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
Rcpp-*.bbl
2+
Rcpp-*.blg
23
Rcpp-*.log
34
Rcpp-*.tex
45
Rcpp-*.pdf

vignettes/Rcpp-attributes.Rnw

Lines changed: 190 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ functions include:
101101
Attributes can also be used for package development via the
102102
\texttt{compileAttributes} function, which automatically generates
103103
\texttt{extern "C"} and \texttt{.Call} wrappers for \proglang{C++}
104-
functions within pacakges.
104+
functions within packages.
105105

106106
\section{Using Attributes}
107107

@@ -156,8 +156,9 @@ and \pkg{Rcpp} wrapper types and then source them just as we would an
156156
\proglang{R} script.
157157

158158
The \texttt{sourceCpp} function performs caching based on the last
159-
modified date of the source file so as long as the source file does not
160-
change the compilation will occur only once per R session.
159+
modified date of the source file and it's local dependencies so as
160+
long as the source does not change the compilation will occur only
161+
once per R session.
161162

162163
\subsection{Specifying Argument Defaults}
163164

@@ -169,21 +170,21 @@ the following C++ function:
169170
DataFrame readData(
170171
CharacterVector file,
171172
CharacterVector colNames = CharacterVector::create(),
172-
std::string commentChar = "#",
173+
std::string comment = "#",
173174
bool header = true)
174175
@
175176

176177
Will be exported to R as:
177178

178179
<<eval=FALSE,lang=r>>=
179-
function(file, colNames=character(), commentChar="#", header=TRUE)
180+
function(file, colNames=character(), comment="#", header=TRUE)
180181
@
181182

182183
Note that C++ rules for default arguments still apply: they must occur
183184
consecutively at the end of the function signature and (unlike R) can't rely
184185
on the values of other arguments.
185186

186-
Not all \proglang{C++} defualt argument values can be parsed into their
187+
Not all \proglang{C++} default argument values can be parsed into their
187188
\proglang{R} equivalents, however the most common cases are supported, including:
188189

189190
\begin{itemize}
@@ -204,9 +205,6 @@ Not all \proglang{C++} defualt argument values can be parsed into their
204205
\texttt{cols} constructor.
205206
\end{itemize}
206207

207-
208-
\pagebreak
209-
210208
\subsection{Signaling Errors}
211209

212210
Within \proglang{R} code the \texttt{stop} function is typically used to signal
@@ -233,6 +231,46 @@ In both cases the \proglang{C++} exception will be caught by \pkg{Rcpp}
233231
prior to returning control to \proglang{R} and converted into the correct
234232
signal to \proglang{R} that execution should stop with the specified message.
235233

234+
You can similarly also signal warnings with the \texttt{Rcpp::warning}
235+
function:
236+
237+
<<lang=cpp>>=
238+
if (unexpectedCondition)
239+
Rcpp::warning("Unexpected condition occurred");
240+
@
241+
242+
\subsection{Supporting User Interruption}
243+
244+
If your function may run for an extended period of time, users will appreciate
245+
the ability to interrupt it's processing and return to the REPL. This is
246+
handled automatically for R code (as R checks for user interrupts periodically
247+
during processing) however requires explicit accounting for in C and C++
248+
extensions to R. To make computations interrupt-able, you should periodically
249+
call the \texttt{Rcpp::checkUserInterrupt} function, for example:
250+
251+
<<lang=cpp>>=
252+
for (int i=0; i<1000000; i++) {
253+
254+
// check for interrupt every 1000 iterations
255+
if (i % 1000 == 0)
256+
Rcpp::checkUserInterrupt();
257+
258+
// ...do some expensive work...
259+
260+
}
261+
@
262+
263+
A good guideline is to call \texttt{Rcpp::checkUserInterrupt} every 1 or 2
264+
seconds that your computation is running. In the above code, if the user
265+
requests an interrupt then an exception is thrown and the attributes wrapper
266+
code arranges for the user to be returned to the REPL.
267+
268+
Note that R provides a \proglang{C} API for the same purpose
269+
(\texttt{R\_CheckUserInterrupt}) however this API is not safe to use in
270+
\proglang{C++} code as it uses \texttt{longjmp} to exit the current scope,
271+
bypassing any C++ destructors on the stack. The \texttt{Rcpp::checkUserInterrupt}
272+
function is provided as a safe alternative for \proglang{C++} code.
273+
236274
\subsection{Embedding R Code}
237275

238276
Typically \proglang{C++} and \proglang{R} code are kept in their own source
@@ -256,20 +294,20 @@ Multiple \proglang{R} code chunks can be included in a \proglang{C++} file. The
256294
\texttt{sourceCpp} function will first compile the \proglang{C++} code into a
257295
shared library and then source the embedded \proglang{R} code.
258296

259-
\pagebreak
260-
261297
\subsection{Modifying Function Names}
262298

263299
You can change the name of an exported function as it appears to \proglang{R} by
264300
adding a name parameter to \texttt{Rcpp::export}. For example:
265301

266302
<<lang=cpp>>=
267-
// [[Rcpp::export(".convolveCpp")]]
303+
// [[Rcpp::export(name = ".convolveCpp")]]
268304
NumericVector convolveCpp(NumericVector a, NumericVector b)
269305
@
270306

271-
Note that in this case since the specified name is prefaced by a \code{.} the exported R
272-
function will be hidden.
307+
Note that in this case since the specified name is prefaced by a \code{.} the
308+
exported R function will be hidden. You can also use this method to provide
309+
implementations of S3 methods (which wouldn't otherwise be possible because
310+
C++ functions can't contain a '.' in their name).
273311

274312
\subsection{Function Requirements}
275313

@@ -293,7 +331,7 @@ requirements to be correctly handled:
293331
\subsection{Random Number Generation}
294332

295333
\proglang{R} functions implemented in \proglang{C} or \proglang{C++} need
296-
to be careful to surround use of internal random number geneneration routines
334+
to be careful to surround use of internal random number generation routines
297335
(e.g. \texttt{unif\_rand}) with calls to \texttt{GetRNGstate} and
298336
\texttt{PutRNGstate}.
299337

@@ -304,7 +342,20 @@ Note that \pkg{Rcpp} implements \texttt{RNGScope} using a counter, so it's
304342
still safe to execute code that may establish it's own \texttt{RNGScope} (such
305343
as the \pkg{Rcpp} sugar functions that deal with random number generation).
306344

307-
\pagebreak
345+
The overhead associated with using \texttt{RNGScope} is negligible (only a
346+
couple of milliseconds) and it provides a guarantee that all C++ code
347+
will inter-operate correctly with R's random number generation. If you are
348+
certain that no C++ code will make use of random number generation and the
349+
2ms of execution time is meaningful in your context, you can disable the
350+
automatic injection of \texttt{RNGScope} using the \texttt{rng} parameter
351+
of the \texttt{Rcpp::export} attribute. For example:
352+
353+
<<lang=cpp>>=
354+
// [[Rcpp::export(rng = false)]]
355+
double myFunction(double input) {
356+
// ...code that never uses R random number generation...
357+
}
358+
@
308359

309360
\subsection{Importing Dependencies}
310361

@@ -352,9 +403,60 @@ and by invoking \pkg{inline} plugins if they are available for a package.
352403
Note that while the \texttt{Rcpp::depends} attribute establishes dependencies
353404
for \texttt{sourceCpp}, it's important to note that if you include the same
354405
source file in an \proglang{R} package these dependencies must still be
355-
listed in the \texttt{Depends} and \texttt{LinkingTo} fields of the package
406+
listed in the \texttt{Imports} and/or \texttt{LinkingTo} fields of the package
356407
\texttt{DESCRIPTION} file.
357408

409+
\subsection{Sharing Code}
410+
411+
The core use case for \texttt{sourceCpp} is the compilation of a single
412+
self-contained source file. Code within this file can import other C++ code
413+
by using the \texttt{Rcpp::depends} attribute as described above.
414+
415+
The recommended practice for sharing C++ code across many uses of
416+
\texttt{sourceCpp} is therefore to create an R package to wrap the C++
417+
code. This has many benefits not the least of which is easy distribution of
418+
shared code. More information on creating packages that contain C++ code
419+
is included in the Package Development section below.
420+
421+
If you need to share a small amount of C++ code between source files
422+
compiled with \texttt{sourceCpp} and the option of creating a package
423+
isn't practical, then you can also share code using local includes of C++
424+
header files. To do this, create a header file with the definition of
425+
shared functions, classes, enums, etc. For example:
426+
427+
<<lang=cpp>>=
428+
#ifndef __UTILITIES__
429+
#define __UTILITIES__
430+
431+
double timesTwo(double x) {
432+
return x * 2;
433+
}
434+
435+
#endif // __UTILITIES__
436+
@
437+
438+
Note the use of the \texttt{\#ifndef} include guard, this is import to ensure
439+
that code is not included more than once in a source file. You should
440+
use an include guard and be sure to pick a unique name for the corresponding
441+
\texttt{\#define}.
442+
443+
To use this code in a source file you'd just include
444+
it based on it's relative path (being sure to use \texttt{"} as the
445+
delimiter to indicate a local file reference). For example:
446+
447+
<<lang=cpp>>=
448+
#include "shared/utilities.hpp"
449+
450+
// [[Rcpp::export]]
451+
double transformValue(double x) {
452+
return timesTwo(x) * 10;
453+
}
454+
@
455+
456+
Note that the processing of Rcpp attributes (e.g. \texttt{export},
457+
\texttt{depends}, etc.) is limited to the main source file so all exported
458+
functions and dependencies should be defined there rather than in
459+
shared header files.
358460

359461
\subsection{Including C++ Inline}
360462

@@ -428,24 +530,41 @@ Rcpp.package.skeleton("NewPackage", example_code = FALSE,
428530

429531
\subsection{Specifying Dependencies}
430532

431-
%% TODOD(DE) Rework in terms of Imports:
432533
Once you've migrated \proglang{C++} code into a package, the dependencies for
433-
source files are derived from the \texttt{Depends} and \texttt{LinkingTo} fields
534+
source files are derived from the \texttt{Imports} and \texttt{LinkingTo} fields
434535
in the package \texttt{DESCRIPTION} file rather than the \texttt{Rcpp::depends}
435-
attribute. For every package you import C++ code from (including \pkg{Rcpp})
436-
you need to add these entries.
536+
attribute. Some packages also require the addition of an entry to the package
537+
\texttt{NAMESPACE} file to ensure that the package's shared library is loaded
538+
prior to callers using the package. For every package you import C++ code from
539+
(including \pkg{Rcpp}) you need to add these entries.
540+
541+
Packages that provide only C++ header files (and no shared library) need only
542+
be referred to using \texttt{LinkingTo}. You should consult the documentation
543+
for the package you are using for the requirements particular to that package.
437544

438-
For example, if your package depends on \pkg{Rcpp} and \pkg{RcppArmadillo}
439-
you would have the following in your \texttt{DESCRIPTION} file:
545+
For example, if your package depends on \pkg{Rcpp} you'd have the following
546+
entries in the \texttt{DESCRIPTION} file:
440547

441548
<<lang=bash>>=
442-
Depends: Rcpp (>= 0.10.0), RcppArmadillo (>= 0.3.4.4)
443-
LinkingTo: Rcpp, RcppArmadillo
549+
Imports: Rcpp (>= 0.11.4)
550+
LinkingTo: Rcpp
551+
@
552+
553+
And the following entry in your \texttt{NAMESPACE} file:
554+
555+
<<lang=bash>>=
556+
importFrom(Rcpp, evalCpp)
557+
@
558+
559+
If your package additionally depended on the \pkg{BH} (Boost headers) package
560+
you'd just add an entry for \pkg{BH} to the \texttt{LinkingTo} field since
561+
\pkg{BH} is a header-only package:
562+
563+
<<lang=bash>>=
564+
Imports: Rcpp (>= 0.11.4)
565+
LinkingTo: Rcpp, BH
444566
@
445567

446-
Using a \texttt{Imports} declaration together with an \texttt{import} or
447-
\texttt{importFrom} statement in the file \texttt{NAMESPACE} is a more recent
448-
alternative.
449568

450569
\subsection{Exporting R Functions}
451570

@@ -474,7 +593,10 @@ Results in the generation of the following two source files:
474593
\end{itemize}
475594

476595
You should re-run \texttt{compileAttributes} whenever functions are added,
477-
removed, or have their signatures changed.
596+
removed, or have their signatures changed. Note that if you are using either
597+
RStudio or \pkg{devtools} to build your package then the
598+
\texttt{compileAttributes} function is called automatically whenever your
599+
package is built.
478600

479601
The \texttt{compileAttributes} function deals only with exporting
480602
\proglang{C++} functions to \proglang{R}. If you want the functions to
@@ -483,6 +605,45 @@ step may be required. Specifically, if your package \texttt{NAMESPACE} file
483605
does not use a pattern to export functions then you should add an explicit
484606
entry to \texttt{NAMESPACE} for each R function you want publicly available.
485607

608+
\subsection{Types in Generated Code}
609+
610+
In some cases the signatures of the C++ functions that are generated within
611+
\texttt{RcppExports.cpp} may have additional type requirements beyond the core
612+
standard library and \pkg{Rcpp} types (e.g. \texttt{CharacterVector},
613+
\texttt{NumericVector}, etc.). Examples might include convenience typedefs,
614+
as/wrap handlers for marshaling between custom types and SEXP, or types
615+
wrapped by the Rcpp \texttt{XPtr} template.
616+
617+
In this case, you can create a header file that contains these type definitions
618+
(either defined inline or by including other headers) and have this header
619+
file automatically included in \texttt{RcppExports.cpp}. Headers named with
620+
the convention \texttt{pkgname\_types} are automatically included along with
621+
the generated C++ code. For example, if your package is named \pkg{fastcode}
622+
then any of the following header files would be automatically included in
623+
\texttt{RcppExports.cpp}:
624+
625+
<<lang=cpp>>=
626+
src/fastcode_types.h
627+
src/fastcode_types.hpp
628+
inst/include/fastcode_types.h
629+
inst/include/fastcode_types.hpp
630+
@
631+
632+
There is one other mechanism for type visibility in \texttt{RcppExports.cpp}.
633+
If your package provides a master include file for consumption by C++ clients
634+
then this file will also be automatically included. For example, if the
635+
\pkg{fastcode} package had a C++ API and the following header file:
636+
637+
<<lang=cpp>>=
638+
inst/include/fastcode.h
639+
@
640+
641+
This header file will also automatically be included in
642+
\texttt{RcppExports.cpp}. Note that the convention of using \texttt{.h} for
643+
header files containing C++ code may seem unnatural, but this comes from the
644+
recommended practices described in `\textsl{Writing R Extensions}'
645+
\citep{R:Extensions}.
646+
486647
\subsection{Roxygen Comments}
487648

488649
The \pkg{roxygen2} package \citep{CRAN:roxygen2} provides a facility for

0 commit comments

Comments
 (0)