Skip to content

Commit 04add89

Browse files
authored
Fix ICE for msv2022 and add msvc2022 workflow
Fix ICE on join_v and partial write for msv2022 and add msvc2022 workflow
1 parent ae6b4ea commit 04add89

File tree

4 files changed

+53
-44
lines changed

4 files changed

+53
-44
lines changed

.github/workflows/msvc.yml .github/workflows/msvc_2019.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: msvc
1+
name: msvc_2019
22

33
on:
44
push:

.github/workflows/msvc_cpm.yml .github/workflows/msvc_2022.yml

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: msvc_cpm
1+
name: msvc_2022
22

33
on:
44
push:
@@ -17,14 +17,13 @@ env:
1717

1818
jobs:
1919
build:
20-
runs-on: windows-2019
20+
runs-on: windows-2022
2121

2222
steps:
2323
- uses: actions/checkout@v3
2424

25-
# using specific windows SDK to address this issue: https://stackoverflow.com/questions/65402366/c5105-and-other-compiler-warnings-when-building-with-github-actions-winsdk-10
2625
- name: Configure CMake
27-
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_SYSTEM_VERSION="10.0.22621.0"
26+
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}}
2827

2928
- name: Build
3029
run: cmake --build build --config ${{env.BUILD_TYPE}} -j 2

include/glaze/api/name.hpp

