Skip to content

Commit 6512f69

Browse files
authored
Merge pull request #88 from fabinsch/topic/c++14-compat
CI for c++14 compatibility
2 parents 76977e5 + d248c24 commit 6512f69

File tree

6 files changed

+158
-83
lines changed

6 files changed

+158
-83
lines changed

.github/workflows/ci-linux-osx-win-conda.yml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,14 @@ on:
66

77
jobs:
88
build-with-conda:
9-
name: '[conda:${{ matrix.os }}:${{ matrix.build_type }}]'
9+
name: '[conda:${{ matrix.os }}:${{ matrix.build_type }}:c++${{ matrix.cxx_std }}]'
1010
runs-on: ${{ matrix.os }}
1111
strategy:
1212
fail-fast: false
1313
matrix:
1414
build_type: [Release, Debug]
1515
name: [ubuntu-latest, macos-latest, windows-2019-clang-cl, windows-latest]
16+
cxx_std: [17]
1617

1718
include:
1819
- name: ubuntu-latest
@@ -24,6 +25,10 @@ jobs:
2425
compiler: clang-cl
2526
- name: windows-latest
2627
os: windows-latest
28+
- name: macos-latest
29+
os: macos-latest
30+
build_type: Release
31+
cxx_std: 14
2732

2833
steps:
2934
- uses: actions/checkout@v2
@@ -84,7 +89,7 @@ jobs:
8489
git submodule update --init
8590
mkdir build
8691
cd build
87-
cmake .. -GNinja -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_INSTALL_PREFIX=${CONDA_PREFIX} -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DBUILD_PYTHON_INTERFACE:BOOL=ON -DPYTHON_EXECUTABLE=$(which python3) -DINSTALL_DOCUMENTATION:BOOL=ON -DTEST_JULIA_INTERFACE:BOOL=ON
92+
cmake .. -GNinja -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_STANDARD=${{ matrix.cxx_std }} -DCMAKE_INSTALL_PREFIX=${CONDA_PREFIX} -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DBUILD_PYTHON_INTERFACE:BOOL=ON -DPYTHON_EXECUTABLE=$(which python3) -DINSTALL_DOCUMENTATION:BOOL=ON -DTEST_JULIA_INTERFACE:BOOL=ON
8893
8994
- name: Configure [Conda/Windows-2019]
9095
if: contains(matrix.os, 'windows-2019')

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ endif(INITIALIZE_EIGEN_WITH_NAN)
7474

7575
# set CXX standard
7676
if(DEFINED CMAKE_CXX_STANDARD)
77-
check_minimal_cxx_standard(17 ENFORCE)
77+
check_minimal_cxx_standard(14 ENFORCE)
7878
else()
7979
set(CMAKE_CXX_STANDARD 17)
8080
endif()

include/proxsuite/helpers/instruction-set.hpp

Lines changed: 126 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -41,81 +41,11 @@ cpuidex(std::array<int, 4>& cpui, int level, int count)
4141
__cpuidex(cpui.data(), level, count);
4242
#endif
4343
}
44-
}
4544

