Skip to content

Commit

Permalink
fixed ICE in VS2019 when using /std:c++17 instead of /std:c++latest
Browse files Browse the repository at this point in the history
  • Loading branch information
marzer committed Mar 10, 2020
1 parent f0e9171 commit 3ac8c2c
Show file tree
Hide file tree
Showing 5 changed files with 224 additions and 138 deletions.
138 changes: 71 additions & 67 deletions include/toml++/toml_parser_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,73 @@ TOML_IMPL_START
return { prev_pos.line, static_cast<source_index>(prev_pos.column + fallback_offset) };
}

template <typename T, size_t N>
static void abort_with_error_concatenate(T&& arg, char(& buf)[N], char*& ptr) noexcept
{
(void)buf;

using arg_t = remove_cvref_t<T>;
if constexpr (std::is_same_v<arg_t, std::string_view> || std::is_same_v<arg_t, std::string>)
{
std::memcpy(ptr, arg.data(), arg.length());
ptr += arg.length();
}
else if constexpr (std::is_same_v<arg_t, utf8_codepoint>)
{
toml::string_view cp_view;
if (arg.value <= U'\x1F') TOML_UNLIKELY
cp_view = low_character_escape_table[arg.value];
else if (arg.value == U'\x7F') TOML_UNLIKELY
cp_view = TOML_STRING_PREFIX("\\u007F"sv);
else
cp_view = arg.template as_view<string_char>();

std::memcpy(ptr, cp_view.data(), cp_view.length());
ptr += cp_view.length();
}
else if constexpr (std::is_same_v<arg_t, char>)
{
*ptr++ = arg;
}
else if constexpr (std::is_same_v<arg_t, bool>)
{
const auto boolval = arg ? "true"sv : "false"sv;
std::memcpy(ptr, boolval.data(), boolval.length());
ptr += boolval.length();
}
else if constexpr (std::is_same_v<arg_t, node_type>)
{
const auto str = impl::node_type_friendly_names[
static_cast<std::underlying_type_t<node_type>>(arg)
];
std::memcpy(ptr, str.data(), str.length());
ptr += str.length();
}
else if constexpr (std::is_floating_point_v<arg_t>)
{
#if TOML_USE_STREAMS_FOR_FLOATS
{
std::ostringstream ss;
ss.precision(std::numeric_limits<arg_t>::digits10 + 1);
ss << arg;
const auto str = std::move(ss).str();
std::memcpy(ptr, str.c_str(), str.length());
ptr += str.length();
}
#else
{
const auto result = std::to_chars(ptr, buf + N, arg);
ptr = result.ptr;
}
#endif
}
else if constexpr (std::is_integral_v<arg_t>)
{
const auto result = std::to_chars(ptr, buf + N, arg);
ptr = result.ptr;
}
}