+26-18
Original file line numberDiff line numberDiff line change
@@ -14,40 +14,48 @@ namespace glz
1414
{
1515
namespace detail
1616
{
17-
inline constexpr auto total_length(const auto& strs) noexcept {
17+
#ifdef _MSC_VER
18+
// Workaround for problems with MSVC and passing refrences to stringviews as template params
19+
struct string_view_wrapper
20+
{
21+
const char* start{};
1822
size_t n{};
19-
for_each<std::tuple_size_v<std::decay_t<decltype(strs)>>>([&](auto I) { n += std::get<I>(strs).size(); });
20-
return n;
21-
}
22-
23+
constexpr string_view_wrapper(std::string_view sv) : start(sv.data()), n(sv.size()) {}
24+
constexpr auto data() const { return start; }
25+
constexpr auto begin() const { return data(); }
26+
constexpr auto end() const { return data() + n; }
27+
constexpr auto size() const { return n; }
28+
};
29+
template <string_view_wrapper... Strs>
30+
#else
2331
template <const std::string_view&... Strs>
32+
#endif
2433
struct join
2534
{
2635
// Join all strings into a single std::array of chars
2736
static constexpr auto impl() noexcept
2837
{
29-
// This local copy to a tuple and avoiding of parameter pack expansion is needed to avoid MSVC internal compiler errors
30-
constexpr auto strs_tuple = std::make_tuple(Strs...);
31-
//constexpr size_t len = (Strs.size() + ... + 0);
32-
constexpr size_t len = total_length(strs_tuple);
38+
// This local copy to a tuple and avoiding of parameter pack expansion is needed to avoid MSVC internal
39+
// compiler errors
40+
constexpr size_t len = (Strs.size() + ... + 0);
3341
std::array<char, len + 1> arr{};
3442
auto append = [i = 0, &arr](const auto& s) mutable {
3543
for (auto c : s) arr[i++] = c;
3644
};
37-
38-
for_each<sizeof...(Strs)>([&](auto I) { append(std::get<I>(strs_tuple));
39-
});
40-
41-
//(append(Strs), ...);
45+
(append(Strs), ...);
4246
arr[len] = 0;
4347
return arr;
4448
}
45-
46-
static constexpr auto arr = impl(); // Give the joined string static storage
47-
static constexpr std::string_view value {arr.data(), arr.size() - 1};
49+
50+
static constexpr auto arr = impl(); // Give the joined string static storage
51+
static constexpr std::string_view value{arr.data(), arr.size() - 1};
4852
};
49-
// Helper to get the value out
53+
// Helper to get the value out
54+
#ifdef _MSC_VER
55+
template <string_view_wrapper... Strs>
56+
#else
5057
template <const std::string_view&... Strs>
58+
#endif
5159
static constexpr auto join_v = join<Strs...>::value;
5260
}
5361

include/glaze/binary/write.hpp

+23-21
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
namespace glz
1717
{
1818
namespace detail
19-
{
19+
{
2020
template <class T = void>
2121
struct to_binary {};
2222

@@ -29,15 +29,15 @@ namespace glz
2929
return to_binary<std::decay_t<T>>::template op<Opts>(
3030
std::forward<T>(value), std::forward<B>(b));
3131
}
32-
32+
3333
template <auto Opts, class T, class B, class IX>
3434
static auto op(T&& value, B&& b, IX&& ix)
3535
{
3636
return to_binary<std::decay_t<T>>::template op<Opts>(
3737
std::forward<T>(value), std::forward<B>(b), std::forward<IX>(ix));
3838
}
3939
};
40-
40+
4141
template <class T>
4242
requires (std::same_as<T, bool> || std::same_as<T, std::vector<bool>::reference> || std::same_as<T, std::vector<bool>::const_reference>)
4343
struct to_binary<T> final
@@ -61,13 +61,13 @@ namespace glz
6161
static auto op(auto&& /*value*/, Args&&... args) noexcept
6262
{ return error{}; }
6363
};
64-
64+
6565
template <class... Args>
6666
auto dump_type(auto&& value, Args&&... args) noexcept
6767
{
6868
return dump(std::as_bytes(std::span{ &value, 1 }), std::forward<Args>(args)...);
6969
}
70-
70+
7171
template <uint64_t i, class... Args>
7272
[[nodiscard]] auto dump_int(Args&&... args) noexcept
7373
{
@@ -92,7 +92,7 @@ namespace glz
9292
"size not supported");
9393
}
9494
}
95-
95+
9696
template <auto Opts, class... Args>
9797
[[nodiscard]] auto dump_int(size_t i, Args&&... args) noexcept(Opts.no_except)
9898
{
@@ -117,7 +117,7 @@ namespace glz
117117
}
118118
}
119119
}
120-
120+
121121
template <class T>
122122
requires num_t<T> || char_t<T> || glaze_enum_t<T>
123123
struct to_binary<T> final
@@ -128,7 +128,7 @@ namespace glz
128128
return dump_type(value, std::forward<Args>(args)...);
129129
}
130130
};
131-
131+
132132
template <str_t T>
133133
struct to_binary<T> final
134134
{
@@ -139,7 +139,7 @@ namespace glz
139139
dump(std::as_bytes(std::span{ value.data(), value.size() }), std::forward<Args>(args)...);
140140
}
141141
};
142-
142+
143143
template <array_t T>
144144
struct to_binary<T> final
145145
{
@@ -154,7 +154,7 @@ namespace glz
154154
}
155155
}
156156
};
157-
157+
158158
template <map_t T>
159159
struct to_binary<T> final
160160
{
@@ -168,7 +168,7 @@ namespace glz
168168
}
169169
}
170170
};
171-
171+
172172
template <nullable_t T>
173173
struct to_binary<T> final
174174
{
@@ -184,7 +184,7 @@ namespace glz
184184
}
185185
}
186186
};
187-
187+
188188
template <class T>
189189
requires glaze_object_t<T>
190190
struct to_binary<T> final
@@ -195,7 +195,7 @@ namespace glz
195195
using V = std::decay_t<T>;
196196
static constexpr auto N = std::tuple_size_v<meta_t<V>>;
197197
dump_int<N>(std::forward<Args>(args)...); // even though N is known at compile time in this case, it is not known for partial cases, so we still use a compressed integer
198-
198+
199199
for_each<N>([&](auto I) {
200200
static constexpr auto item = std::get<I>(meta_v<V>);
201201
dump_int<Opts>(I, std::forward<Args>(args)...); // dump the known key as an integer
@@ -224,19 +224,19 @@ namespace glz
224224
}
225225
};
226226
}
227-
227+
228228
template <class T, class Buffer>
229229
inline auto write_binary(T&& value, Buffer&& buffer) {
230230
return write<opts{.format = binary}>(std::forward<T>(value), std::forward<Buffer>(buffer));
231231
}
232-
232+
233233
template <class T>
234234
inline auto write_binary(T&& value) {
235235
std::string buffer{};
236236
write<opts{.format = binary}>(std::forward<T>(value), buffer);
237237
return buffer;
238238
}
239-
239+
240240
template <auto& Partial, opts Opts, class T, class Buffer>
241241
requires nano::ranges::input_range<Buffer> && (sizeof(nano::ranges::range_value_t<Buffer>) == sizeof(char))
242242
inline auto write(T&& value, Buffer& buffer) noexcept
@@ -260,9 +260,11 @@ namespace glz
260260
if constexpr (detail::glaze_object_t<std::decay_t<T>>) {
261261
static constexpr auto key_to_int = detail::make_key_int_map<T>();
262262
glz::for_each<N>([&](auto I) {
263-
static constexpr auto group = []() {
264-
return std::get<decltype(I)::value>(groups);
265-
}(); // MSVC internal compiler error workaround
263+
using index_t = decltype(I);
264+
using group_t = std::tuple_element_t<I, decltype(groups)>;
265+
static constexpr auto group = [](index_t Index) constexpr -> group_t {
266+
return std::get<Index>(groups);
267+
}({}); // MSVC internal compiler error workaround
266268
static constexpr auto key = std::get<0>(group);
267269
static constexpr auto sub_partial = std::get<1>(group);
268270
static constexpr auto frozen_map = detail::make_map<T>();
@@ -298,12 +300,12 @@ namespace glz
298300
else {
299301
throw std::runtime_error(
300302
"Invalid key for map when writing out partial message");
301-
}
303+
}
302304
});
303305
}
304306
}
305307
}
306-
308+
307309
template <auto& Partial, class T, class Buffer>
308310
inline auto write_binary(T&& value, Buffer&& buffer) {
309311
return write<Partial, opts{}>(std::forward<T>(value), std::forward<Buffer>(buffer));

0 commit comments

Comments
 (0)