46-
// Adapted from
47-
// https://docs.microsoft.com/fr-fr/cpp/intrinsics/cpuid-cpuidex?view=msvc-170
48-
struct InstructionSet
45+
template<typename T = void>
46+
struct InstructionSetBase
4947
{
50-
static std::string vendor(void) { return data.vendor_; }
51-
static std::string brand(void) { return data.brand_; }
52-
53-
static bool has_SSE3(void) { return data.f_1_ECX_[0]; }
54-
static bool has_PCLMULQDQ(void) { return data.f_1_ECX_[1]; }
55-
static bool has_MONITOR(void) { return data.f_1_ECX_[3]; }
56-
static bool has_SSSE3(void) { return data.f_1_ECX_[9]; }
57-
static bool has_FMA(void) { return data.f_1_ECX_[12]; }
58-
static bool has_CMPXCHG16B(void) { return data.f_1_ECX_[13]; }
59-
static bool has_SSE41(void) { return data.f_1_ECX_[19]; }
60-
static bool has_SSE42(void) { return data.f_1_ECX_[20]; }
61-
static bool has_MOVBE(void) { return data.f_1_ECX_[22]; }
62-
static bool has_POPCNT(void) { return data.f_1_ECX_[23]; }
63-
static bool has_AES(void) { return data.f_1_ECX_[25]; }
64-
static bool has_XSAVE(void) { return data.f_1_ECX_[26]; }
65-
static bool has_OSXSAVE(void) { return data.f_1_ECX_[27]; }
66-
static bool has_AVX(void) { return data.f_1_ECX_[28]; }
67-
static bool has_F16C(void) { return data.f_1_ECX_[29]; }
68-
static bool has_RDRAND(void) { return data.f_1_ECX_[30]; }
69-
70-
static bool has_MSR(void) { return data.f_1_EDX_[5]; }
71-
static bool has_CX8(void) { return data.f_1_EDX_[8]; }
72-
static bool has_SEP(void) { return data.f_1_EDX_[11]; }
73-
static bool has_CMOV(void) { return data.f_1_EDX_[15]; }
74-
static bool has_CLFSH(void) { return data.f_1_EDX_[19]; }
75-
static bool has_MMX(void) { return data.f_1_EDX_[23]; }
76-
static bool has_FXSR(void) { return data.f_1_EDX_[24]; }
77-
static bool has_SSE(void) { return data.f_1_EDX_[25]; }
78-
static bool has_SSE2(void) { return data.f_1_EDX_[26]; }
79-
80-
static bool has_FSGSBASE(void) { return data.f_7_EBX_[0]; }
81-
static bool has_AVX512VBMI(void) { return data.f_7_EBX_[1]; }
82-
static bool has_BMI1(void) { return data.f_7_EBX_[3]; }
83-
static bool has_HLE(void) { return data.isIntel_ && data.f_7_EBX_[4]; }
84-
static bool has_AVX2(void) { return data.f_7_EBX_[5]; }
85-
static bool has_BMI2(void) { return data.f_7_EBX_[8]; }
86-
static bool has_ERMS(void) { return data.f_7_EBX_[9]; }
87-
static bool has_INVPCID(void) { return data.f_7_EBX_[10]; }
88-
static bool has_RTM(void) { return data.isIntel_ && data.f_7_EBX_[11]; }
89-
static bool has_AVX512F(void) { return data.f_7_EBX_[16]; }
90-
static bool has_AVX512DQ(void) { return data.f_7_EBX_[17]; }
91-
static bool has_RDSEED(void) { return data.f_7_EBX_[18]; }
92-
static bool has_ADX(void) { return data.f_7_EBX_[19]; }
93-
static bool has_AVX512IFMA(void) { return data.f_7_EBX_[21]; }
94-
static bool has_AVX512PF(void) { return data.f_7_EBX_[26]; }
95-
static bool has_AVX512ER(void) { return data.f_7_EBX_[27]; }
96-
static bool has_AVX512CD(void) { return data.f_7_EBX_[28]; }
97-
static bool has_SHA(void) { return data.f_7_EBX_[29]; }
98-
static bool has_AVX512BW(void) { return data.f_7_EBX_[30]; }
99-
static bool has_AVX512VL(void) { return data.f_7_EBX_[31]; }
100-
101-
static bool has_PREFETCHWT1(void) { return data.f_7_ECX_[0]; }
102-
103-
static bool has_LAHF(void) { return data.f_81_ECX_[0]; }
104-
static bool has_LZCNT(void) { return data.isIntel_ && data.f_81_ECX_[5]; }
105-
static bool has_ABM(void) { return data.isAMD_ && data.f_81_ECX_[5]; }
106-
static bool has_SSE4a(void) { return data.isAMD_ && data.f_81_ECX_[6]; }
107-
static bool has_XOP(void) { return data.isAMD_ && data.f_81_ECX_[11]; }
108-
static bool has_FMA4(void) { return data.isAMD_ && data.f_81_ECX_[16]; }
109-
static bool has_TBM(void) { return data.isAMD_ && data.f_81_ECX_[21]; }
110-
111-
static bool has_SYSCALL(void) { return data.isIntel_ && data.f_81_EDX_[11]; }
112-
static bool has_MMXEXT(void) { return data.isAMD_ && data.f_81_EDX_[22]; }
113-
static bool has_RDTSCP(void) { return data.isIntel_ && data.f_81_EDX_[27]; }
114-
static bool has_x64(void) { return data.isIntel_ && data.f_81_EDX_[29]; }
115-
static bool has_3DNOWEXT(void) { return data.isAMD_ && data.f_81_EDX_[30]; }
116-
static bool has_3DNOW(void) { return data.isAMD_ && data.f_81_EDX_[31]; }
117-
118-
private:
48+
protected:
11949
struct Data
12050
{
12151
Data()
@@ -214,7 +144,129 @@ struct InstructionSet
214144
std::vector<std::array<int, 4>> extdata_;
215145
};
216146

217-
inline static const Data data = Data();
147+
static const Data data;
148+
};
149+
150+
template<>
151+
const typename InstructionSetBase<>::Data InstructionSetBase<>::data =
152+
typename InstructionSetBase<>::Data();
153+
} // namespace internal
154+
155+
// Adapted from
156+
// https://docs.microsoft.com/fr-fr/cpp/intrinsics/cpuid-cpuidex?view=msvc-170
157+
struct InstructionSet : public internal::InstructionSetBase<>
158+
{
159+
typedef internal::InstructionSetBase<> Base;
160+
161+
static std::string vendor(void) { return Base::data.vendor_; }
162+
static std::string brand(void) { return Base::data.brand_; }
163+
164+
static bool has_SSE3(void) { return Base::data.f_1_ECX_[0]; }
165+
static bool has_PCLMULQDQ(void) { return Base::data.f_1_ECX_[1]; }
166+
static bool has_MONITOR(void) { return Base::data.f_1_ECX_[3]; }
167+
static bool has_SSSE3(void) { return Base::data.f_1_ECX_[9]; }
168+
static bool has_FMA(void) { return Base::data.f_1_ECX_[12]; }
169+
static bool has_CMPXCHG16B(void) { return Base::data.f_1_ECX_[13]; }
170+
static bool has_SSE41(void) { return Base::data.f_1_ECX_[19]; }
171+
static bool has_SSE42(void) { return Base::data.f_1_ECX_[20]; }
172+
static bool has_MOVBE(void) { return Base::data.f_1_ECX_[22]; }
173+
static bool has_POPCNT(void) { return Base::data.f_1_ECX_[23]; }
174+
static bool has_AES(void) { return Base::data.f_1_ECX_[25]; }
175+
static bool has_XSAVE(void) { return Base::data.f_1_ECX_[26]; }
176+
static bool has_OSXSAVE(void) { return Base::data.f_1_ECX_[27]; }
177+
static bool has_AVX(void) { return Base::data.f_1_ECX_[28]; }
178+
static bool has_F16C(void) { return Base::data.f_1_ECX_[29]; }
179+
static bool has_RDRAND(void) { return Base::data.f_1_ECX_[30]; }
180+
181+
static bool has_MSR(void) { return Base::data.f_1_EDX_[5]; }
182+
static bool has_CX8(void) { return Base::data.f_1_EDX_[8]; }
183+
static bool has_SEP(void) { return Base::data.f_1_EDX_[11]; }
184+
static bool has_CMOV(void) { return Base::data.f_1_EDX_[15]; }
185+
static bool has_CLFSH(void) { return Base::data.f_1_EDX_[19]; }
186+
static bool has_MMX(void) { return Base::data.f_1_EDX_[23]; }
187+
static bool has_FXSR(void) { return Base::data.f_1_EDX_[24]; }
188+
static bool has_SSE(void) { return Base::data.f_1_EDX_[25]; }
189+
static bool has_SSE2(void) { return Base::data.f_1_EDX_[26]; }
190+
191+
static bool has_FSGSBASE(void) { return Base::data.f_7_EBX_[0]; }
192+
static bool has_AVX512VBMI(void) { return Base::data.f_7_EBX_[1]; }
193+
static bool has_BMI1(void) { return Base::data.f_7_EBX_[3]; }
194+
static bool has_HLE(void)
195+
{
196+
return Base::data.isIntel_ && Base::data.f_7_EBX_[4];
197+
}
198+
static bool has_AVX2(void) { return Base::data.f_7_EBX_[5]; }
199+
static bool has_BMI2(void) { return Base::data.f_7_EBX_[8]; }
200+
static bool has_ERMS(void) { return Base::data.f_7_EBX_[9]; }
201+
static bool has_INVPCID(void) { return Base::data.f_7_EBX_[10]; }
202+
static bool has_RTM(void)
203+
{
204+
return Base::data.isIntel_ && Base::data.f_7_EBX_[11];
205+
}
206+
static bool has_AVX512F(void) { return Base::data.f_7_EBX_[16]; }
207+
static bool has_AVX512DQ(void) { return Base::data.f_7_EBX_[17]; }
208+
static bool has_RDSEED(void) { return Base::data.f_7_EBX_[18]; }
209+
static bool has_ADX(void) { return Base::data.f_7_EBX_[19]; }
210+
static bool has_AVX512IFMA(void) { return Base::data.f_7_EBX_[21]; }
211+
static bool has_AVX512PF(void) { return Base::data.f_7_EBX_[26]; }
212+
static bool has_AVX512ER(void) { return Base::data.f_7_EBX_[27]; }
213+
static bool has_AVX512CD(void) { return Base::data.f_7_EBX_[28]; }
214+
static bool has_SHA(void) { return Base::data.f_7_EBX_[29]; }
215+
static bool has_AVX512BW(void) { return Base::data.f_7_EBX_[30]; }
216+
static bool has_AVX512VL(void) { return Base::data.f_7_EBX_[31]; }
217+
218+
static bool has_PREFETCHWT1(void) { return Base::data.f_7_ECX_[0]; }
219+
220+
static bool has_LAHF(void) { return Base::data.f_81_ECX_[0]; }
221+
static bool has_LZCNT(void)
222+
{
223+
return Base::data.isIntel_ && Base::data.f_81_ECX_[5];
224+
}
225+
static bool has_ABM(void)
226+
{
227+
return Base::data.isAMD_ && Base::data.f_81_ECX_[5];
228+
}
229+
static bool has_SSE4a(void)
230+
{
231+
return Base::data.isAMD_ && Base::data.f_81_ECX_[6];
232+
}
233+
static bool has_XOP(void)
234+
{
235+
return Base::data.isAMD_ && Base::data.f_81_ECX_[11];
236+
}
237+
static bool has_FMA4(void)
238+
{
239+
return Base::data.isAMD_ && Base::data.f_81_ECX_[16];
240+
}
241+
static bool has_TBM(void)
242+
{
243+
return Base::data.isAMD_ && Base::data.f_81_ECX_[21];
244+
}
245+
246+
static bool has_SYSCALL(void)
247+
{
248+
return Base::data.isIntel_ && Base::data.f_81_EDX_[11];
249+
}
250+
static bool has_MMXEXT(void)
251+
{
252+
return Base::data.isAMD_ && Base::data.f_81_EDX_[22];
253+
}
254+
static bool has_RDTSCP(void)
255+
{
256+
return Base::data.isIntel_ && Base::data.f_81_EDX_[27];
257+
}
258+
static bool has_x64(void)
259+
{
260+
return Base::data.isIntel_ && Base::data.f_81_EDX_[29];
261+
}
262+
static bool has_3DNOWEXT(void)
263+
{
264+
return Base::data.isAMD_ && Base::data.f_81_EDX_[30];
265+
}
266+
static bool has_3DNOW(void)
267+
{
268+
return Base::data.isAMD_ && Base::data.f_81_EDX_[31];
269+
}
218270
};
219271