template <typename... T>
TOML_NORETURN
void abort_with_error(T &&... args) const TOML_MAY_THROW
Expand All @@ -90,70 +157,7 @@ TOML_IMPL_START
static constexpr auto buf_size = 512_sz;
TOML_GCC_ATTR(uninitialized) char buf[buf_size];
auto ptr = buf;
const auto concatenator = [&](auto&& arg) noexcept //a.k.a. "no stringstreams, thanks"
{
using arg_t = remove_cvref_t<decltype(arg)>;
if constexpr (std::is_same_v<arg_t, std::string_view> || std::is_same_v<arg_t, std::string>)
{
std::memcpy(ptr, arg.data(), arg.length());
ptr += arg.length();
}
else if constexpr (std::is_same_v<arg_t, utf8_codepoint>)
{
toml::string_view cp_view;
if (arg.value <= U'\x1F') TOML_UNLIKELY
cp_view = low_character_escape_table[arg.value];
else if (arg.value == U'\x7F') TOML_UNLIKELY
cp_view = TOML_STRING_PREFIX("\\u007F"sv);
else
cp_view = arg.template as_view<string_char>();

std::memcpy(ptr, cp_view.data(), cp_view.length());
ptr += cp_view.length();
}
else if constexpr (std::is_same_v<arg_t, char>)
{
*ptr++ = arg;
}
else if constexpr (std::is_same_v<arg_t, bool>)
{
const auto boolval = arg ? "true"sv : "false"sv;
std::memcpy(ptr, boolval.data(), boolval.length());
ptr += boolval.length();
}
else if constexpr (std::is_same_v<arg_t, node_type>)
{
const auto str = impl::node_type_friendly_names[
static_cast<std::underlying_type_t<node_type>>(arg)
];
std::memcpy(ptr, str.data(), str.length());
ptr += str.length();
}
else if constexpr (std::is_floating_point_v<arg_t>)
{
#if TOML_USE_STREAMS_FOR_FLOATS
{
std::ostringstream ss;
ss.precision(std::numeric_limits<arg_t>::digits10 + 1);
ss << arg;
const auto str = std::move(ss).str();
std::memcpy(ptr, str.c_str(), str.length());
ptr += str.length();
}
#else
{
const auto result = std::to_chars(ptr, buf + buf_size, arg);
ptr = result.ptr;
}
#endif
}
else if constexpr (std::is_integral_v<arg_t>)
{
const auto result = std::to_chars(ptr, buf + buf_size, arg);
ptr = result.ptr;
}
};
(concatenator(std::forward<T>(args)), ...);
(abort_with_error_concatenate(std::forward<T>(args), buf, ptr), ...);
*ptr = '\0';
#if TOML_EXCEPTIONS
TOML_ERROR(buf, current_position(1), reader.source_path());
Expand Down Expand Up @@ -1014,7 +1018,7 @@ TOML_IMPL_START
default: //??
abort_with_error(
"Error parsing "sv, node_type::floating_point,
"; an unspecified error occurred while trying to interpret '",
"; an unspecified error occurred while trying to interpret '"sv,
std::string_view{ chars, length }, "' as a value"sv
);
}
Expand Down Expand Up @@ -1211,7 +1215,7 @@ TOML_IMPL_START
default: //??
abort_with_error(
"Error parsing hexadecimal "sv, node_type::floating_point,
"; an unspecified error occurred while trying to interpret '",
"; an unspecified error occurred while trying to interpret '"sv,
std::string_view{ chars, length }, "' as a value"sv
);
}
Expand Down Expand Up @@ -1402,7 +1406,7 @@ TOML_IMPL_START
default: //??
abort_with_error(
"Error parsing "sv, traits::qualifier, ' ', node_type::integer,
"; an unspecified error occurred while trying to interpret '",
"; an unspecified error occurred while trying to interpret '"sv,
std::string_view{ chars, length }, "' as a value"sv
);
}
Expand Down
2 changes: 1 addition & 1 deletion include/toml++/toml_version.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

#define TOML_LIB_MAJOR 0
#define TOML_LIB_MINOR 4
#define TOML_LIB_PATCH 2
#define TOML_LIB_PATCH 3

