[Rcpp-commits] r4069 - pkg/contributedPatches

noreply at r-forge.r-project.org noreply at r-forge.r-project.org
Tue Dec 4 04:15:46 CET 2012


Author: edd
Date: 2012-12-04 04:15:46 +0100 (Tue, 04 Dec 2012)
New Revision: 4069

Added:
   pkg/contributedPatches/Yan.Zhou.c++11.2012-12-03.patch
Log:
patch corresponding to rev 4068


Added: pkg/contributedPatches/Yan.Zhou.c++11.2012-12-03.patch
===================================================================
--- pkg/contributedPatches/Yan.Zhou.c++11.2012-12-03.patch	                        (rev 0)
+++ pkg/contributedPatches/Yan.Zhou.c++11.2012-12-03.patch	2012-12-04 03:15:46 UTC (rev 4069)
@@ -0,0 +1,548 @@
+From: Yan Zhou <zhouyan at me.com>
+To: Yan Zhou <zhouyan at me.com>
+Cc: Dirk Eddelbuettel <edd at debian.org>,
+ rcpp-devel <rcpp-devel at lists.r-forge.r-project.org>
+Subject: Re: [Rcpp-devel] Patch for using Rcpp with proper check of TR1/C++11
+ headers
+Date: Mon, 03 Dec 2012 06:11:51 +0000 (GMT)
+
+Hi Dirk,
+
+Here is a more detailed summary of the change and some test results
+
+Things affected by the change
+=============================
+
+* The use of <initializer_list>, <unordered_map> and <unordered_set> header
+* The use C++11 static assert and variadic template
+
+Things work before the change
+=============================
+
+GCC, Clang, Intel, SunPro in C++98 mode
+TR1 headers are used if some macros defined, otherwise ordered map and set are
+used.
+
+Earlier GCC in C++0x mode (up to version 4.6 series)
+
+Things do not work before the change
+====================================
+
+Any compiler with __cplusplus >= 201103L, Clang, Intel, GCC 4.7 with -std=c++0x
+This is due to the fact that Rcpp/sugar/sets.h has the following code
+
+#if __cplusplus >= 201103L
+    #define RCPP_UNORDERED_SET std::unordered_set
+    #define RCPP_UNORDERED_MAP std::unordered_map
+#elif defined(HAS_TR1_UNORDERED_SET)
+    #define RCPP_UNORDERED_SET std::tr1::unordered_set
+    #define RCPP_UNORDERED_MAP std::tr1::unordered_map
+#else
+    #define RCPP_UNORDERED_SET std::set
+    #define RCPP_UNORDERED_MAP std::map
+#endif
+
+while C++11 <unordered_map> and <unordered_set> are not included anywhere
+
+Clang with libc++
+Similar reasons. libc++ does not provide TR1 headers but only C++98 and C++11
+headers
+
+The change
+==========
+
+If the compiler is in a C++0x/11 mode, (-std=c++0x, or -std=c++11), then choose
+<unordered_map> and <unordered_set> if possible. Otherwise choose <map> and
+<set>
+
+If the compiler is in a C++98 mode, (usually the default), then choose
+<tr1/unordered_map> and <tr1/unordered_set> if possible. Otherwise choose <map>
+and <set>
+
+We do not try to choose TR1 headers in C++11 mode. Some testing shows very
+wired errors in this combinations when using intel compilers.
+
+However, the GCC is an exception. Even when in C++11 mode, GCC will always try
+to use TR1 headers instead of C++11 headers. This is for backward
+compatibility, to void breaking of ABI. If this is not desired, remove the
+comment before #define HAS_CXX0X_FLAG in the following (line 107)
+
+...
+#elif defined(__GNUC__)
+    #ifdef __GXX_EXPERIMENTAL_CXX0X__
+        // #define HAS_CXX0X_FLAG
+        #if GCC_VERSION >= 40300
+            // #define HAS_VARIADIC_TEMPLATES
+            #define HAS_STATIC_ASSERT
+        #endif
+    #endif
+#endif
+...
+
+C++11 static assert feature is properly tested for the four
+GOOD_COMPILER_FOR_RCPP.
+
+C++11 variadic templates are disabled for all compilers. This clearly does not
+affect C++98 implementation. In C++11 mode, when this feature is enabled, my
+test results showed some wired error emitted from basename, which was called by
+sourceCppContext. This may need some further investigation. I believe this is
+not due to the change made here. The compilers I tried was Intel icpc 13, GCC
+4.6 and 4.7. They all have the same problem when variadic templates are
+enabled.
+
+C++11 <initializer_list> is also properly tested for each of the four compilers
+
+A small glitch in Rcpp/traits/comparator_type.h is fixed. This is found when
+running the Unit tests with Clang, which somehow is more strict than GCC.
+
+Things work the same way before AND after the change
+=====================================================
+
+The four compilers in C++98 mode
+The ABI shall be unchanged for these situations. At least this is the
+intention, everything depend on Rcpp shall not need to be rebuilt. But maybe
+some carelessness invalidate this claim. More testing on this front are needed.
+
+Things break before still break anyway.
+
+Things work after the change BUT not before
+===========================================
+
+Clang with libc++ in C++98 and C++11 mode, -std=c++98 or -std=c++0x;
+-stdlib=libc++
+
+Intel icpc in C++11 mode, -std=c++0x
+
+GCC 4.7 in C++11 mode, -std=c++0x
+
+Compilers tested
+================
+
+The following are compilers tested, within each paragraph, the first line is
+compiler version and platform. The second and third lines are the C and C++
+compilers and flags used when building R. The R configure script may add
+additional flags like -std=gnu99. Building R only uses the C compiler and C
+flags. However the configure script capture the C++ compiler and flags for use
+when, e.g., R CMD INSTALL Rcpp
+
+All tests are peformed with R 2.15.2 patched
+
+Mac OS X Mountain Lion 10.8.2, Xcode 4.5.2, clang 4.1 (based on LLVM 3.1svn)
+clang
+clang++ -std=c++98 -stdlib=libc++
+
+Mac OS X Mountain Lion 10.8.2, Xcode 4.5.2, clang 4.1 (based on LLVM 3.1svn)
+clang
+clang++ -std=c++11 -stdlib=libc++
+
+Mac OS X Mountain Lion 10.8.2, Xcode 4.5.2, clang 4.1 (based on LLVM 3.1svn)
+clang
+clang++ -std=c++98 -stdlib=libstdc++
+
+Mac OS X Mountain Lion 10.8.2, Xcode 4.5.2, clang 4.1 (based on LLVM 3.1svn)
+clang
+clang++ -std=c++11 -stdlib=libstdc++
+
+The official build of R on Mac OS X use GCC 4.2.1 on Mac OS X Leopard, which is
+a legacy system I don't have access any more.
+
+Ubuntu 12.10 Intel C++ 13.0.1
+icc -std=gnu99 -gcc-name=gcc-4.7 -fp-model strict
+icpc -std=c++98 -gcc-name=gcc-4.7 -gxx-name=g++-4.7 -fp-model strict
+
+Ubuntu 12.10 Intel C++ 13.0.1
+icc -std=gnu99 -gcc-name=gcc-4.7 -fp-model strict
+icpc -std=c++11 -gcc-name=gcc-4.7 -gxx-name=g++-4.7 -fp-model strict
+
+Ubuntu 12.10 GCC 4.7.2
+gcc
+g++ -std=c++98
+
+Ubuntu 12.10 GCC 4.7.2
+gcc
+g++ -std=c++11
+
+Test results
+============
+
+Rcpp Unit Test
+--------------
+
+The following are the Rcpp Unit Test results for the tested compilers above.
+The links are named as platform-C++Compiler-std=Lang.html
+
+http://www.yan-zhou.com/rcppunit/mac-clang++-std=c++98-stdlib=libstdc++.html
+http://www.yan-zhou.com/rcppunit/mac-clang++-std=c++98-stdlib=libc++.html
+http://www.yan-zhou.com/rcppunit/mac-clang++-std=c++11-stdlib=libstdc++.html
+http://www.yan-zhou.com/rcppunit/mac-clang++-std=c++11-stdlib=libc++.html
+http://www.yan-zhou.com/rcppunit/linux-icpc-std=c++98.html
+http://www.yan-zhou.com/rcppunit/linux-icpc-std=c++11.html
+http://www.yan-zhou.com/rcppunit/linux-g++-std=c++98.html
+http://www.yan-zhou.com/rcppunit/linux-g++-std=c++11.html
+
+As shown in those pages, most compilers works well. With Intel Compiler and
+Clang with libc++, in C++11 mode, two tests fails. These may need some further
+investigation. It could be problems with compiler or the code in Rcpp. Either
+way, since these compilers do no work at all previously, I consider this a
+improvement.
+
+Rcpp and RInside examples
+-------------------------
+
+These all works well without any problem as far as I can tell
+
+Packages distributed in Rcpp SVN repository
+-------------------------------------------
+
+RcppCImg, RcppModels cannot compile due to some C++ issues. I believe they are
+not due to the changes as the same error happens when using GCC and a SVN
+version of Rcpp without the changes. RcppParDE has some dependencies I cannot
+find.
+
+When using Clang on Mac OS X without libc++ but using -std=c++11, RcppEigen and
+RcppArmadillo failed to build. However those are due the two libraries made
+some wrong assumption about the existence of some C++11 headers. With clang
+-std=c++11-stdlib=libstdc++ on Mac OS X, __cplusplus test will give the wrong
+impression that C++11 is supported, while the libstdc++ on Mac OS X is still
+the GCC 4.2.1 version, which does not have any C++11 support. These issues
+shall be fixed in the upstream projects rather than within Rcpp.
+
+Other packages build successfully and examples work well.
+
+Packages depend on Rcpp
+-----------------------
+
+There are about 90 such packages. Most of them built well. But more tests are
+needed.
+
+Best,
+
+Yan Zhou
+
+----------------------------------------------------------------------
+Index: pkg/Rcpp/inst/include/RcppCommon.h
+===================================================================
+--- pkg/Rcpp/inst/include/RcppCommon.h	(revision 4055)
++++ pkg/Rcpp/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,84 @@
+     #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
+-
+-// This definition was contributed by Yan Zhou
+-#ifdef __clang__
+-    #if !__has_include(<tr1/unordered_map>)
+-        #undef HAS_TR1
+-        #undef HAS_TR1_UNORDERED_MAP
++// Check C++0x features
++#if defined(__INTEL_COMPILER)
++    #if __cplusplus >= 201103L
++        #define HAS_CXX0X_FLAG
++        #if __INTEL_COMPILER >= 1210
++            // #define HAS_VARIADIC_TEMPLATES
++        #endif
++        #if __INTEL_COMPILER >= 1100
++            #define HAS_STATIC_ASSERT
++        #endif
+     #endif
+-    #if !__has_include(<tr1/unordered_set>)
+-        #undef HAS_TR1
+-        #undef HAS_TR1_UNORDERED_SET
++#elif defined(__clang__)
++    #if __cplusplus >= 201103L
++        #define HAS_CXX0X_FLAG
++        #if __has_feature(cxx_variadic_templates)
++            // #define HAS_VARIADIC_TEMPLATES
++        #endif
++        #if __has_feature(cxx_static_assert)
++            #define HAS_STATIC_ASSERT
++        #endif
+     #endif
+-    #if __has_feature(cxx_variadic_templates)
+-        #define HAS_VARIADIC_TEMPLATES
++#elif defined(__GNUC__)
++    #ifdef __GXX_EXPERIMENTAL_CXX0X__
++        // #define HAS_CXX0X_FLAG
++        #if GCC_VERSION >= 40300
++            // #define HAS_VARIADIC_TEMPLATES
++            #define HAS_STATIC_ASSERT
++        #endif
+     #endif
+ #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
++// Check C++0x headers
++#include <cmath>
++#if defined(__INTEL_COMPILER) || (defined(__GNUC__) && !defined(__clang__))
++    #if defined(__GLIBCXX__) && defined(__GXX_EXPERIMENTAL_CXX0X__)
++        #if __GLIBCXX__ >= 20090421 // GCC 4.4.0
++            #define HAS_CXX0X_UNORDERED_MAP
++            #define HAS_CXX0X_UNORDERED_SET
++            #define HAS_CXX0X_INITIALIZER_LIST
++        #endif
+     #endif
++#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
+ #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
++#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
++#endif
+ 
++#if defined(HAS_TR1_UNORDERED_MAP) && defined(HAS_TR1_UNORDERED_SET)
++#define HAS_TR1
++#endif
++
+ #include <iterator>
+ #include <exception>
+ #include <iostream>
+@@ -156,31 +178,41 @@
+ #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>
+-#endif
+-
+-#ifdef HAS_TR1_UNORDERED_SET
+-#include <tr1/unordered_set>
+-#endif
+-
+-
+-#if __cplusplus >= 201103L
+-    #if defined(__GLIBCXX__) && __GLIBCXX__ > 20090421
+-    #include <unordered_map>
+-    #include <unordered_set>
+-    #elif defined(__clang__)
+-        #if __has_include(<unordered_map>)
++#ifdef HAS_CXX0X_FLAG
++    #if defined(HAS_CXX0X_UNORDERED_MAP)
+         #include <unordered_map>
+-        #endif
+-        #if __has_include(<unordered_set>)
++        #define RCPP_UNORDERED_MAP std::unordered_map
++    #else
++        #include <map>
++        #define RCPP_UNORDERED_MAP std::map
++    #endif
++    #if defined(HAS_CXX0X_UNORDERED_SET)
+         #include <unordered_set>
+-        #endif
++        #define RCPP_UNORDERED_SET std::unordered_set
++    #else
++        #include <set>
++        #define RCPP_UNORDERED_SET std::set
+     #endif
++#else
++    #if 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_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
+ #endif
+ 
+ std::string demangle( const std::string& name) ;
+Index: pkg/Rcpp/inst/include/Rcpp/vector/Vector.h
+===================================================================
+--- pkg/Rcpp/inst/include/Rcpp/vector/Vector.h	(revision 4055)
++++ pkg/Rcpp/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: pkg/Rcpp/inst/include/Rcpp/sugar/sugar.h
+===================================================================
+--- pkg/Rcpp/inst/include/Rcpp/sugar/sugar.h	(revision 4055)
++++ pkg/Rcpp/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>
+ 
+Index: pkg/Rcpp/inst/include/Rcpp/internal/wrap.h
+===================================================================
+--- pkg/Rcpp/inst/include/Rcpp/internal/wrap.h	(revision 4055)
++++ pkg/Rcpp/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: pkg/Rcpp/inst/include/Rcpp/traits/comparator_type.h
+===================================================================
+--- pkg/Rcpp/inst/include/Rcpp/traits/comparator_type.h	(revision 4055)
++++ pkg/Rcpp/inst/include/Rcpp/traits/comparator_type.h	(working copy)
+@@ -28,7 +28,7 @@
+    
+ class StringCompare {
+ public:
+-    inline bool operator()( SEXP x, SEXP y){
++    inline bool operator()( SEXP x, SEXP y) const {
+         return strcmp( char_nocheck(x), char_nocheck(y) ) < 0 ; 
+     }
+ } ;
+Index: pkg/Rcpp/inst/unitTests/runit.wrap.R
+===================================================================
+--- pkg/Rcpp/inst/unitTests/runit.wrap.R	(revision 4055)
++++ pkg/Rcpp/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: pkg/Rcpp/src/RcppCommon.cpp
+===================================================================
+--- pkg/Rcpp/src/RcppCommon.cpp	(revision 4055)
++++ pkg/Rcpp/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 ;



More information about the Rcpp-commits mailing list