Skip to content

Commit 19e9598

Browse files
author
Eddie
committed
Fixes MSVC build bugs
1 parent 118e9f1 commit 19e9598

File tree

18 files changed

+1304
-1185
lines changed

18 files changed

+1304
-1185
lines changed

compiler_bugs/msvc/sfinae.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#include <type_traits>
2+
#include <new>
3+
#include <utility>
4+
5+
template<typename T, typename... Args>
6+
constexpr auto Constructible_v = std::is_constructible_v<T, Args...>;
7+
8+
template<typename Q>
9+
struct ATemplate {
10+
Q space_;
11+
12+
template<typename T>
13+
constexpr static auto FitsInSpace_v = sizeof(T) <= sizeof(Q);
14+
15+
template<typename T, typename... Args>
16+
std::enable_if_t<
17+
FitsInSpace_v<T>
18+
&&
19+
#ifdef TRIGGER_MSVC_SFINAE_BUG
20+
Constructible_v<T, Args...>
21+
#else
22+
std::is_constructible_v<T, Args...>
23+
#endif
24+
,
25+
T *
26+
>
27+
sfinaeFunction(Args &&...args) {
28+
T *rv = new(static_cast<void *>(&space_)) T(std::forward<Args>(args)...);
29+
return rv;
30+
}
31+
32+
};
33+
34+
auto triggerError(ATemplate<void *[2]> &m) {
35+
return m.sfinaeFunction<void *>(nullptr);
36+
}
37+
38+
int main(int, const char *[]) { return 0; }

inc/zoo/AlignedStorage.h

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,13 @@ struct Constructible<T[L], Source>:
3939
{};
4040

4141
template<typename T, typename... Args>
42-
constexpr auto Constructible_v = Constructible<T, Args &&...>::value;
42+
constexpr
43+
#ifndef _MSC_VER
44+
auto
45+
#else
46+
bool
47+
#endif
48+
Constructible_v = Constructible<T, Args &&...>::value;
4349