#define TOML_LANG_MAJOR 0
#define TOML_LANG_MINOR 5
Expand Down
2 changes: 1 addition & 1 deletion meson.build
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
project(
'tomlplusplus',
'cpp',
version : '0.4.2',
version : '0.4.3',
license : 'MIT',
default_options : [
'cpp_std=c++17',
Expand Down
142 changes: 73 additions & 69 deletions toml.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------------------------------------------------
//
// toml++ v0.4.2
// toml++ v0.4.3
// https://github.com/marzer/tomlplusplus
// SPDX-License-Identifier: MIT
//
Expand Down Expand Up @@ -312,7 +312,7 @@

#define TOML_LIB_MAJOR 0
#define TOML_LIB_MINOR 4
#define TOML_LIB_PATCH 2
#define TOML_LIB_PATCH 3

#define TOML_LANG_MAJOR 0
#define TOML_LANG_MINOR 5
Expand Down Expand Up @@ -6299,6 +6299,73 @@ TOML_IMPL_START
return { prev_pos.line, static_cast<source_index>(prev_pos.column + fallback_offset) };
}

template <typename T, size_t N>
static void abort_with_error_concatenate(T&& arg, char(& buf)[N], char*& ptr) noexcept
{
(void)buf;

using arg_t = remove_cvref_t<T>;
if constexpr (std::is_same_v<arg_t, std::string_view> || std::is_same_v<arg_t, std::string>)
{
std::memcpy(ptr, arg.data(), arg.length());
ptr += arg.length();
}
else if constexpr (std::is_same_v<arg_t, utf8_codepoint>)
{
toml::string_view cp_view;
if (arg.value <= U'\x1F') TOML_UNLIKELY
cp_view = low_character_escape_table[arg.value];
else if (arg.value == U'\x7F') TOML_UNLIKELY
cp_view = TOML_STRING_PREFIX("\\u007F"sv);
else
cp_view = arg.template as_view<string_char>();

std::memcpy(ptr, cp_view.data(), cp_view.length());
ptr += cp_view.length();
}
else if constexpr (std::is_same_v<arg_t, char>)
{
*ptr++ = arg;
}
else if constexpr (std::is_same_v<arg_t, bool>)
{
const auto boolval = arg ? "true"sv : "false"sv;
std::memcpy(ptr, boolval.data(), boolval.length());
ptr += boolval.length();
}
else if constexpr (std::is_same_v<arg_t, node_type>)
{
const auto str = impl::node_type_friendly_names[
static_cast<std::underlying_type_t<node_type>>(arg)
];
std::memcpy(ptr, str.data(), str.length());
ptr += str.length();
}
else if constexpr (std::is_floating_point_v<arg_t>)
{
#if TOML_USE_STREAMS_FOR_FLOATS
{
std::ostringstream ss;
ss.precision(std::numeric_limits<arg_t>::digits10 + 1);
ss << arg;
const auto str = std::move(ss).str();
std::memcpy(ptr, str.c_str(), str.length());
ptr += str.length();
}
#else
{
const auto result = std::to_chars(ptr, buf + N, arg);
ptr = result.ptr;
}
#endif
}
else if constexpr (std::is_integral_v<arg_t>)
{
const auto result = std::to_chars(ptr, buf + N, arg);
ptr = result.ptr;
}
}

template <typename... T>
TOML_NORETURN
void abort_with_error(T &&... args) const TOML_MAY_THROW
Expand All @@ -6312,70 +6379,7 @@ TOML_IMPL_START
static constexpr auto buf_size = 512_sz;
TOML_GCC_ATTR(uninitialized) char buf[buf_size];
auto ptr = buf;
const auto concatenator = [&](auto&& arg) noexcept //a.k.a. "no stringstreams, thanks"
{
using arg_t = remove_cvref_t<decltype(arg)>;
if constexpr (std::is_same_v<arg_t, std::string_view> || std::is_same_v<arg_t, std::string>)
{
std::memcpy(ptr, arg.data(), arg.length());
ptr += arg.length();
}
else if constexpr (std::is_same_v<arg_t, utf8_codepoint>)
{
toml::string_view cp_view;
if (arg.value <= U'\x1F') TOML_UNLIKELY
cp_view = low_character_escape_table[arg.value];
else if (arg.value == U'\x7F') TOML_UNLIKELY
cp_view = TOML_STRING_PREFIX("\\u007F"sv);
else
cp_view = arg.template as_view<string_char>();

std::memcpy(ptr, cp_view.data(), cp_view.length());
ptr += cp_view.length();
}
else if constexpr (std::is_same_v<arg_t, char>)
{
*ptr++ = arg;
}
else if constexpr (std::is_same_v<arg_t, bool>)
{
const auto boolval = arg ? "true"sv : "false"sv;
std::memcpy(ptr, boolval.data(), boolval.length());
ptr += boolval.length();
}
else if constexpr (std::is_same_v<arg_t, node_type>)
{
const auto str = impl::node_type_friendly_names[
static_cast<std::underlying_type_t<node_type>>(arg)
];
std::memcpy(ptr, str.data(), str.length());
ptr += str.length();
}
else if constexpr (std::is_floating_point_v<arg_t>)
{
#if TOML_USE_STREAMS_FOR_FLOATS
{
std::ostringstream ss;
ss.precision(std::numeric_limits<arg_t>::digits10 + 1);
ss << arg;
const auto str = std::move(ss).str();
std::memcpy(ptr, str.c_str(), str.length());
ptr += str.length();
}
#else
{
const auto result = std::to_chars(ptr, buf + buf_size, arg);
ptr = result.ptr;
}
#endif
}
else if constexpr (std::is_integral_v<arg_t>)
{
const auto result = std::to_chars(ptr, buf + buf_size, arg);
ptr = result.ptr;
}
};
(concatenator(std::forward<T>(args)), ...);
(abort_with_error_concatenate(std::forward<T>(args), buf, ptr), ...);
*ptr = '\0';
#if TOML_EXCEPTIONS
TOML_ERROR(buf, current_position(1), reader.source_path());
Expand Down Expand Up @@ -7236,7 +7240,7 @@ TOML_IMPL_START
default: //??
abort_with_error(
"Error parsing "sv, node_type::floating_point,
"; an unspecified error occurred while trying to interpret '",
"; an unspecified error occurred while trying to interpret '"sv,
std::string_view{ chars, length }, "' as a value"sv
);
}
Expand Down Expand Up @@ -7433,7 +7437,7 @@ TOML_IMPL_START
default: //??
abort_with_error(
"Error parsing hexadecimal "sv, node_type::floating_point,
"; an unspecified error occurred while trying to interpret '",
"; an unspecified error occurred while trying to interpret '"sv,
std::string_view{ chars, length }, "' as a value"sv
);
}
Expand Down Expand Up @@ -7624,7 +7628,7 @@ TOML_IMPL_START
default: //??
abort_with_error(
"Error parsing "sv, traits::qualifier, ' ', node_type::integer,
"; an unspecified error occurred while trying to interpret '",
"; an unspecified error occurred while trying to interpret '"sv,
std::string_view{ chars, length }, "' as a value"sv
);
}
Expand Down
Loading

0 comments on commit 3ac8c2c

Please sign in to comment.