Skip to content

Commit 257e197

Browse files
authored
Header cleanup with C++11 as a baseline (#1364)
* First step of simplifying compiler checks There is more that can be done but each removal of a #DEFINE needs to check exactly where it is used. The bottom part of compiler.h still spans a grid over C++0x/TR1 to see if unordered map and set are a given (as in C++11 or later) which together with other calls of 'C++11 it is now' can simplify but we need to carefully walk this through the rest of the code and not just delete here as we'd keep unnecessary #define 'orphans' around. * Do not rely on __has_feature() for g++ Given that we test for C++11 we can assume variadic templates and just use the #define. Can likely be generalized to icc and clang too. * Expand macos matrix to macos-13, simplify via r-ci with bootstrap * No longer provide fallback for unordered_{set,map} which are given Removes one if/else use in table.h for map, none for set * Further cleanup * Reduced compiler.h to about a page of mostly defines and includes * Additional simplification, and typo fix * Remove HAS_STATIC_ASSERT define and simplify at its sole use * Reflect code review comments * Following rebase roll micro release and date, update ChangeLog * Remove remaining stray HAS_CXX0X_INITIALIZER_LIST
1 parent 0905d92 commit 257e197

File tree

13 files changed

+90
-332
lines changed

13 files changed

+90
-332
lines changed

.github/workflows/macos.yaml

+3-5
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ jobs:
1414
strategy:
1515
matrix:
1616
include:
17-
- {os: macOS-latest}
17+
- {os: macos-latest}
18+
- {os: macos-13}
1819
#- {os: ubuntu-latest}
1920

2021
runs-on: ${{ matrix.os }}
@@ -24,10 +25,7 @@ jobs:
2425
uses: actions/checkout@v4
2526

2627
- name: Setup
27-
uses: eddelbuettel/github-actions/r-ci-setup@master
28-
29-
- name: Bootstrap
30-
run: ./run.sh bootstrap
28+
uses: eddelbuettel/github-actions/r-ci@master
3129

3230
- name: Dependencies
3331
run: ./run.sh install_deps

ChangeLog

+16
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,19 @@
1+
2025-03-15 Dirk Eddelbuettel <[email protected]>
2+
3+
* DESCRIPTION (Version, Date): Roll micro version and date
4+
* inst/include/Rcpp/config.h: Idem
5+
6+
* inst/include/Rcpp/platform/compiler.h: Simplified and shortened
7+
establishing C++11 as baseline; further PRs to complete this
8+
* inst/include/Rcpp/String.h: Unconditionally use std::hash with C++11
9+
* inst/include/Rcpp/wrap.h: Unconditionally use static_assert
10+
* inst/include/Rcpp/sugar/functions/sapply.h: Use std::result_of
11+
(with C++11 or C++14) or std::invoke_result (C++17 or later)
12+
* inst/include/Rcpp/sugar/functions/table.h: Use std::map
13+
* inst/include/Rcpp/sugar/sets.h: Use std::unordered_{set,map}
14+
* man/evalCpp.Rd: Update example
15+
* src/api.cpp: Simplify rcpp_capabilities assignment
16+
117
2025-03-13 Dirk Eddelbuettel <[email protected]>
218

319
* DESCRIPTION (Version, Date): Roll micro version and date

DESCRIPTION

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Package: Rcpp
22
Title: Seamless R and C++ Integration
3-
Version: 1.0.14.6
4-
Date: 2025-03-13
3+
Version: 1.0.14.7
4+
Date: 2025-03-15
55
Authors@R: c(person("Dirk", "Eddelbuettel", role = c("aut", "cre"), email = "[email protected]",
66
comment = c(ORCID = "0000-0001-6419-907X")),
77
person("Romain", "Francois", role = "aut",

inst/include/Rcpp/String.h

+3-13
Original file line numberDiff line numberDiff line change
@@ -734,24 +734,14 @@ namespace Rcpp {
734734

735735
} // Rcpp
736736

737-
/** hash can be in std or std::tr1 */
738-
#if defined(RCPP_USING_CXX11) || defined(HAS_TR1)
739-
namespace std
740-
{
741-
#ifndef RCPP_USING_CXX11
742-
namespace tr1 {
743-
#endif
737+
/** hash via std */
738+
namespace std {
744739
template <>
745-
struct hash<Rcpp::String>
746-
{
740+
struct hash<Rcpp::String> {
747741
size_t operator()(const Rcpp::String & s) const{
748742
return hash<string>()(s.get_cstring());
749743
}
750744
};
751-
#ifndef RCPP_USING_CXX11
752-
}
753-
#endif
754745
}
755-
#endif
756746

757747
#endif

inst/include/Rcpp/config.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
#define RCPP_VERSION_STRING "1.0.14"
3131

3232
// the current source snapshot (using four components, if a fifth is used in DESCRIPTION we ignore it)
33-
#define RCPP_DEV_VERSION RcppDevVersion(1,0,14,6)
34-
#define RCPP_DEV_VERSION_STRING "1.0.14.6"
33+
#define RCPP_DEV_VERSION RcppDevVersion(1,0,14,7)
34+
#define RCPP_DEV_VERSION_STRING "1.0.14.7"
3535

3636
#endif

inst/include/Rcpp/internal/wrap.h

+7-13
Original file line numberDiff line numberDiff line change
@@ -522,18 +522,12 @@ namespace Rcpp {
522522
* quite a cryptic message
523523
*/
524524
template <typename T>
525-
inline SEXP wrap_dispatch_unknown_iterable(const T& object, ::Rcpp::traits::false_type) {
526-
RCPP_DEBUG_1("wrap_dispatch_unknown_iterable<%s>(., false )", DEMANGLE(T))
527-
// here we know that T is not convertible to SEXP
528-
#ifdef HAS_STATIC_ASSERT
529-
static_assert(!sizeof(T), "cannot convert type to SEXP");
530-
#else
531-
// leave the cryptic message
532-
SEXP x = object;
533-
return x;
534-
#endif
535-
return R_NilValue; // -Wall
536-
}
525+
inline SEXP wrap_dispatch_unknown_iterable(const T& object, ::Rcpp::traits::false_type) {
526+
RCPP_DEBUG_1("wrap_dispatch_unknown_iterable<%s>(., false )", DEMANGLE(T))
527+
// here we know that T is not convertible to SEXP
528+
static_assert(!sizeof(T), "cannot convert type to SEXP");
529+
return R_NilValue; // -Wall
530+
}
537531

538532
template <typename T>
539533
inline SEXP wrap_dispatch_unknown_iterable__logical(const T& object, ::Rcpp::traits::true_type) {
@@ -936,7 +930,7 @@ namespace Rcpp {
936930
if (v != NULL)
937931
return Rf_mkString(v);
938932
else
939-
return R_NilValue; // #nocov
933+
return R_NilValue; // #nocov
940934
}
941935

942936
/**

inst/include/Rcpp/platform/compiler.h

+18-163
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
1-
// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*-
2-
//
31
// compiler.h: Rcpp R/C++ interface class library -- check compiler
42
//
5-
// Copyright (C) 2012 - 2013 Dirk Eddelbuettel, Romain Francois, and Kevin Ushey
3+
// Copyright (C) 2012 - 2025 Dirk Eddelbuettel, Romain Francois, and Kevin Ushey
64
//
75
// This file is part of Rcpp.
86
//
@@ -24,173 +22,30 @@
2422

2523
// NB: A vast list valid identifiers is at these wiki pages:
2624
// http://sourceforge.net/p/predef/wiki/Home/
27-
28-
#undef GOOD_COMPILER_FOR_RCPP
29-
#ifdef __GNUC__
30-
#define GOOD_COMPILER_FOR_RCPP
31-
#endif
32-
#ifdef __SUNPRO_CC
33-
#define GOOD_COMPILER_FOR_RCPP
34-
#endif
35-
#ifdef __clang__
36-
#define GOOD_COMPILER_FOR_RCPP
37-
#endif
38-
#ifdef __INTEL_COMPILER
39-
#define GOOD_COMPILER_FOR_RCPP
40-
#endif
41-
42-
#ifndef GOOD_COMPILER_FOR_RCPP
43-
# error "This compiler is not supported"
44-
#endif
45-
46-
#ifdef __GNUC__
47-
#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
48-
// g++ 4.5 does not seem to like some of the fast indexing
49-
#if GCC_VERSION >= 40500
50-
#define IS_GCC_450_OR_LATER
51-
#endif
52-
// g++ 4.6 switches from exception_defines.h to bits/exception_defines.h
53-
#if GCC_VERSION < 40600
54-
#define IS_EARLIER_THAN_GCC_460
55-
#endif
56-
#if GCC_VERSION >= 40600
57-
#define IS_GCC_460_OR_LATER
58-
#endif
59-
#endif
60-
61-
// Check for the presence of C++0x (or later) support
62-
#if defined(__GXX_EXPERIMENTAL_CXX0X__) || (__cplusplus >= 201103L)
63-
#define RCPP_USING_CXX0X_OR_LATER
25+
#if !defined(__GNUC__) && !defined(__SUNPRO_CC) && !defined(__clang__) && !defined(__INTEL_COMPILER)
26+
#error "This compiler is not supported"
6427
#endif
6528

66-
// Check C++0x/11 features
67-
#if defined(__INTEL_COMPILER)
68-
#if __cplusplus >= 201103L
69-
#define RCPP_USING_CXX11
70-
#if __INTEL_COMPILER >= 1210
71-
#define HAS_VARIADIC_TEMPLATES
72-
#endif
73-
#if __INTEL_COMPILER >= 1100
74-
#define HAS_STATIC_ASSERT
75-
#endif
76-
#endif
77-
#elif defined(__clang__)
78-
#if __cplusplus >= 201103L
79-
#define RCPP_USING_CXX11
80-
#if __has_feature(cxx_variadic_templates)
81-
#define HAS_VARIADIC_TEMPLATES
82-
#endif
83-
#if __has_feature(cxx_static_assert)
84-
#define HAS_STATIC_ASSERT
85-
#endif
86-
#endif
87-
#elif defined(__GNUC__)
88-
#ifdef __GXX_EXPERIMENTAL_CXX0X__
89-
#if GCC_VERSION >= 40300
90-
#define HAS_VARIADIC_TEMPLATES
91-
#define HAS_STATIC_ASSERT
92-
#endif
93-
#endif
94-
#if GCC_VERSION >= 40800 && __cplusplus >= 201103L
95-
#define RCPP_USING_CXX11
96-
#endif
29+
// Simpler test and minimal standard: C++11 or else we die
30+
#if __cplusplus < 201103L
31+
#error "The C++ compilation standard is too old: use C++11 or newer."
9732
#endif
9833

99-
// Check C++0x headers
34+
// C++11 features -- that used to be carefully tested for or worked around via CXX0X / TR1
35+
// These defines are all planned to get removed just how a number have already been removed. One at a time...
36+
#define RCPP_USING_CXX11
37+
#define HAS_VARIADIC_TEMPLATES
10038
#include <cmath>
101-
#if defined(__INTEL_COMPILER) || (defined(__GNUC__) && !defined(__clang__))
102-
#if defined(__GLIBCXX__) && defined(__GXX_EXPERIMENTAL_CXX0X__)
103-
#if GCC_VERSION >= 40400
104-
#define HAS_CXX0X_UNORDERED_MAP
105-
#define HAS_CXX0X_UNORDERED_SET
106-
#define HAS_CXX0X_INITIALIZER_LIST
107-
#endif
108-
#endif
109-
#elif defined(__clang__)
110-
#if __cplusplus >= 201103L
111-
#if __has_include(<unordered_map>)
112-
#define HAS_CXX0X_UNORDERED_MAP
113-
#endif
114-
#if __has_include(<unordered_set>)
115-
#define HAS_CXX0X_UNORDERED_SET
116-
#endif
117-
#if __has_include(<initializer_list>)
118-
#define HAS_CXX0X_INITIALIZER_LIST
119-
#endif
120-
#endif
121-
#endif
122-
123-
// Check TR1 Headers
124-
#if defined(__INTEL_COMPILER) || (defined(__GNUC__) && !defined(__clang__))
125-
#if defined(__GLIBCXX__)
126-
#if GCC_VERSION >= 40400 || ( GCC_VERSION >= 40201 && defined(__APPLE__) )
127-
#define HAS_TR1_UNORDERED_MAP
128-
#define HAS_TR1_UNORDERED_SET
129-
#endif
130-
#endif
131-
#elif defined(__clang__)
132-
#if __cplusplus >= 201103L
133-
#if __has_include(<tr1/unordered_map>)
134-
#define HAS_TR1_UNORDERED_MAP
135-
#endif
136-
#if __has_include(<tr1/unordered_set>)
137-
#define HAS_TR1_UNORDERED_SET
138-
#endif
139-
#endif
140-
#endif
141-
142-
#if defined(HAS_TR1_UNORDERED_MAP) && defined(HAS_TR1_UNORDERED_SET)
143-
#define HAS_TR1
144-
#endif
145-
146-
// Conditionally include headers
147-
#ifdef HAS_CXX0X_INITIALIZER_LIST
14839
#include <initializer_list>
149-
#endif
150-
151-
#ifdef RCPP_USING_CXX11
152-
#if defined(HAS_CXX0X_UNORDERED_MAP)
153-
#include <unordered_map>
154-
#define RCPP_USING_UNORDERED_MAP
155-
#define RCPP_UNORDERED_MAP std::unordered_map
156-
#else
157-
#include <map>
158-
#define RCPP_USING_MAP
159-
#define RCPP_UNORDERED_MAP std::map
160-
#endif
161-
#if defined(HAS_CXX0X_UNORDERED_SET)
162-
#include <unordered_set>
163-
#define RCPP_USING_UNORDERED_SET
164-
#define RCPP_UNORDERED_SET std::unordered_set
165-
#else
166-
#include <set>
167-
#define RCPP_USING_SET
168-
#define RCPP_UNORDERED_SET std::set
169-
#endif
170-
#else
171-
#if defined(HAS_TR1_UNORDERED_MAP)
172-
#include <tr1/unordered_map>
173-
#define RCPP_USING_TR1_UNORDERED_MAP
174-
#define RCPP_UNORDERED_MAP std::tr1::unordered_map
175-
#else
176-
#include <map>
177-
#define RCPP_USING_MAP
178-
#define RCPP_UNORDERED_MAP std::map
179-
#endif
180-
#if defined(HAS_TR1_UNORDERED_SET)
181-
#include <tr1/unordered_set>
182-
#define RCPP_USING_TR1_UNORDERED_SET
183-
#define RCPP_UNORDERED_SET std::tr1::unordered_set
184-
#else
185-
#include <set>
186-
#define RCPP_USING_SET
187-
#define RCPP_UNORDERED_SET std::set
188-
#endif
189-
#endif
190-
191-
#ifdef __GNUC__
40+
#include <unordered_map>
41+
#define RCPP_USING_UNORDERED_MAP
42+
#define RCPP_UNORDERED_MAP std::unordered_map
43+
#include <unordered_set>
44+
#define RCPP_USING_UNORDERED_SET
45+
#define RCPP_UNORDERED_SET std::unordered_set
46+
47+
#if defined(__GNUC__)
19248
#define RCPP_HAS_DEMANGLING
19349
#endif
19450

195-
19651
#endif

inst/include/Rcpp/sugar/functions/sapply.h

+5-5
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,16 @@
2121
#ifndef Rcpp__sugar__sapply_h
2222
#define Rcpp__sugar__sapply_h
2323

24-
#if defined(RCPP_USING_CXX0X_OR_LATER)
25-
#include <type_traits> // ::std::result_of
26-
#endif
24+
// This used to be conditional on a define and test in compiler.h
25+
#include <type_traits> // ::std::result_of
2726

2827
namespace Rcpp{
2928
namespace sugar{
3029

3130
template <typename Function, typename SugarExpression>
3231
struct sapply_application_result_of
3332
{
34-
#if defined(RCPP_USING_CXX0X_OR_LATER)
33+
#if __cplusplus >= 201103L
3534
#if __cplusplus < 201703L
3635
// deprecated by C++17, removed by C++2020, see https://en.cppreference.com/w/cpp/types/result_of
3736
typedef typename ::std::result_of<Function(typename SugarExpression::stored_type)>::type type;
@@ -40,9 +39,10 @@ struct sapply_application_result_of
4039
typedef typename ::std::invoke_result<Function, typename SugarExpression::stored_type>::type type;
4140
#endif
4241
#else
42+
// TODO this else branch can likely go
4343
typedef typename ::Rcpp::traits::result_of<Function>::type type;
4444
#endif
45-
} ;
45+
};
4646

4747
// template <typename Function, typename SugarExpression>
4848
// using sapply_application_result_of_t = typename sapply_application_result_of<Function, SugarExpression>::type;

0 commit comments

Comments
 (0)