4450
template<typename T>
4551
void destroy(T &t) noexcept { t.~T(); }
@@ -122,13 +128,13 @@ struct AlignedStorage {
122128

123129
template<typename T, typename... Args>
124130
#define PP_ZOO_BUILD_EXPRESSION \
125-
impl::build(*as<T>(), std::forward<Args>(args)...)
126-
auto build(Args &&...args) noexcept(noexcept(PP_ZOO_BUILD_EXPRESSION)) ->
131+
impl::build(*this->as<T>(), std::forward<Args>(args)...)
127132
std::enable_if_t<
128133
SuitableType<T>() &&
129134
impl::Constructible_v<T, Args...>,
130135
T *
131136
>
137+
build(Args &&...args) noexcept(noexcept(PP_ZOO_BUILD_EXPRESSION))
132138
{
133139
PP_ZOO_BUILD_EXPRESSION;
134140
#undef PP_ZOO_BUILD_EXPRESSION

inc/zoo/algorithm/cfs.h

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,24 @@
11
#ifndef ZOO_CFS_CACHE_FRIENDLY_SEARCH
22
#define ZOO_CFS_CACHE_FRIENDLY_SEARCH
33

4-
#include <zoo/algorithm/less.h>
4+
#include "zoo/algorithm/less.h"
5+
#include "zoo/meta/log.h"
56

67
#ifndef SIMPLIFY_INCLUDES
78
// because of std::declval needed to default comparator
89
#include <utility>
910
// because of std::decay needed to decay deferenced iterator
1011
#include <type_traits>
12+
13+
#include <ciso646>
1114
#endif
1215

1316
namespace zoo {
1417

15-
constexpr unsigned long long log2Floor(unsigned long long arg) {
16-
return 63 - __builtin_clzll(arg);
17-
}
18-
19-
constexpr unsigned long long log2Ceiling(unsigned long long arg) {
20-
return 63 - __builtin_clzll(2*arg - 1);
21-
}
22-
2318
template<typename Output, typename Input>
2419
void transformToCFS(Output output, Input base, Input end) {
2520
auto s = end - base;
26-
auto logP = log2Floor(s + 1); // n
21+
auto logP = meta::logFloor(s + 1); // n
2722
auto power2 = 1ul << logP;
2823
auto fullSubtreeSize = power2 - 1;
2924
// Full tree has (2^n) - 1 elements
@@ -52,7 +47,8 @@ void transformToCFS(Output output, Input base, Input end) {
5247
}
5348

5449
// now just write the excess leaves
55-
for(auto ndx = 0ul, top = 2*excess; ndx < top; ndx += 2) {
50+
auto top = 2*excess;
51+
for(auto ndx = 0ll; ndx < top; ndx += 2) {
5652
*output++ = *(base + ndx);
5753
}
5854
}
@@ -167,7 +163,7 @@ struct ValidResult {
167163

168164
template<typename I, typename Comparator = Less>
169165
auto validHeap(
170-
I base, int current, int max, Comparator c = Comparator{}
166+
I base, long current, long max, Comparator c = Comparator{}
171167
) -> ValidResult {
172168
for(;;) {
173169
auto higherSubtree = current*2 + 2;

inc/zoo/algorithm/quicksort.h

Lines changed: 130 additions & 130 deletions
Original file line numberDiff line numberDiff line change
@@ -1,130 +1,130 @@
1-
#ifndef ZOO_QUICKSORT
2-
#define ZOO_QUICKSORT
3-
4-
#include <zoo/algorithm/moveRotation.h> // for moveRotate
5-
6-
#include <zoo/algorithm/less.h>
7-
8-
#include <array> // for temporary storage
9-
#include <stdexcept>
10-
11-
namespace zoo {
12-
13-
template<typename FI>
14-
struct ImplicitPivotResult {
15-
FI pivot_;
16-
long bias_;
17-
};
18-
19-
/// \tparam FI is a forward iterator
20-
/// \pre b != e
21-
template<typename FI, typename Comparison>
22-
auto implicitPivotPartition(FI b, FI e, Comparison cmp) ->
23-
ImplicitPivotResult<FI>
24-
{
25-
auto bias = 0;
26-
auto pivot = b++;
27-
/*if(e == b) { return pivot; }
28-
if(cmp(*b, *pivot)) {
29-
auto third = next(b);
30-
if(third == e) {
31-
moveRotation(*pivot, *b);
32-
return pivot;
33-
}
34-
}*/
35-
for(; b != e; ++b) {
36-
// invariant: ..., L0, P == *pivot, G0, G1, ... Gn, *b
37-
// where Lx means lower-than-pivot and Gx higher-equal-to-pivot
38-
if(!cmp(*b, *pivot)) {
39-
++bias;
40-
continue;
41-
}
42-
--bias;
43-
// ..., L1, P == *pivot, G0, G1, ..., Gn, L0 == *b, X0, ...
44-
// The pivot is greater than the element:
45-
// insert *b into the lower partition:
46-
// 1. *b goes into the pivot position
47-
// 2. the pivot increases by one
48-
// 3. the element at pivot + 1, the new pivot, must be greater
49-
// than or equal to any Lx, the value of *pivot satisfies this
50-
// property.
51-
// These requirements can be satisfied by rotating the elements
52-
// at positions (pivot, b, pivot + 1)
53-
// ..., L1, L0, P == *pivot, G1, ..., Gn, G0 == *b, X0, ...
54-
auto oldPivot = pivot++;
55-
if(b == pivot) {
56-
moveRotation(*oldPivot, *pivot);
57-
} else {
58-
moveRotation(*oldPivot, *b, *pivot);
59-
}
60-
// tmp = *b, *b = *1, *1 = *0, *0 = tmp
61-
/*moveRotation(*oldPivot, *b);
62-
moveRotation(*b, *pivot);*/
63-
}
64-
return {pivot, bias};
65-
}
66-
67-
template<typename I, typename Comparison = Less>
68-
void quicksort(I begin, I end, Comparison cmp = Comparison{}) {
69-
if(begin == end) { return; }
70-
71-
constexpr static const auto FrameCount = 64;
72-
struct Frame {
73-
I b, e;
74-
};
75-
std::array<Frame, FrameCount> stack;
76-
auto index = 0;
77-
78-
for(;;) {
79-
auto result = implicitPivotPartition(begin, end, cmp);
80-
auto pivot = result.pivot_;
81-
auto bias = result.bias_;
82-
auto higherBegin = next(pivot);
83-
if(higherBegin == end) { // no higher-recursion needed
84-
if(begin != pivot) {
85-
end = pivot; // then just do lower recursion
86-
continue; // without leaving a frame
87-
}
88-
// there is no lower-recursion either
89-
if(!index) { return; }
90-
auto &frame = stack[--index];
91-
begin = frame.b;
92-
end = frame.e;
93-
continue;
94-
}
95-
// higher recursion needed
96-
if(begin == pivot) { // no lower recursion needed
97-
begin = higherBegin; // becomes the higher recursion
98-
continue;
99-
}
100-
// both lower and higher recursions needed, make frame for the larger
101-
// partition:
102-
// The smaller partition is less than or equal to half the elements:
103-
// size(smaller) <= size/2 => depth of recursion <= log2(N)
104-
if(0 < bias) { // lower partition is smaller
105-
stack[index] = { higherBegin, end };
106-
end = pivot;
107-
} else { // higher partition is smaller
108-
stack[index] = { begin, pivot };
109-
begin = higherBegin;
110-
}
111-
if(FrameCount <= ++index) {
112-
throw std::runtime_error("quicksort stack exhausted");
113-
}
114-
}
115-
}
116-
117-
template<typename FI, typename Comparison = Less>
118-
bool is_sorted(FI begin, FI end, Comparison cmp = Comparison{}) {
119-
if(begin == end) { return true; }
120-
auto old = begin++;
121-
while(begin != end) {
122-
if(not cmp(*old, *begin)) { return false; }
123-
old = begin++;
124-
}
125-
return true;
126-
}
127-
128-
}
129-
130-
#endif
1+
#ifndef ZOO_QUICKSORT
2+
#define ZOO_QUICKSORT
3+
4+
#include <zoo/algorithm/moveRotation.h> // for moveRotate
5+
6+
#include <zoo/algorithm/less.h>
7+
8+
#include <array> // for temporary storage
9+
#include <stdexcept>
10+
11+
namespace zoo {
12+
13+
template<typename FI>
14+
struct ImplicitPivotResult {
15+
FI pivot_;
16+
long bias_;
17+
};
18+
19+
/// \tparam FI is a forward iterator
20+
/// \pre b != e
21+
template<typename FI, typename Comparison>
22+
auto implicitPivotPartition(FI b, FI e, Comparison cmp) ->
23+
ImplicitPivotResult<FI>
24+
{
25+
auto bias = 0;
26+
auto pivot = b++;
27+
/*if(e == b) { return pivot; }
28+
if(cmp(*b, *pivot)) {
29+
auto third = next(b);
30+
if(third == e) {
31+
moveRotation(*pivot, *b);
32+
return pivot;
33+
}
34+
}*/
35+
for(; b != e; ++b) {
36+
// invariant: ..., L0, P == *pivot, G0, G1, ... Gn, *b
37+
// where Lx means lower-than-pivot and Gx higher-equal-to-pivot
38+
if(!cmp(*b, *pivot)) {
39+
++bias;
40+
continue;
41+
}
42+
--bias;
43+
// ..., L1, P == *pivot, G0, G1, ..., Gn, L0 == *b, X0, ...
44+
// The pivot is greater than the element:
45+
// insert *b into the lower partition:
46+
// 1. *b goes into the pivot position
47+
// 2. the pivot increases by one
48+
// 3. the element at pivot + 1, the new pivot, must be greater
49+
// than or equal to any Lx, the value of *pivot satisfies this
50+
// property.
51+
// These requirements can be satisfied by rotating the elements
52+
// at positions (pivot, b, pivot + 1)
53+
// ..., L1, L0, P == *pivot, G1, ..., Gn, G0 == *b, X0, ...
54+
auto oldPivot = pivot++;
55+
if(b == pivot) {
56+
moveRotation(*oldPivot, *pivot);
57+
} else {
58+
moveRotation(*oldPivot, *b, *pivot);
59+
}
60+
// tmp = *b, *b = *1, *1 = *0, *0 = tmp
61+
/*moveRotation(*oldPivot, *b);
62+
moveRotation(*b, *pivot);*/
63+
}
64+
return {pivot, bias};
65+
}
66+
67+
template<typename I, typename Comparison = Less>
68+
void quicksort(I begin, I end, Comparison cmp = Comparison{}) {
69+
if(begin == end) { return; }
70+
71+
constexpr static const auto FrameCount = 64;
72+
struct Frame {
73+
I b, e;
74+
};
75+
std::array<Frame, FrameCount> stack;
76+
auto index = 0;
77+
78+
for(;;) {
79+
auto result = implicitPivotPartition(begin, end, cmp);
80+
auto pivot = result.pivot_;
81+
auto bias = result.bias_;
82+
auto higherBegin = next(pivot);
83+
if(higherBegin == end) { // no higher-recursion needed
84+
if(begin != pivot) {
85+
end = pivot; // then just do lower recursion
86+
continue; // without leaving a frame
87+
}
88+
// there is no lower-recursion either
89+
if(!index) { return; }
90+
auto &frame = stack[--index];
91+
begin = frame.b;
92+
end = frame.e;
93+
continue;
94+
}
95+
// higher recursion needed
96+
if(begin == pivot) { // no lower recursion needed
97+
begin = higherBegin; // becomes the higher recursion
98+
continue;
99+
}
100+
// both lower and higher recursions needed, make frame for the larger
101+
// partition:
102+
// The smaller partition is less than or equal to half the elements:
103+
// size(smaller) <= size/2 => depth of recursion <= log2(N)
104+
if(0 < bias) { // lower partition is smaller
105+
stack[index] = { higherBegin, end };
106+
end = pivot;
107+
} else { // higher partition is smaller
108+
stack[index] = { begin, pivot };
109+
begin = higherBegin;
110+
}
111+
if(FrameCount <= ++index) {
112+
throw std::runtime_error("quicksort stack exhausted");
113+
}
114+
}
115+
}
116+
117+
template<typename FI, typename Comparison = Less>
118+
bool is_sorted(FI begin, FI end, Comparison cmp = Comparison{}) {
119+
if(begin == end) { return true; }
120+
auto old = begin++;
121+
while(begin != end) {
122+
if(not cmp(*old, *begin)) { return false; }
123+
old = begin++;
124+
}
125+
return true;
126+
}
127+
128+
}
129+
130+
#endif

0 commit comments

Comments
 (0)