Skip to content

Commit

Permalink
Fix ICE for msv2022 and add msvc2022 workflow
Browse files Browse the repository at this point in the history
Fix ICE on join_v and partial write for msv2022 and add msvc2022 workflow
  • Loading branch information
mwalcott3 authored Nov 9, 2022
1 parent ae6b4ea commit 04add89
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 44 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: msvc
name: msvc_2019

on:
push:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: msvc_cpm
name: msvc_2022

on:
push:
Expand All @@ -17,14 +17,13 @@ env:

jobs:
build:
runs-on: windows-2019
runs-on: windows-2022

steps:
- uses: actions/checkout@v3

# 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
- name: Configure CMake
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_SYSTEM_VERSION="10.0.22621.0"
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}}

- name: Build
run: cmake --build build --config ${{env.BUILD_TYPE}} -j 2
Expand Down
44 changes: 26 additions & 18 deletions include/glaze/api/name.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,40 +14,48 @@ namespace glz
{
namespace detail
{
inline constexpr auto total_length(const auto& strs) noexcept {
#ifdef _MSC_VER
// Workaround for problems with MSVC and passing refrences to stringviews as template params
struct string_view_wrapper
{
const char* start{};
size_t n{};
for_each<std::tuple_size_v<std::decay_t<decltype(strs)>>>([&](auto I) { n += std::get<I>(strs).size(); });
return n;
}

constexpr string_view_wrapper(std::string_view sv) : start(sv.data()), n(sv.size()) {}
constexpr auto data() const { return start; }
constexpr auto begin() const { return data(); }
constexpr auto end() const { return data() + n; }
constexpr auto size() const { return n; }
};
template <string_view_wrapper... Strs>
#else
template <const std::string_view&... Strs>
#endif
struct join
{
// Join all strings into a single std::array of chars
static constexpr auto impl() noexcept
{
// This local copy to a tuple and avoiding of parameter pack expansion is needed to avoid MSVC internal compiler errors
constexpr auto strs_tuple = std::make_tuple(Strs...);
//constexpr size_t len = (Strs.size() + ... + 0);
constexpr size_t len = total_length(strs_tuple);
// This local copy to a tuple and avoiding of parameter pack expansion is needed to avoid MSVC internal
// compiler errors
constexpr size_t len = (Strs.size() + ... + 0);
std::array<char, len + 1> arr{};
auto append = [i = 0, &arr](const auto& s) mutable {
for (auto c : s) arr[i++] = c;
};

for_each<sizeof...(Strs)>([&](auto I) { append(std::get<I>(strs_tuple));
});

//(append(Strs), ...);
(append(Strs), ...);
arr[len] = 0;
return arr;
}
static constexpr auto arr = impl(); // Give the joined string static storage
static constexpr std::string_view value {arr.data(), arr.size() - 1};

static constexpr auto arr = impl(); // Give the joined string static storage
static constexpr std::string_view value{arr.data(), arr.size() - 1};
};
// Helper to get the value out
// Helper to get the value out
#ifdef _MSC_VER
template <string_view_wrapper... Strs>
#else
template <const std::string_view&... Strs>
#endif
static constexpr auto join_v = join<Strs...>::value;
}

Expand Down
44 changes: 23 additions & 21 deletions include/glaze/binary/write.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
namespace glz
{
namespace detail
{
{
template <class T = void>
struct to_binary {};

Expand All @@ -29,15 +29,15 @@ namespace glz
return to_binary<std::decay_t<T>>::template op<Opts>(
std::forward<T>(value), std::forward<B>(b));
}

template <auto Opts, class T, class B, class IX>
static auto op(T&& value, B&& b, IX&& ix)
{
return to_binary<std::decay_t<T>>::template op<Opts>(
std::forward<T>(value), std::forward<B>(b), std::forward<IX>(ix));
}
};

template <class T>
requires (std::same_as<T, bool> || std::same_as<T, std::vector<bool>::reference> || std::same_as<T, std::vector<bool>::const_reference>)
struct to_binary<T> final
Expand All @@ -61,13 +61,13 @@ namespace glz
static auto op(auto&& /*value*/, Args&&... args) noexcept
{ return error{}; }
};

template <class... Args>
auto dump_type(auto&& value, Args&&... args) noexcept
{
return dump(std::as_bytes(std::span{ &value, 1 }), std::forward<Args>(args)...);
}

template <uint64_t i, class... Args>
[[nodiscard]] auto dump_int(Args&&... args) noexcept
{
Expand All @@ -92,7 +92,7 @@ namespace glz
"size not supported");
}
}

