[Rcpp-devel] Patch for using Rcpp with proper check of TR1/C++11 headers

Dirk Eddelbuettel edd at debian.org
Sun Dec 2 15:50:44 CET 2012


Yan,

Follow-ups on list are preferred to on-list stuff, so I pivoting this back to
the list.  

Now, it so happens that your post did not get through because it exceeded the
40kb limit.  Do you want me to let it through, or in light of what is below,
remove it?

On 2 December 2012 at 14:24, Yan Zhou wrote:
| Dear Dirk,
| 
| The last patch has some typos. Though they don't cause compile errors (that's
| why I didn't find them in the first place), they cause <initializer_list> not
| used even it is there.
| 
| Sorry for being so careless, always have to submit a new a new corrected
| version right after sending one patch.

No worries.  What I have some worries about, though, is amount of change.  

We got bitten in the behind this time as we (indadvertently) changed the ABI
requiring a rebuild of _everything_ that depends on Rcpp. Not ideal.

I am already paranoid about testing and do

    R CMD check      -- with its 700+ tests but you MUST define
      	  	        RunAllRcppTests="yes" (as CRAN wants a 1 min limit,
			all tests are off otherwise); setting a "subversion"
			as eg 0.10.1.1 enables it too

    examples in the package itself   -- below inst/examples/, loop over directories

    examples in the RInside package   -- similar 

    builds on Windows using the win-builder service

and we probably should also try to build and test many of the 90 packages
depending on Rcpp.

Could you shoulder some of that testing ?  Just doing a compile is nowhere
close enough, especially for something moderately invasive.

Dirk
 
| Best,
| 
| Yan Zhou
| 
| On Dec 02, 2012, at 02:13 PM, Yan Zhou <zhouyan at me.com> wrote:
| 
| 
|     Hi Dirk,
| 
|     First, in the last email I forgot to actually attach the file. Second, that
|     one seems grown too large and is posted yet.
| 
|     The attached Rcpp.diff is the change we discussed yesterday. RcppCommon.h
|     is the new version of the header, which shall be easier to read than the
|     diff file, which is a little mess.
| 
|     To summary the change.
| 
|     1. No longer define HAS_CXX0X. Currently this is only used for test of
|     static_assert. If we are going to use more C++0X feature in future, this
|     macro will be a source of pain (as I once experienced), due to the various
|     status of C++11 implementations. Instead, now we have a separate macro
|     HAS_STATIC_ASSERT
| 
|     2. Most compiler dependent test macros are now grouped together
|         i) Test C++0x language features: variadic template and static assert
|         ii) Test C++0x library features: initializer_list, unordered_map,
|     unordered_set
|         iii) Test TR1 headers, unordered_map, unordered_set
|     The first two only define macros in the case that the compiler is indeed
|     used in C++11 mode. There are situations that the compiler can include
|     C++11 header but cannot compile them
| 
|     3. Rcpp/sugar.h no longer need to include Rcpp/sugar/sets.h
| 
|     4. Rcpp/inst/unitTests/runit.wrap.R: Change std::tr1::unordered_map to
|     RCPP_UNORDERED_MAP
| 
|     5. It passes some unit tests. It seems that these changes do not break unit
|     tests. But there are tests that says in sourceCpp(...) a character vector
|     is expected. I am not sure if it is caused by these changes. I am using a
|     SVN tip version of R. And this does look like an R error. So perhaps
|     nothing need to worry.
| 
|     I would suggest you may do some more test and review before considering
|     merge into the trunk (I was never known to be a careful person, typos are
|     always possible). These changes perhaps only benefits very few people like
|     me who are eager to use C++11, so there is no reason to merge them any time
|     soon unless we are sure they don't introduce new problems. I have tested
|     the build and installation under the compilers and platform I mentioned
|     yesterday.
| 
|     Best,
| 
|     Yan Zhou
|     _______________________________________________
|     Rcpp-devel mailing list
|     Rcpp-devel at lists.r-forge.r-project.org
|     https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel
|      
| 
| 
| ----------------------------------------------------------------------
| // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*-
| //
| // RcppCommon.h: Rcpp R/C++ interface class library -- common include and defines statements
| //
| // Copyright (C) 2008 - 2009 Dirk Eddelbuettel
| // Copyright (C) 2009 - 2012 Dirk Eddelbuettel and Romain Francois
| //
| // This file is part of Rcpp.
| //
| // Rcpp is free software: you can redistribute it and/or modify it
| // under the terms of the GNU General Public License as published by
| // the Free Software Foundation, either version 2 of the License, or
| // (at your option) any later version.
| //
| // Rcpp is distributed in the hope that it will be useful, but
| // WITHOUT ANY WARRANTY; without even the implied warranty of
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
| // GNU General Public License for more details.
| //
| // You should have received a copy of the GNU General Public License
| // along with Rcpp.  If not, see <http://www.gnu.org/licenses/>.
| 
| #ifndef RcppCommon_h
| #define RcppCommon_h
| 
| #undef GOOD_COMPILER_FOR_RCPP
| #ifdef __GNUC__
| #define GOOD_COMPILER_FOR_RCPP
| #endif
| #ifdef __SUNPRO_CC
| #define GOOD_COMPILER_FOR_RCPP
| #endif
| #ifdef __clang__
| #define GOOD_COMPILER_FOR_RCPP
| #endif
| #ifdef __INTEL_COMPILER
| #define GOOD_COMPILER_FOR_RCPP
| #endif
| 
| #ifndef GOOD_COMPILER_FOR_RCPP
| # error "This compiler is not supported"
| #endif
| 
| #include <Rcpp/config.h>
| #include <Rcpp/macros/unroll.h>
| 
| void logTxtFunction(const char* file, const int line, const char* expression ) ;
| 
| /**
|  * \brief Rcpp API
|  */
| namespace Rcpp{
| 
|     /**
|      * \brief traits used to dispatch wrap
|      */
|     namespace traits{
|     } // traits
| 
|     /**
|      * \brief internal implementation details
|      */
|     namespace internal{     
|     } // internal 
| } // Rcpp
| 
| #include <Rcpp/module/macros.h>
| 
| #ifdef __GNUC__
|     #define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
|     // g++ 4.5 does not seem to like some of the fast indexing
|     #if GCC_VERSION >= 40500
|         #define IS_GCC_450_OR_LATER
|     #endif
|     // g++ 4.6 switches from exception_defines.h to bits/exception_defines.h
|     #if GCC_VERSION < 40600
|         #define IS_EARLIER_THAN_GCC_460
|     #endif
|     #if GCC_VERSION >= 40600
|         #define IS_GCC_460_OR_LATER
|     #endif
| #endif
| 
| // SunPro does not support C++0x or TR1, they use
| // STLPort4, so we don't need to consider SunPro at all in the following checks
| 
| // Intel icpc may define __clang__ (on Mac OS X, -use-clang-env) or __GNUC__
| // (otherwise)
| // Clang define __GNUC__ as if it is GCC 4.2.1
| // So all checks are in the order Intel -> Clang -> GCC
| 
| // Check C++0x features
| // No longer defines HAS_CXX0X
| // If in future we would like to use more than one C++11 feature, this macro
| // will become a source of pain because the various status of C++11
| // implementation among compilers.
| // Currently it is only used for static_assert, so we just test static_assert
| #if defined(__INTEL_COMPILER)
|     #if __cplusplus >= 201103L
|         // Intel icpc 12.1 support variadic template v0.9
|         // I noticed that previously this macro is defined for GCC 4.3, which
|         // also only support v0.9
|         #if __INTEL_COMPILER >= 1210
|             #define HAS_VARIADIC_TEMPLATES
|         #endif
|         #if __INTEL_COMPILER >= 1100
|             #define HAS_STATIC_ASSERT
|         #endif
|     #endif // __cplusplus >= 201103L
| #elif defined(__clang__)
|     #if __cplusplus >= 201103L
|         #if __has_feature(cxx_variadic_templates)
|             #define HAS_VARIADIC_TEMPLATES
|         #endif
| 
|         #if __has_feature(cxx_static_assert)
|             #define HAS_STATIC_ASSERT
|         #endif
|     #endif // __cplusplus >= 201103L
| #elif defined(__GNUC__)
|     // GCC does not defien __cplusplus >= 201103L until 4.7
|     #ifdef __GXX_EXPERIMENTAL_CXX0X__
|         #if GCC_VERSION >= 40300
|             #define HAS_VARIADIC_TEMPLATES
|             #define HAS_STATIC_ASSERT
|         #endif
|     #endif // __GXX_EXPERIMENTAL_CXX0X_
| #endif
| 
| // Check C++0x headers
| //
| // Intel icpc undef __GXX_EMPERIMENTAL_CXX0X_ for versions of libstdc++
| // that it cannot compile, even -std=c++0x. For example. icpc 12.1 undef
| // this macro for libstdc++ 4.6 and later
| // Note that icpc 13.0 cannot compile all libstdc++ 4.7 though it is
| // officially supported. Update to 13.0 Update 1 solve the problem.
| //
| // Clang is much simpler, just use __has_include
| #include <cmath>
| #if defined(__INTEL_COMPILER) || (defined(__GNUC__) && !defined(__clang__))
|     #if defined(__GXX_EXPERIMENTAL_CXX0X__) && defined(__GLIBCXX__)
|         #if __GLIBCXX__ >= 20090421 // GCC 4.4.0
|             #define HAS_CXX0X_UNORDERED_MAP
|             #define HAS_CXX0X_UNORDERED_SET
|             #define HAS_CXX0X_INITIALIZER_LIST
|         #endif
|     #endif // defined(__GXX_EXPERIMENTAL_CXX0X__) && defined(__GLIBCXX__)
| #elif defined(__clang__)
|     #if __cplusplus >= 201103L
|         #if __has_include(<unordered_map>)
|             #define HAS_CXX0X_UNORDERED_MAP
|         #endif
|         #if __has_include(<unordered_set>)
|             #define HAS_CXX0X_UNORDERED_SET
|         #endif
|         #if __has_include(<initializer_list>)
|             #define HAS_CXX0X_INITIALIZER_LIST
|         #endif
|     #endif // __cplusplus >= 201103L
| #endif
| 
| // Check TR1 Headers
| #if defined(__INTEL_COMPILER) || (defined(__GNUC__) && !defined(__clang__))
|     #if defined(__GLIBCXX__)
|         #if __GLIBCXX__ >= 20070719 // GCC 4.2.1
|             #define HAS_TR1_UNORDERED_MAP
|             #define HAS_TR1_UNORDERED_SET
|         #endif
|     #endif // defined(__GXX_EXPERIMENTAL_CXX0X__) && defined(__GLIBCXX__)
| #elif defined(__clang__)
|     #if __cplusplus >= 201103L
|         #if __has_include(<tr1/unordered_map>)
|             #define HAS_TR1_UNORDERED_MAP
|         #endif
|         #if __has_include(<tr1/unordered_set>)
|             #define HAS_TR1_UNORDERED_SET
|         #endif
|     #endif // __cplusplus >= 201103L
| #endif
| 
| #if defined(HAS_TR1_UNORDERED_MAP) && defined(HAS_TR1_UNORDERED_SET)
| #define HAS_TR1
| #endif
| 
| #include <iterator>
| #include <exception>
| #include <iostream>
| #include <sstream>
| #include <string>
| #include <list>
| #include <map>
| #include <set>
| #include <stdexcept>
| #include <vector>
| #include <deque>
| #include <functional>
| #include <numeric>
| #include <algorithm>
| #include <complex>
| #include <limits>
| #include <typeinfo>
| #include <Rcpp/sprintf.h>
| 
| // Conditionally include headers
| #ifdef HAS_CXX0X_INITIALIZER_LIST
| #include <initializer_list>
| #endif
| 
| #if defined(HAS_CXX0X_UNORDERED_MAP)
|     #include <unordered_map>
|     #define RCPP_UNORDERED_MAP std::unordered_map
| #elif defined(HAS_TR1_UNORDERED_MAP)
|     #include <tr1/unordered_map>
|     #define RCPP_UNORDERED_MAP std::tr1::unordered_map
| #else
|     #include <map>
|     #define RCPP_UNORDERED_MAP std::map
| #endif
| 
| #if defined(HAS_CXX0X_UNORDERED_SET)
|     #include <unordered_set>
|     #define RCPP_UNORDERED_SET std::unordered_set
| #elif defined(HAS_TR1_UNORDERED_SET)
|     #include <tr1/unordered_set>
|     #define RCPP_UNORDERED_SET std::tr1::unordered_set
| #else
|     #include <set>
|     #define RCPP_UNORDERED_SET std::set
| #endif
| 
| std::string demangle( const std::string& name) ;
| #define DEMANGLE(__TYPE__) demangle( typeid(__TYPE__).name() ).c_str() 
| 
| // include R headers, but set R_NO_REMAP and access everything via Rf_ prefixes
| #define R_NO_REMAP
| #include <R.h>
| #include <Rinternals.h>
| #include <R_ext/Callbacks.h>
| #include <R_ext/Complex.h>
| #include <R_ext/Parse.h>
| #include <R_ext/Rdynload.h>
| #include <Rversion.h>
| #define RCPP_GET_NAMES(x)       Rf_getAttrib(x, R_NamesSymbol)
| 
| inline SEXP Rcpp_lcons(SEXP car, SEXP cdr){
|     PROTECT(car) ;
|     car = Rf_lcons( car, cdr ) ; 
|     UNPROTECT(1) ;
|     return car ;
| }
| #include <Rcpp/lang.h>
| 
| #include <Rcpp/complex.h>
| 
| #include <Rcpp/barrier.h>
| 
| #define RcppExport extern "C"
| 
| #include <Rcpp/internal/posixt.h>
| 
| RcppExport void init_Rcpp_routines(DllInfo*) ;
| 
| namespace Rcpp{
|     namespace internal{
|         template <typename T> int rcpp_call_test(T t){
|             return T::r_type::value ;
|         }
|         int rcpp_call_test_(SEXP) ;
|     }
| }
| 
| extern "C" SEXP rcpp_call_test(SEXP x) ;
| 
| /* in exceptions.cpp */
| void forward_uncaught_exceptions_to_r() ;
| void forward_exception_to_r( const std::exception& ) ;
| RcppExport SEXP initUncaughtExceptionHandler() ; 
| 
| /* just testing variadic templates */
| #ifdef HAS_VARIADIC_TEMPLATES
| template<typename... Args>
| int variadic_length( const Args&... args) { return sizeof...(Args) ; }
| #endif
| 
| #ifdef HAS_VARIADIC_TEMPLATES
| RcppExport inline SEXP canUseCXX0X(){ return Rf_ScalarLogical( TRUE ); }
| #else
| RcppExport inline SEXP canUseCXX0X(){ return Rf_ScalarLogical( FALSE ); }
| #endif
| 
| RcppExport SEXP test_named() ;
| RcppExport SEXP capabilities() ;
| 
| const char * sexp_to_name(int sexp_type); 
| 
| #include <Rcpp/exceptions.h>
| 
| namespace Rcpp{
|     /* internal namespace for things not intended to be used by the user */
|     namespace internal{     
|         
|         /* defined in Evaluator.cpp */
|         SEXP convert_using_rfunction(SEXP x, const char* const fun);
|         
|         SEXP try_catch( SEXP expr, SEXP env );
|         SEXP try_catch( SEXP expr );
|         
|     } // namespace internal 
|     
|     inline bool Rboolean_to_bool( int x){ return x == TRUE ; }
|     inline bool int_to_bool(int x){ return x != 0 ; }
|     inline bool double_to_bool(double x){ return x != 0.0 ; }
|     inline bool Rbyte_to_bool(Rbyte x){ return x != static_cast<Rbyte>(0) ; }
| 
| } // namespace Rcpp
| 
| // simple logging help
| #define RCPP_DEBUG_LEVEL 0
| 
| #ifndef logTxt
|     #if RCPP_DEBUG_LEVEL > 0
|         #define logTxt(x) ::logTxtFunction(__FILE__, __LINE__, x);
|     #else
|         #define logTxt(x)
|     #endif
| #endif
| 
| #if RCPP_DEBUG_LEVEL > 0
|     #define RCPP_DEBUG( MSG ) Rprintf( "%s:%d %s\n" , __FILE__, __LINE__, MSG ) ;
|     #define RCPP_DEBUG_1( fmt, MSG ) Rprintf( "%s:%d " fmt "\n" , __FILE__, __LINE__, MSG ) ;
|     #define RCPP_DEBUG_2( fmt, M1, M2 ) Rprintf( "%s:%d" fmt "\n" , __FILE__, __LINE__, M1, M2 ) ;
|     #define RCPP_DEBUG_3( fmt, M1, M2, M3 ) Rprintf( "%s:%d" fmt "\n" , __FILE__, __LINE__, M1, M2, M3) ;
| #else
|     #define RCPP_DEBUG( MSG )
|     #define RCPP_DEBUG_1( fmt, MSG )
|     #define RCPP_DEBUG_2( fmt, M1, M2 )
|     #define RCPP_DEBUG_3( fmt, M1, M2, M3 )
| #endif
| 
| SEXP stack_trace( const char *file, int line) ;
| #define GET_STACKTRACE() stack_trace( __FILE__, __LINE__ )
| #define Rcpp_error(MESSAGE) throw Rcpp::exception( MESSAGE, __FILE__, __LINE__ ) 
| 
| namespace Rcpp {
| 	  inline void stop(const std::string& message) { throw Rcpp::exception(message.c_str()); }
| } // namespace Rcpp
| 
| #if RCPP_DEBUG_LEVEL > 0
|     #include <typeinfo>
| #endif
| 
| #ifdef __GNUC__
| #ifdef __GXX_EXPERIMENTAL_CXX0X__
| #ifdef LONG_LONG_MAX
|     __extension__ typedef long long int rcpp_long_long_type;
|     __extension__ typedef unsigned long long int rcpp_ulong_long_type;
|     #define RCPP_HAS_LONG_LONG_TYPES
| #endif
| #endif
| #endif
| 
| namespace Rcpp{
|     template <typename T> class object ;
| 	namespace internal{
| 		template <typename Class> SEXP make_new_object( Class* ptr ) ;	
| 	}
| }	
| 
| // DO NOT CHANGE THE ORDER OF THESE INCLUDES
| #include <Rcpp/traits/integral_constant.h>
| #include <Rcpp/traits/same_type.h>
| #include <Rcpp/traits/named_object.h>
| #include <Rcpp/Named.h>
| #include <Rcpp/traits/is_convertible.h>
| #include <Rcpp/traits/has_iterator.h>
| #include <Rcpp/traits/expands_to_logical.h>
| #include <Rcpp/traits/matrix_interface.h>
| #include <Rcpp/traits/is_sugar_expression.h>
| #include <Rcpp/traits/is_eigen_base.h>
| #include <Rcpp/traits/has_na.h>
| #include <Rcpp/traits/storage_type.h>
| #include <Rcpp/traits/r_sexptype_traits.h>
| #include <Rcpp/traits/storage_type.h>
| #include <Rcpp/traits/comparator_type.h>
| #include <Rcpp/traits/r_type_traits.h>
| #include <Rcpp/traits/un_pointer.h>
| #include <Rcpp/traits/is_pointer.h>
| #include <Rcpp/traits/wrap_type_traits.h>
| #include <Rcpp/traits/module_wrap_traits.h>
| #include <Rcpp/traits/is_na.h>
| #include <Rcpp/traits/if_.h>
| #include <Rcpp/traits/get_na.h>
| #include <Rcpp/traits/is_trivial.h>
| #include <Rcpp/traits/init_type.h>
| 
| #include <Rcpp/traits/is_const.h>
| #include <Rcpp/traits/is_reference.h>
| #include <Rcpp/traits/remove_const.h>
| #include <Rcpp/traits/remove_reference.h>
| #include <Rcpp/traits/remove_const_and_reference.h>
| #include <Rcpp/traits/result_of.h>
| 
| #include <Rcpp/Generator.h>
| 
| #include <Rcpp/internal/caster.h>
| #include <Rcpp/internal/r_vector.h>
| #include <Rcpp/r_cast.h>
| 
| #include <Rcpp/internal/wrap_forward.h>
| 
| #include <Rcpp/Date_forward.h>
| #include <Rcpp/Datetime_forward.h>
| 
| #include <Rcpp/internal/export.h>
| #include <Rcpp/traits/Exporter.h>
| #include <Rcpp/internal/r_coerce.h>
| #include <Rcpp/as.h>
| 
| #include <Rcpp/vector/VectorBase.h>
| #include <Rcpp/vector/MatrixBase.h>
| 
| #include <Rcpp/internal/wrap.h>
| 
| #include <Rcpp/internal/ListInitialization.h>
| #include <Rcpp/internal/Proxy_Iterator.h>
| #include <Rcpp/internal/SEXP_Iterator.h>
| 
| RcppExport SEXP RcppXPtrExample_create_external_pointer() ;
| RcppExport SEXP RcppXPtrExample_get_external_pointer(SEXP ); 
| 
| #include <Rcpp/preprocessor.h>
| #include <Rcpp/algo.h>
| 
| #include <Rcpp/sugar/sugar_forward.h>
| 
| #include <Rcpp/routines.h>
| #include <Rcpp/cache.h>
| 
| // "Rcout" iostream class contributed by Jelmer Ypma
| #include <Rcpp/iostream/Rstreambuf.h>
| #include <Rcpp/iostream/Rostream.h>
| 
| #endif
| 
| ----------------------------------------------------------------------
| Index: src/RcppCommon.cpp
| ===================================================================
| --- src/RcppCommon.cpp	(revision 4055)
| +++ src/RcppCommon.cpp	(working copy)
| @@ -36,7 +36,7 @@
|  #else
|  	LOGICAL(cap)[0] = FALSE ;
|  #endif
| -#ifdef HAS_INIT_LISTS
| +#ifdef HAS_CXX0X_INITIALIZER_LIST
|  	LOGICAL(cap)[1] = TRUE ;
|  #else
|  	LOGICAL(cap)[1] = FALSE ;
| Index: inst/unitTests/runit.wrap.R
| ===================================================================
| --- inst/unitTests/runit.wrap.R	(revision 4055)
| +++ inst/unitTests/runit.wrap.R	(working copy)
| @@ -142,7 +142,7 @@
|          ## definition of all the tr1 functions at once, appended to existing list
|          g <- list("unordered_map_string_int"=list(
|                    signature(),
| -                  'std::tr1::unordered_map< std::string, int > m ;
| +                  'RCPP_UNORDERED_MAP< std::string, int > m ;
|  	           m["b"] = 100;
|    	           m["a"] = 200;
|    	           m["c"] = 300;
| @@ -150,7 +150,7 @@
|  
|                    ,"unordered_map_string_double"=list(
|                     signature(),
| -                   'std::tr1::unordered_map<std::string,double> m ;
| +                   'RCPP_UNORDERED_MAP<std::string,double> m ;
|  	            m["b"] = 100;
|    	            m["a"] = 200;
|    	            m["c"] = 300;
| @@ -158,7 +158,7 @@
|  
|                    ,"unordered_map_string_bool"=list(
|                     signature(),
| -                   'std::tr1::unordered_map<std::string,bool> m ;
| +                   'RCPP_UNORDERED_MAP<std::string,bool> m ;
|              	    m["b"] = true;
|                	    m["a"] = false;
|                	    m["c"] = true;
| @@ -167,7 +167,7 @@
|  
|                    ,"unordered_map_string_Rbyte"=list(
|                     signature(),
| -                   'std::tr1::unordered_map<std::string,Rbyte> m ;
| +                   'RCPP_UNORDERED_MAP<std::string,Rbyte> m ;
|  	            m["b"] = (Rbyte)0;
|    	            m["a"] = (Rbyte)1;
|    	            m["c"] = (Rbyte)2;
| @@ -175,7 +175,7 @@
|  
|                    ,"unordered_map_string_string"=list(
|                     signature(),
| -                   'std::tr1::unordered_map<std::string,std::string> m ;
| +                   'RCPP_UNORDERED_MAP<std::string,std::string> m ;
|  	            m["b"] = "foo" ;
|    	            m["a"] = "bar" ;
|    	            m["c"] = "bling" ;
| @@ -184,7 +184,7 @@
|  
|                    ,"unordered_map_string_generic"=list(
|                     signature(),
| -                   'std::tr1::unordered_map< std::string,std::vector<int> > m ;
| +                   'RCPP_UNORDERED_MAP< std::string,std::vector<int> > m ;
|  	            std::vector<int> b; b.push_back(1); b.push_back(2); m["b"] = b ;
|    	            std::vector<int> a; a.push_back(1); a.push_back(2); a.push_back(2); m["a"] = a;
|    	            std::vector<int> c; c.push_back(1); c.push_back(2); c.push_back(2); c.push_back(2); m["c"] = c;
| Index: inst/include/RcppCommon.h
| ===================================================================
| --- inst/include/RcppCommon.h	(revision 4055)
| +++ inst/include/RcppCommon.h	(working copy)
| @@ -68,22 +68,6 @@
|  
|  #ifdef __GNUC__
|      #define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
| -    #ifdef __GXX_EXPERIMENTAL_CXX0X__
| -        #define HAS_CXX0X
| -        #if GCC_VERSION >= 40300
| -            #define HAS_VARIADIC_TEMPLATES
| -        #endif
| -        #if GCC_VERSION >= 40400
| -            #define HAS_INIT_LISTS
| -        #endif
| -    #endif
| -    // FIXME: [romain] I did not actually check, tr1::unordered_map was 
| -    // probably introduced before GCC 4.2.1
| -    #if GCC_VERSION >= 40201
| -        #define HAS_TR1
| -        #define HAS_TR1_UNORDERED_MAP
| -        #define HAS_TR1_UNORDERED_SET
| -    #endif
|      // g++ 4.5 does not seem to like some of the fast indexing
|      #if GCC_VERSION >= 40500
|          #define IS_GCC_450_OR_LATER
| @@ -97,46 +81,107 @@
|      #endif
|  #endif
|  
| -// #ifdef __clang__
| -//     #define CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__)
| -//     #if CLANG_VERSION < 30000
| -//         #define IS_EARLIER_THAN_CLANG_300
| -//     #endif
| -//     #if CLANG_VERSION >= 30000
| -//         #define IS_CLANG_300_OR_LATER
| -//     #endif
| -// #endif
| +// SunPro does not support C++0x or TR1, they use
| +// STLPort4, so we don't need to consider SunPro at all in the following checks
|  
| -// This definition was contributed by Yan Zhou
| -#ifdef __clang__
| -    #if !__has_include(<tr1/unordered_map>)
| -        #undef HAS_TR1
| -        #undef HAS_TR1_UNORDERED_MAP
| -    #endif
| -    #if !__has_include(<tr1/unordered_set>)
| -        #undef HAS_TR1
| -        #undef HAS_TR1_UNORDERED_SET
| -    #endif
| -    #if __has_feature(cxx_variadic_templates)
| -        #define HAS_VARIADIC_TEMPLATES
| -    #endif
| +// Intel icpc may define __clang__ (on Mac OS X, -use-clang-env) or __GNUC__
| +// (otherwise)
| +// Clang define __GNUC__ as if it is GCC 4.2.1
| +// So all checks are in the order Intel -> Clang -> GCC
| +
| +// Check C++0x features
| +// No longer defines HAS_CXX0X
| +// If in future we would like to use more than one C++11 feature, this macro
| +// will become a source of pain because the various status of C++11
| +// implementation among compilers.
| +// Currently it is only used for static_assert, so we just test static_assert
| +#if defined(__INTEL_COMPILER)
| +    #if __cplusplus >= 201103L
| +        // Intel icpc 12.1 support variadic template v0.9
| +        // I noticed that previously this macro is defined for GCC 4.3, which
| +        // also only support v0.9
| +        #if __INTEL_COMPILER >= 1210
| +            #define HAS_VARIADIC_TEMPLATES
| +        #endif
| +        #if __INTEL_COMPILER >= 1100
| +            #define HAS_STATIC_ASSERT
| +        #endif
| +    #endif // __cplusplus >= 201103L
| +#elif defined(__clang__)
| +    #if __cplusplus >= 201103L
| +        #if __has_feature(cxx_variadic_templates)
| +            #define HAS_VARIADIC_TEMPLATES
| +        #endif
| +
| +        #if __has_feature(cxx_static_assert)
| +            #define HAS_STATIC_ASSERT
| +        #endif
| +    #endif // __cplusplus >= 201103L
| +#elif defined(__GNUC__)
| +    // GCC does not defien __cplusplus >= 201103L until 4.7
| +    #ifdef __GXX_EXPERIMENTAL_CXX0X__
| +        #if GCC_VERSION >= 40300
| +            #define HAS_VARIADIC_TEMPLATES
| +            #define HAS_STATIC_ASSERT
| +        #endif
| +    #endif // __GXX_EXPERIMENTAL_CXX0X_
|  #endif
|  
| -#ifdef __INTEL_COMPILER
| -    // This is based on an email by Alexey Stukalov who tested 
| -    // Intel Compiler 12.0 and states that is does support Cxx0x 
| -    // or even TR1 (by default; maybe there are options?)
| -    // Extended further via patch in email by Yan Zhou
| -    #undef HAS_VARIADIC_TEMPLATES
| -    #include <cmath>
| -    #ifndef __GLIBCXX__
| -    #undef HAS_TR1
| -    #undef HAS_TR1_UNORDERED_MAP
| -    #undef HAS_TR1_UNORDERED_SET
| -    #endif
| +// Check C++0x headers
| +//
| +// Intel icpc undef __GXX_EMPERIMENTAL_CXX0X_ for versions of libstdc++
| +// that it cannot compile, even -std=c++0x. For example. icpc 12.1 undef
| +// this macro for libstdc++ 4.6 and later
| +// Note that icpc 13.0 cannot compile all libstdc++ 4.7 though it is
| +// officially supported. Update to 13.0 Update 1 solve the problem.
| +//
| +// Clang is much simpler, just use __has_include
| +#include <cmath>
| +#if defined(__INTEL_COMPILER) || (defined(__GNUC__) && !defined(__clang__))
| +    #if defined(__GXX_EXPERIMENTAL_CXX0X__) && defined(__GLIBCXX__)
| +        #if __GLIBCXX__ >= 20090421 // GCC 4.4.0
| +            #define HAS_CXX0X_UNORDERED_MAP
| +            #define HAS_CXX0X_UNORDERED_SET
| +            #define HAS_CXX0X_INITIALIZER_LIST
| +        #endif
| +    #endif // defined(__GXX_EXPERIMENTAL_CXX0X__) && defined(__GLIBCXX__)
| +#elif defined(__clang__)
| +    #if __cplusplus >= 201103L
| +        #if __has_include(<unordered_map>)
| +            #define HAS_CXX0X_UNORDERED_MAP
| +        #endif
| +        #if __has_include(<unordered_set>)
| +            #define HAS_CXX0X_UNORDERED_SET
| +        #endif
| +        #if __has_include(<initializer_list>)
| +            #define HAS_CXX0X_INITIALIZER_LIST
| +        #endif
| +    #endif // __cplusplus >= 201103L
|  #endif
|  
| +// Check TR1 Headers
| +#if defined(__INTEL_COMPILER) || (defined(__GNUC__) && !defined(__clang__))
| +    #if defined(__GLIBCXX__)
| +        #if __GLIBCXX__ >= 20070719 // GCC 4.2.1
| +            #define HAS_TR1_UNORDERED_MAP
| +            #define HAS_TR1_UNORDERED_SET
| +        #endif
| +    #endif // defined(__GXX_EXPERIMENTAL_CXX0X__) && defined(__GLIBCXX__)
| +#elif defined(__clang__)
| +    #if __cplusplus >= 201103L
| +        #if __has_include(<tr1/unordered_map>)
| +            #define HAS_TR1_UNORDERED_MAP
| +        #endif
| +        #if __has_include(<tr1/unordered_set>)
| +            #define HAS_TR1_UNORDERED_SET
| +        #endif
| +    #endif // __cplusplus >= 201103L
| +#endif
|  
| +#if defined(HAS_TR1_UNORDERED_MAP) && defined(HAS_TR1_UNORDERED_SET)
| +#define HAS_TR1
| +#endif
| +
|  #include <iterator>
|  #include <exception>
|  #include <iostream>
| @@ -156,31 +201,31 @@
|  #include <typeinfo>
|  #include <Rcpp/sprintf.h>
|  
| -#ifdef HAS_INIT_LISTS
| +// Conditionally include headers
| +#ifdef HAS_CXX0X_INITIALIZER_LIST
|  #include <initializer_list>
|  #endif
|  
| -#ifdef HAS_TR1_UNORDERED_MAP
| -#include <tr1/unordered_map>
| +#if defined(HAS_CXX0X_UNORDERED_MAP)
| +    #include <unordered_map>
| +    #define RCPP_UNORDERED_MAP std::unordered_map
| +#elif defined(HAS_TR1_UNORDERED_MAP)
| +    #include <tr1/unordered_map>
| +    #define RCPP_UNORDERED_MAP std::tr1::unordered_map
| +#else
| +    #include <map>
| +    #define RCPP_UNORDERED_MAP std::map
|  #endif
|  
| -#ifdef HAS_TR1_UNORDERED_SET
| -#include <tr1/unordered_set>
| -#endif
| -
| -
| -#if __cplusplus >= 201103L
| -    #if defined(__GLIBCXX__) && __GLIBCXX__ > 20090421
| -    #include <unordered_map>
| +#if defined(HAS_CXX0X_UNORDERED_SET)
|      #include <unordered_set>
| -    #elif defined(__clang__)
| -        #if __has_include(<unordered_map>)
| -        #include <unordered_map>
| -        #endif
| -        #if __has_include(<unordered_set>)
| -        #include <unordered_set>
| -        #endif
| -    #endif
| +    #define RCPP_UNORDERED_SET std::unordered_set
| +#elif defined(HAS_TR1_UNORDERED_SET)
| +    #include <tr1/unordered_set>
| +    #define RCPP_UNORDERED_SET std::tr1::unordered_set
| +#else
| +    #include <set>
| +    #define RCPP_UNORDERED_SET std::set
|  #endif
|  
|  std::string demangle( const std::string& name) ;
| Index: inst/include/Rcpp/vector/Vector.h
| ===================================================================
| --- inst/include/Rcpp/vector/Vector.h	(revision 4055)
| +++ inst/include/Rcpp/vector/Vector.h	(working copy)
| @@ -263,7 +263,7 @@
|          RObject::setSEXP( internal::vector_from_string<RTYPE>(st) );
|      }
|  	
| -#ifdef HAS_INIT_LISTS
| +#ifdef HAS_CXX0X_INITIALIZER_LIST
|      Vector( std::initializer_list<init_type> list ) : RObject(){
|          assign( list.begin() , list.end() ) ;
|      }
| Index: inst/include/Rcpp/internal/wrap.h
| ===================================================================
| --- inst/include/Rcpp/internal/wrap.h	(revision 4055)
| +++ inst/include/Rcpp/internal/wrap.h	(working copy)
| @@ -426,7 +426,7 @@
|  template <typename T>
|  inline SEXP wrap_dispatch_unknown_iterable(const T& object, ::Rcpp::traits::false_type){
|  	// here we know that T is not convertible to SEXP
| -#ifdef HAS_CXX0X
| +#ifdef HAS_STATIC_ASSERT
|  	static_assert( !sizeof(T), "cannot convert type to SEXP" ) ;
|  #else
|  	// leave the cryptic message
| Index: inst/include/Rcpp/sugar/sugar.h
| ===================================================================
| --- inst/include/Rcpp/sugar/sugar.h	(revision 4055)
| +++ inst/include/Rcpp/sugar/sugar.h	(working copy)
| @@ -22,7 +22,6 @@
|  #ifndef RCPP_SUGAR_H
|  #define RCPP_SUGAR_H
|  
| -#include <Rcpp/sugar/sets.h>
|  #include <Rcpp/sugar/tools/iterator.h>
|  #include <Rcpp/sugar/block/block.h>
|  

-- 
Dirk Eddelbuettel | edd at debian.org | http://dirk.eddelbuettel.com  


More information about the Rcpp-devel mailing list