// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8 -*- #include #ifdef _OPENMP #include #endif #include /** * Base class for interrupt exceptions thrown when user * interrupts are detected. */ class interrupt_exception : public std::exception { public: /** * Constructor. * @param[in] message A description of event that * caused this exception. */ interrupt_exception(std::string message) : detailed_message(message) {}; /** * Virtual destructor. Needed to avoid "looser throw specification" errors. */ virtual ~interrupt_exception() throw() {}; /** * Obtain a description of the exception. * @return Description. */ virtual const char* what() const throw() { return detailed_message.c_str(); } /** * String with details on the error. */ std::string detailed_message; }; /** * Do the actual check for an interrupt. * @attention This method should never be called directly. * @param[in] dummy Dummy argument. */ static inline void check_interrupt_impl(void* /*dummy*/) { R_CheckUserInterrupt(); } /** * Call this method to check for user interrupts. * This is based on the results of a discussion on the * R-devel mailing list, suggested by Simon Urbanek. * @attention This method must not be called by any other * thread than the master thread. If called from within * an OpenMP parallel for loop, make sure to check * for omp_get_thread_num()==0 before calling this method! * @return True, if a user interrupt has been detected. */ inline bool check_interrupt() { return (R_ToplevelExec(check_interrupt_impl, NULL) == FALSE); } /** * Compute pi using the Leibniz formula * (a very inefficient approach). * @param[in] n Number of summands * @param[in] frequency Check for interrupts after * every @p frequency loop cycles. */ RcppExport SEXP PiLeibniz(SEXP n, SEXP frequency) { BEGIN_RCPP // cast parameters int n_cycles = Rcpp::as(n); int interrupt_check_frequency = Rcpp::as(frequency); // user interrupt flag bool interrupt = false; double pi = 0; #ifdef _OPENMP #pragma omp parallel for \ shared(interrupt_check_frequency, n_cycles, interrupt) \ reduction(+:pi) #endif for (int i=0; i