[Rcpp-commits] r3996 - in pkg/Rcpp: . man src

noreply at r-forge.r-project.org noreply at r-forge.r-project.org
Mon Nov 19 15:32:12 CET 2012


Author: jjallaire
Date: 2012-11-19 15:32:11 +0100 (Mon, 19 Nov 2012)
New Revision: 3996

Modified:
   pkg/Rcpp/ChangeLog
   pkg/Rcpp/TODO
   pkg/Rcpp/man/exportAttribute.Rd
   pkg/Rcpp/src/Attributes.cpp
   pkg/Rcpp/src/AttributesParser.cpp
   pkg/Rcpp/src/AttributesParser.h
Log:
support for argument default values

Modified: pkg/Rcpp/ChangeLog
===================================================================
--- pkg/Rcpp/ChangeLog	2012-11-18 20:59:00 UTC (rev 3995)
+++ pkg/Rcpp/ChangeLog	2012-11-19 14:32:11 UTC (rev 3996)
@@ -1,3 +1,10 @@
+2012-11-19  JJ Allaire <jj at rstudio.org>
+
+        * src/AttributesParser.h: support for argument default values
+        * src/AttributesParser.cpp: support for argument default values
+        * src/Attributes.cpp: support for argument default values
+        * man/exportAttribute.Rd: documentation updates
+
 2012-11-18  JJ Allaire <jj at rstudio.org>
 
         * R/Attributes.R: sourceCpp embedded R code; print warning if 

Modified: pkg/Rcpp/TODO
===================================================================
--- pkg/Rcpp/TODO	2012-11-18 20:59:00 UTC (rev 3995)
+++ pkg/Rcpp/TODO	2012-11-19 14:32:11 UTC (rev 3996)
@@ -132,9 +132,6 @@
     
     o   Add unit tests 
 
-    o   Mechanism for specifying default values for exported R functions
-        (Rcpp::defaults attribute?)
-
     o   onBuildCompleted hook should pass succeeded = false if the loading
         of the dynamic library fails
 

Modified: pkg/Rcpp/man/exportAttribute.Rd
===================================================================
--- pkg/Rcpp/man/exportAttribute.Rd	2012-11-18 20:59:00 UTC (rev 3995)
+++ pkg/Rcpp/man/exportAttribute.Rd	2012-11-19 14:32:11 UTC (rev 3996)
@@ -20,8 +20,25 @@
     \item Have a return type that is either void or compatible with \code{Rcpp::wrap} and parameter types that are compatible with \code{Rcpp::as} (see sections 3.1 and 3.2 of the \emph{Rcpp-introduction} vignette for more details).
     \item Use fully qualified type names for the return value and all parameters. However, Rcpp types may appear without the namespace qualifier (i.e. \code{DataFrame} is okay as a type name but \code{std::string} must be specified fully).
 }
+    If default argument values are provided in the C++ function definition then these defaults are also used for the exported R function. For example, the following C++ function:
+    
+\preformatted{
+DataFrame readData(
+    CharacterVector file, 
+    CharacterVector exclude = CharacterVector::create(),
+    bool fill = true)
 }
 
+    Will be exported to R as:
+
+\preformatted{
+function (file, exclude = character(0), fill = TRUE)
+}
+
+    Note that C++ rules for default arguments still apply: they must occur consecutively at the end of the function signature and unlike R can't rely on the values of other arguments.
+
+}
+
 \note{
     When a C++ function has export bindings automatically generated by the \code{\link{compileAttributes}} function, it can optionally also have a direct C++ interface generated using the \code{\link[=interfacesAttribute]{Rcpp::interfaces}} attribute.
     

Modified: pkg/Rcpp/src/Attributes.cpp
===================================================================
--- pkg/Rcpp/src/Attributes.cpp	2012-11-18 20:59:00 UTC (rev 3995)
+++ pkg/Rcpp/src/Attributes.cpp	2012-11-19 14:32:11 UTC (rev 3996)
@@ -134,7 +134,10 @@
                                         it->function().arguments();
                     ostr << ", Rcpp::List::create("; 
                     for (size_t i=0; i<args.size(); i++) {
-                        ostr << "Rcpp::Named(\"" << args[i].name() << "\")";
+                        const Argument& arg = args[i];
+                        ostr << "Rcpp::Named(\"" << arg.name() << "\")";
+                        if (!arg.defaultValue().empty())
+                            ostr << " = " << arg.defaultValue();
                         if (i != (args.size()-1))
                             ostr << ", ";
                     }

Modified: pkg/Rcpp/src/AttributesParser.cpp
===================================================================
--- pkg/Rcpp/src/AttributesParser.cpp	2012-11-18 20:59:00 UTC (rev 3995)
+++ pkg/Rcpp/src/AttributesParser.cpp	2012-11-19 14:32:11 UTC (rev 3996)
@@ -146,6 +146,8 @@
             if (!argument.name().empty()) {
                 os << " ";
                 os << argument.name();
+                if (!argument.defaultValue().empty())
+                    os << " = " << argument.defaultValue();
             }
         }
         return os;
