Thanks very much, Romain.
On Sat, Dec 4, 2010 at 8:13 AM, Romain Francois <[email protected]> wrote: > Le 02/12/10 22:15, Douglas Bates a écrit : >> >> In the lme4a package I mixed calls to Rf_error and throwing C++ >> exceptions. This is causing problems and I plan to replace the calls >> to Rf_error by exceptions so that there is a consistent approach. >> >> Many of the calls to Rf_error take advantage of the fact the Rf_error >> implicitly calls sprintf to create the error message. Thus I have >> calls like >> >> if (!d_x.size() == d_nrow * d_ncol) >> ::Rf_error("%s: Dim = (%d, %d) is inconsistent with x.size() = >> %d", >> "ddenseMatrix::ddenseMatrix", d_nrow, d_ncol, >> d_x.size()); >> >> Is there a similar idiom for creating an exception's "what" argument? >> I imagine I could add std::strings and maybe use some iostreams or >> something like that ... > > Hello, > > I've added the sprintf template, defined as: > > template <int MAX_SIZE> > const char* sprintf( const char *format, ...) { > static char buffer[MAX_SIZE]; > va_list(ap); > va_start(ap, format); > vsprintf( buffer, format, ap); > va_end(ap); > buffer[MAX_SIZE] = '\0'; > return strdup( buffer ) ; > } > > so that we can do things like : > > fx <- cxxfunction( , ' > return CharacterVector::create( > sprintf<100>( "bla %d", 10 ), > sprintf<100>( "bla %s %d", " bla" , 10) > ); > ', plugin = "Rcpp", verbose = TRUE > ) > fx() > > > This way, I think you can create your exception class like this: > > > fy <- cxxfunction( , ' > throw foo_exception( 10, 10, 10 ) ; > ', includes = ' > > class foo_exception : public std::exception { > public: > foo_exception( int nrow_, int ncol_, int size_): > nrow(nrow_), ncol(ncol_), size(size_){} > inline const char* what() const throw(){ > return sprintf<100>( > "%s: Dim = (%d, %d) is inconsistent with x.size() = %d", > "ddenseMatrix::ddenseMatrix", nrow, ncol, size > ) ; > } > ~foo_exception() throw(){} > > private: > int nrow, ncol, size ; > } ; > > > ', plugin = "Rcpp", verbose = TRUE > ) > > >> tryCatch( fy(), error = function(e) writeLines( conditionMessage(e) ) ) > ddenseMatrix::ddenseMatrix: Dim = (10, 10) is inconsistent with x.size() = > 10 > > > sprintf is a template, and static data is allocated with it. The parameter > should be bug enough to host the full message. > > one thing you can do is instantiate the template once : > > const char* (*my_sprintf)(const char*, ...) = &sprintf<100> ; > > Romain > > -- > Romain Francois > Professional R Enthusiast > +33(0) 6 28 91 30 30 > http://romainfrancois.blog.free.fr > |- http://bit.ly/gpCSpH : Evolution of Rcpp code size > |- http://bit.ly/hovakS : RcppGSL initial release > `- http://bit.ly/iaxTdO : parser 0.0-12 > > > _______________________________________________ > Rcpp-devel mailing list > [email protected] > https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel > _______________________________________________ Rcpp-devel mailing list [email protected] https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel
