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

Yan Zhou zhouyan at me.com
Sun Dec 2 17:40:51 CET 2012


Hi Dirk,

I thought I have canceled the old post but provided the new one that is almost identical but with a smaller size. I inadvertently replied to you only, that wasn't the intention anyway.

I think I can test the case of clang 3.2, intel 13.0 on Mac OS X and Linux, also the official build release version of R (namely using GCC) on the three platforms. How about we put these changes aside for now. I will come back about it after I have done proper testings. 

About the change of ABI, I think there maybe a workaround. Namely we try TR1 first and then C++0x header. But still there is no guarantee that the ABI will not be changed in that case. I will think about this through more carefully. Be honest, I didn't think about it before and indeed, it is a situation that best to be avoided.

Best,

Yan

On Dec 2, 2012, at 2:50 PM, Dirk Eddelbuettel <edd at debian.org> wrote:

> 
> 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 (intadvertently) 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