220272
} // helpers

include/proxsuite/helpers/optional.hpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,23 @@ using optional = std::optional<T>;
2121
using nullopt_t = std::nullopt_t;
2222
inline constexpr nullopt_t nullopt = std::nullopt;
2323
#else
24+
namespace detail {
25+
// Source boost: https://www.boost.org/doc/libs/1_74_0/boost/none.hpp
26+
// the trick here is to make instance defined once as a global but in a header
27+
// file
28+
template<typename T>
29+
struct nullopt_instance
30+
{
31+
static const T instance;
32+
};
33+
template<typename T>
34+
const T nullopt_instance<T>::instance =
35+
T(tl::nullopt); // global, but because 'tis a template, no cpp file required
36+
} // namespace detail
2437
template<class T>
2538
using optional = tl::optional<T>;
2639
using nullopt_t = tl::nullopt_t;
27-
inline constexpr nullopt_t nullopt = tl::nullopt;
40+
constexpr nullopt_t nullopt = detail::nullopt_instance<tl::nullopt_t>::instance;
2841
#endif
2942
} // namespace proxsuite
3043

include/proxsuite/linalg/veg/memory/alloc.hpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ namespace veg {
2828
namespace alignment {
2929

3030
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 101500 && \
31-
(defined(_LIBCPP_HAS_ALIGNED_ALLOC) || defined(_LIBCPP_HAS_C11_FEATURES))
31+
(defined(_LIBCPP_HAS_ALIGNED_ALLOC) || defined(_LIBCPP_HAS_C11_FEATURES)) && \
32+
defined(PROXSUITE_WITH_CPP_17)
3233
VEG_INLINE void*
3334
aligned_alloc(std::size_t alignment, std::size_t size)
3435
{
@@ -167,11 +168,15 @@ aligned_alloc(usize align, usize size) noexcept -> void*
167168
#if defined(_WIN32)
168169
return _aligned_malloc((size + mask) & ~mask, align);
169170
#elif defined(__APPLE__)
171+
#if defined(PROXSUITE_WITH_CPP_17)
170172
return alignment::aligned_alloc(align, (size + mask) & ~mask);
173+
#elif defined(PROXSUITE_WITH_CPP_14)
174+
return alignment::detail::aligned_alloc(align, (size + mask) & ~mask);
175+
#endif
171176
#else
172177
#ifdef PROXSUITE_WITH_CPP_17
173178
return std::aligned_alloc(align, (size + mask) & ~mask);
174-
#else
179+
#elif defined(PROXSUITE_WITH_CPP_14)
175180
return alignment::detail::aligned_alloc(align, (size + mask) & ~mask);
176181
#endif
177182
#endif

include/proxsuite/proxqp/dense/wrapper.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -327,11 +327,11 @@ struct QP
327327
* @param mu_eq proximal step size wrt equality constrained multiplier.
328328
* @param mu_in proximal step size wrt inequality constrained multiplier.
329329
*/
330-
void update([[maybe_unused]] const nullopt_t H,
330+
void update(PROXSUITE_MAYBE_UNUSED const nullopt_t H,
331331
optional<Vec<T>> g,
332-
[[maybe_unused]] const nullopt_t A,
332+
PROXSUITE_MAYBE_UNUSED const nullopt_t A,
333333
optional<Vec<T>> b,
334-
[[maybe_unused]] const nullopt_t C,
334+
PROXSUITE_MAYBE_UNUSED const nullopt_t C,
335335
optional<Vec<T>> l,
336336
optional<Vec<T>> u,
337337
bool update_preconditioner = true,

0 commit comments

Comments
 (0)