[Rcpp-devel] Rcpp C++11 on Windows

Peter Meissner retep.meissner at gmail.com
Thu Jan 28 00:32:00 CET 2016


Thank you all so much for your suggestions.

What features I needed to get working where auto type in combination
with cycling through multimap.equal_range() results. It seems like
this was not actually a problem with Windows / Rtools / compiler /
c++0x / c++11 but with not cleaning up before recompiling - now I feel
stupid, thanks again for clearifications and pointing in the right
direction. It works.

Best, Peter


PS.:

To be complete here is what I attempt to do, that actually works even
with the g++4.6.3 compiler and c++0x standard under Windows (i.e.
merging two data.frames via time span information by expanding time
spans to days and than cycling through the days and looking up matches
in multimaps to build a new data.frame with day, id1, and id2 that can
ultimatly be re-aggregated to spans):

#include <iostream>
#include <vector>
#include <Rcpp.h>
using namespace Rcpp;
using namespace std;

// [[Rcpp::plugins(cpp11)]]
// [[Rcpp::export]]

DataFrame span_matcher_worker(DataFrame df1, DataFrame df2) {

  // put info in neat litle vectors
  CharacterVector id_one_in = df1[0];
  IntegerVector start_one_in = df1[1];
  IntegerVector end_one_in = df1[2];


  CharacterVector id_two_in = df2[0];
  IntegerVector start_two_in = df2[1];
  IntegerVector end_two_in = df2[2];

  // determine span length
  int min_start_one = min(start_one_in);
  int min_start_two = min(start_two_in);

  int max_end_one = max(end_one_in);
  int max_end_two = max(end_two_in);

  int min_span = min(min_start_one, min_start_two) ;
  int max_span = max(max_end_one, max_end_two);

  // put days:ids into multimap
  multimap<int, string> days_id_one;
  multimap<int, string> days_id_two;

  for( int i = 0; i < id_one_in.size(); i++ ){
    for (int day = start_one_in[i]; day <= end_one_in[i]; day++ ){
      days_id_one.insert(pair<int, string>(day, 
as<string>(id_one_in[i]) ));
    }
  }

  for( int i = 0; i < id_two_in.size(); i++ ){
    for (int day = start_two_in[i]; day <= end_two_in[i]; day++ ){
      days_id_two.insert(pair<int, string>(day, 
as<string>(id_two_in[i])));
    }
  }


  // access the columns
  IntegerVector days;
  CharacterVector id_one ;
  CharacterVector id_two ;

  for (int i = min_span; i <= max_span; i++) {
    // no matches
    if( days_id_one.count(i)==0 && days_id_two.count(i)==0 ){
      days.push_back(i);
      id_one.push_back(NA_STRING);
      id_two.push_back(NA_STRING);
      continue;
    }
    // matches for one but not for two
    if( days_id_one.count(i)>0 && days_id_two.count(i)==0 ){
      auto range = days_id_one.equal_range(i);
      for (auto iterate = range.first; iterate != range.second; 
++iterate) {
        days.push_back(i);
        id_one.push_back(iterate->second);
        id_two.push_back(NA_STRING);
      }
      continue;
    }
    // matches for two but not for one
    if( days_id_one.count(i)==0 && days_id_two.count(i)>0 ){
      auto range = days_id_two.equal_range(i);
      for (auto iterate = range.first; iterate != range.second; 
++iterate) {
        days.push_back(i);
        id_one.push_back(NA_STRING);
        id_two.push_back(iterate->second);
      }
      continue;
    }
    // matches in both
    if( days_id_one.count(i)>0 && days_id_two.count(i)>0 ){
      auto range = days_id_one.equal_range(i);
      for (auto it = range.first; it != range.second; it++) {
        auto range_two = days_id_two.equal_range(i);
        for (auto it_two = range_two.first; it_two !=
range_two.second; it_two++) {
          days.push_back(i);
          id_one.push_back(it->second);
          id_two.push_back(it_two->second);
        }
      }
    }
  };

  // return a new data frame
  return DataFrame::create(
    _["days"]=days,
    _["id_one"]=id_one,
    _["id_two"]=id_two)
    ;
}






Am Mi, 27. Jan, 2016 um 1:57 schrieb Dirk Eddelbuettel <edd at debian.org>:
> 
> On 27 January 2016 at 11:13, Martyn Plummer wrote:
> | Q1: Does CRAN accept C++11 code?
> | A1: Yes but you have to indicate that you are using C++11 rather 
> than C
> | ++98, which is still the default standard for CRAN packages. This is
> | described in the "Writing R Extensions" manual in section 1.2.4.
> 
> Yup. Declaring it is easy. And the consequence _can_ (for now) be 
> that you
> may not be able to build on Windows. The g++ 4.6.* compilers supports 
> a
> subset of C++11 only.
> 
> I declare 'CXX_STD = CXX11' in packages RcppAnnoy, RcppBDT, RcppCCTZ,
> RcppCNPy, RcppTOML -- and of these RcppAnnoy, RcppBDT and RcppCNPy 
> *do*
> create Windows binaries. Whereas RcppCCTZ and RcppTOML use 'real' 
> C++11 with
> features not supported by this old compiler so they exist on Linux 
> and OS X
> only.
>  
> | Q2: Are C++11 features available on Windows?
> | A2: Not yet. Release 4.6.3 includes limited support for C++11 
> features.
> | Again, the "Writing R Extensions" manual will give you more details,
> | with a link to a page describing what features are available. There 
> are
> | plans to update the toolchain on Windows to 4.9.2. This will 
> improve C
> | ++11 support on windows but it will not be complete. The first
> | fully-compliant gcc release is 5.1. However, it is not sufficiently
> | stable on Windows.
> 
> It depends. It is not black/white even if some people insist on 
> portraying it
> as such.  Many features were added incrementally.
> 
> g++-4.6.* has C++0x with some things, g++-4.9 adds quite a lot more 
> and works
> for all I do.  At work we sometimes rely on C++14 already and use 
> g++-5.2.
> 
> So you need to tell us what it is you want to do, or just try it, and 
> the
> compiler _currently in use_ may fail.  With some luck we may get 
> g++-4.9.* on
> Windows with R 3.3.0.
> 
> The error you showed from spanmatcher appeared to be a _linker_ error 
> not a
> compiler error so something else may be going on there.
> 
> Dirk
> 
> -- 
> http://dirk.eddelbuettel.com | @eddelbuettel | edd at debian.org



More information about the Rcpp-devel mailing list