[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