template <auto Opts, class... Args>
[[nodiscard]] auto dump_int(size_t i, Args&&... args) noexcept(Opts.no_except)
{
Expand All @@ -117,7 +117,7 @@ namespace glz
}
}
}

template <class T>
requires num_t<T> || char_t<T> || glaze_enum_t<T>
struct to_binary<T> final
Expand All @@ -128,7 +128,7 @@ namespace glz
return dump_type(value, std::forward<Args>(args)...);
}
};

template <str_t T>
struct to_binary<T> final
{
Expand All @@ -139,7 +139,7 @@ namespace glz
dump(std::as_bytes(std::span{ value.data(), value.size() }), std::forward<Args>(args)...);
}
};

template <array_t T>
struct to_binary<T> final
{
Expand All @@ -154,7 +154,7 @@ namespace glz
}
}
};

template <map_t T>
struct to_binary<T> final
{
Expand All @@ -168,7 +168,7 @@ namespace glz
}
}
};

template <nullable_t T>
struct to_binary<T> final
{
Expand All @@ -184,7 +184,7 @@ namespace glz
}
}
};

template <class T>
requires glaze_object_t<T>
struct to_binary<T> final
Expand All @@ -195,7 +195,7 @@ namespace glz
using V = std::decay_t<T>;
static constexpr auto N = std::tuple_size_v<meta_t<V>>;
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

for_each<N>([&](auto I) {
static constexpr auto item = std::get<I>(meta_v<V>);
dump_int<Opts>(I, std::forward<Args>(args)...); // dump the known key as an integer
Expand Down Expand Up @@ -224,19 +224,19 @@ namespace glz
}
};
}

template <class T, class Buffer>
inline auto write_binary(T&& value, Buffer&& buffer) {
return write<opts{.format = binary}>(std::forward<T>(value), std::forward<Buffer>(buffer));
}

template <class T>
inline auto write_binary(T&& value) {
std::string buffer{};
write<opts{.format = binary}>(std::forward<T>(value), buffer);
return buffer;
}

template <auto& Partial, opts Opts, class T, class Buffer>
requires nano::ranges::input_range<Buffer> && (sizeof(nano::ranges::range_value_t<Buffer>) == sizeof(char))
inline auto write(T&& value, Buffer& buffer) noexcept
Expand All @@ -260,9 +260,11 @@ namespace glz
if constexpr (detail::glaze_object_t<std::decay_t<T>>) {
static constexpr auto key_to_int = detail::make_key_int_map<T>();
glz::for_each<N>([&](auto I) {
static constexpr auto group = []() {
return std::get<decltype(I)::value>(groups);
}(); // MSVC internal compiler error workaround
using index_t = decltype(I);
using group_t = std::tuple_element_t<I, decltype(groups)>;
static constexpr auto group = [](index_t Index) constexpr -> group_t {
return std::get<Index>(groups);
}({}); // MSVC internal compiler error workaround
static constexpr auto key = std::get<0>(group);
static constexpr auto sub_partial = std::get<1>(group);
static constexpr auto frozen_map = detail::make_map<T>();
Expand Down Expand Up @@ -298,12 +300,12 @@ namespace glz
else {
throw std::runtime_error(
"Invalid key for map when writing out partial message");
}
}
});
}
}
}

template <auto& Partial, class T, class Buffer>
inline auto write_binary(T&& value, Buffer&& buffer) {
return write<Partial, opts{}>(std::forward<T>(value), std::forward<Buffer>(buffer));
Expand Down

0 comments on commit 04add89

Please sign in to comment.