Skip to content

Commit d73c537

Browse files
author
Hana Dusíková
committed
#20 workaround for MSVC compiler bug, thanks to TartanLlama
1 parent aa8fb29 commit d73c537

File tree

4 files changed

+336
-3
lines changed

4 files changed

+336
-3
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ DESATOMAT := /www/root/desatomat/console/desatomat.php
99

1010
CPP_STANDARD := $(shell ./cpp-20-check.sh $(CXX))
1111

12-
override CXXFLAGS := $(CXXFLAGS) $(CPP_STANDARD) -Iinclude -O3 -pedantic -Wall -Wextra
12+
override CXXFLAGS := $(CXXFLAGS) $(CPP_STANDARD) -Iinclude -O3 -pedantic -Wall -Wextra
1313
LDFLAGS :=
1414

1515
TESTS := $(wildcard tests/*.cpp) $(wildcard tests/benchmark/*.cpp)

include/ctre/evaluation.hpp

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,13 @@
99
#include "find_captures.hpp"
1010
#include "first.hpp"
1111

12+
// remove me when MSVC fix the constexpr bug
13+
#ifdef _MSC_VER
14+
#ifndef CTRE_MSVC_GREEDY_WORKAROUND
15+
#define CTRE_MSVC_GREEDY_WORKAROUND
16+
#endif
17+
#endif
18+
1219
namespace ctre {
1320

1421
// calling with pattern prepare stack and triplet of iterators
@@ -237,7 +244,11 @@ constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, c
237244

238245
// (gready) repeat
239246
template <typename R, typename Iterator, typename EndIterator, size_t A, size_t B, typename... Content, typename... Tail>
247+
#ifdef CTRE_MSVC_GREEDY_WORKAROUND
248+
constexpr inline void evaluate_recursive(R & result, size_t i, const Iterator begin, Iterator current, const EndIterator end, R captures, ctll::list<repeat<A,B,Content...>, Tail...> stack) {
249+
#else
240250
constexpr inline R evaluate_recursive(size_t i, const Iterator begin, Iterator current, const EndIterator end, R captures, ctll::list<repeat<A,B,Content...>, Tail...> stack) {
251+
#endif
241252
if ((B == 0) || (i < B)) {
242253

243254
// a*ab
@@ -248,12 +259,23 @@ constexpr inline R evaluate_recursive(size_t i, const Iterator begin, Iterator c
248259
// if I uncomment this return it will not fail in constexpr (but the matching result will not be correct)
249260
// return inner_result
250261
// I tried to add all constructors to R but without any success
262+
#ifdef CTRE_MSVC_GREEDY_WORKAROUND
263+
evaluate_recursive(result, i+1, begin, inner_result.get_end_position(), end, inner_result.unmatch(), stack);
264+
if (result) {
265+
return;
266+
}
267+
#else
251268
if (auto rec_result = evaluate_recursive(i+1, begin, inner_result.get_end_position(), end, inner_result.unmatch(), stack)) {
252269
return rec_result;
253270
}
271+
#endif
254272
}
255273
}
274+
#ifdef CTRE_MSVC_GREEDY_WORKAROUND
275+
result = evaluate(begin, current, end, captures, ctll::list<Tail...>());
276+
#else
256277
return evaluate(begin, current, end, captures, ctll::list<Tail...>());
278+
#endif
257279
}
258280

259281

@@ -284,8 +306,13 @@ constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, c
284306
return not_matched;
285307
}
286308
}
287-
309+
#ifdef CTRE_MSVC_GREEDY_WORKAROUND
310+
R result;
311+
evaluate_recursive(result, i, begin, current, end, captures, stack);
312+
return result;
313+
#else
288314
return evaluate_recursive(i, begin, current, end, captures, stack);
315+
#endif
289316
#ifndef CTRE_DISABLE_GREEDY_OPT
290317
} else {
291318
// if there is no collision we can go possessive

single-header/ctre.hpp

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3066,6 +3066,13 @@ template <typename... A, typename... B> constexpr bool collides(ctll::list<A...>
30663066

30673067
#endif
30683068

3069+
// remove me when MSVC fix the constexpr bug
3070+
#ifdef _MSC_VER
3071+
#ifndef CTRE_MSVC_GREEDY_WORKAROUND
3072+
#define CTRE_MSVC_GREEDY_WORKAROUND
3073+
#endif
3074+
#endif
3075+
30693076
namespace ctre {
30703077

30713078
// calling with pattern prepare stack and triplet of iterators
@@ -3292,7 +3299,11 @@ constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, c
32923299

32933300
// (gready) repeat
32943301
template <typename R, typename Iterator, typename EndIterator, size_t A, size_t B, typename... Content, typename... Tail>
3302+
#ifdef CTRE_MSVC_GREEDY_WORKAROUND
3303+
constexpr inline void evaluate_recursive(R & result, size_t i, const Iterator begin, Iterator current, const EndIterator end, R captures, ctll::list<repeat<A,B,Content...>, Tail...> stack) {
3304+
#else
32953305
constexpr inline R evaluate_recursive(size_t i, const Iterator begin, Iterator current, const EndIterator end, R captures, ctll::list<repeat<A,B,Content...>, Tail...> stack) {
3306+
#endif
32963307
if ((B == 0) || (i < B)) {
32973308

32983309
// a*ab
@@ -3303,12 +3314,23 @@ constexpr inline R evaluate_recursive(size_t i, const Iterator begin, Iterator c
33033314
// if I uncomment this return it will not fail in constexpr (but the matching result will not be correct)
33043315
// return inner_result
33053316
// I tried to add all constructors to R but without any success
3317+
#ifdef CTRE_MSVC_GREEDY_WORKAROUND
3318+
evaluate_recursive(result, i+1, begin, inner_result.get_end_position(), end, inner_result.unmatch(), stack);
3319+
if (result) {
3320+
return;
3321+
}
3322+
#else
33063323
if (auto rec_result = evaluate_recursive(i+1, begin, inner_result.get_end_position(), end, inner_result.unmatch(), stack)) {
33073324
return rec_result;
33083325
}
3326+
#endif
33093327
}
33103328
}
3329+
#ifdef CTRE_MSVC_GREEDY_WORKAROUND
3330+
result = evaluate(begin, current, end, captures, ctll::list<Tail...>());
3331+
#else
33113332
return evaluate(begin, current, end, captures, ctll::list<Tail...>());
3333+
#endif
33123334
}
33133335

33143336
// (gready) repeat optimization
@@ -3338,8 +3360,13 @@ constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, c
33383360
return not_matched;
33393361
}
33403362
}
3341-
3363+
#ifdef CTRE_MSVC_GREEDY_WORKAROUND
3364+
R result;
3365+
evaluate_recursive(result, i, begin, current, end, captures, stack);
3366+
return result;
3367+
#else
33423368
return evaluate_recursive(i, begin, current, end, captures, stack);
3369+
#endif
33433370
#ifndef CTRE_DISABLE_GREEDY_OPT
33443371
} else {
33453372
// if there is no collision we can go possessive

0 commit comments

Comments
 (0)