@@ -388,7 +390,7 @@
         // Start at the end and look for the () that deliniates the arguments
         // (bail with an empty result if we can't find them)
         std::string::size_type endParenLoc = signature.find_last_of(')');
-        std::string::size_type beginParenLoc = signature.find_last_of('(');
+        std::string::size_type beginParenLoc = signature.find_first_of('(');
         if (endParenLoc == std::string::npos || 
             beginParenLoc == std::string::npos ||
             endParenLoc < beginParenLoc) {
@@ -451,6 +453,16 @@
                 // we don't warn here because the compilation will fail anyway
                 continue;
             }
+            
+            // If the argument has an = within it then it has a default value
+            std::string defaultValue;
+            std::string::size_type eqPos = arg.find_first_of('=');
+            if ( (eqPos != std::string::npos) && ((eqPos + 1) < arg.size()) ) {    
+                defaultValue = arg.substr(eqPos+1);
+                trimWhitespace(&defaultValue);    
+                arg = arg.substr(0, eqPos);
+                trimWhitespace(&arg);
+            }
                     
             // Scan backwards for whitespace to determine where the type ends
             // (we go backwards because whitespace is valid inside the type
@@ -480,7 +492,7 @@
             }
             
             // add argument
-            arguments.push_back(Argument(name, type));
+            arguments.push_back(Argument(name, type, defaultValue));
         }
         
         return Function(type, name, arguments, signature);
@@ -517,23 +529,45 @@
                                                 const std::string& argText) {
         
         int templateCount = 0;
+        int parenCount = 0;
+        bool insideQuotes = false;
         std::string currentArg;
         std::vector<std::string> args;
+        char prevChar = 0;
         for (std::string::const_iterator 
                             it = argText.begin(); it != argText.end(); ++it) {
             char ch = *it;
             
-            if (ch == ',' && templateCount == 0) {
+            if (ch == '"' && prevChar != '\\') {
+                insideQuotes = !insideQuotes;
+            }
+              
+            if ((ch == ',') && 
+                (templateCount == 0) &&
+                (parenCount == 0) &&
+                !insideQuotes) {
                 args.push_back(currentArg);
                 currentArg.clear();
                 continue;
             } else {
-                currentArg.push_back(ch);   
-                if (ch == '<')
-                    templateCount++;
-                else if (ch == '>')
-                    templateCount--;
+                currentArg.push_back(ch); 
+                switch(ch) {
+                    case '<':
+                        templateCount++;
+                        break;
+                    case '>':
+                        templateCount--;
+                        break;
+                    case '(':
+                        parenCount++;
+                        break;
+                    case ')':
+                        parenCount--;
+                        break;
+                }
             }
+            
+            prevChar = ch;
         }
         
         if (!currentArg.empty())

Modified: pkg/Rcpp/src/AttributesParser.h
===================================================================
--- pkg/Rcpp/src/AttributesParser.h	2012-11-18 20:59:00 UTC (rev 3995)
+++ pkg/Rcpp/src/AttributesParser.h	2012-11-19 14:32:11 UTC (rev 3996)
@@ -58,8 +58,10 @@
     class Argument {
     public:
         Argument() {}
-        Argument(const std::string& name, const Type& type) 
-            : name_(name), type_(type) 
+        Argument(const std::string& name, 
+                 const Type& type,
+                 const std::string& defaultValue) 
+            : name_(name), type_(type), defaultValue_(defaultValue) 
         {
         }
         
@@ -67,10 +69,12 @@
         
         const std::string& name() const { return name_; }
         const Type& type() const { return type_; }
+        const std::string& defaultValue() const { return defaultValue_; }
         
     private:
         std::string name_;
         Type type_;
+        std::string defaultValue_;
     };
     
     // Function info  



More information about the Rcpp-commits mailing list