Skip to content

Commit

Permalink
Make scan_arg_store non-movable
Browse files Browse the repository at this point in the history
  • Loading branch information
eliaskosunen committed May 22, 2024
1 parent 16c21a4 commit b38bc53
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 25 deletions.
55 changes: 38 additions & 17 deletions include/scn/scan.h
Original file line number Diff line number Diff line change
Expand Up @@ -4623,7 +4623,7 @@ auto make_scan_buffer(Range&&) = delete;
/////////////////////////////////////////////////////////////////

namespace detail {
enum class arg_type {
enum class arg_type : unsigned char {
none_type,
schar_type,
short_type,
Expand Down Expand Up @@ -4901,7 +4901,7 @@ static_assert((1 << packed_arg_bits) >= static_cast<int>(arg_type::last_type));
constexpr std::size_t bits_in_sz = sizeof(std::size_t) * 8;
constexpr std::size_t max_packed_args = (bits_in_sz - 2) / packed_arg_bits - 1;
constexpr std::size_t is_unpacked_bit = std::size_t{1} << (bits_in_sz - 1);
constexpr std::size_t is_builtin_only_bit = std::size_t{1} << (bits_in_sz - 2);
constexpr std::size_t has_custom_types_bit = std::size_t{1} << (bits_in_sz - 2);

template <typename>
constexpr size_t encode_types_impl()
Expand Down Expand Up @@ -5159,10 +5159,10 @@ template <scan_arg_store_kind Kind, typename CharT, typename... Args>
constexpr size_t compute_arg_store_desc()
{
if constexpr (Kind == scan_arg_store_kind::builtin) {
return encode_types<CharT, Args...>() | is_builtin_only_bit;
return encode_types<CharT, Args...>();
}
else if constexpr (Kind == scan_arg_store_kind::packed) {
return encode_types<CharT, Args...>();
return encode_types<CharT, Args...>() | has_custom_types_bit;
}
else {
return sizeof...(Args) | is_unpacked_bit;
Expand Down Expand Up @@ -5203,6 +5203,12 @@ struct scan_arg_store {
typename Context::char_type>::value>(args)...};
}

scan_arg_store(const scan_arg_store&) = delete;
scan_arg_store(scan_arg_store&&) = delete;
scan_arg_store& operator=(const scan_arg_store&) = delete;
scan_arg_store& operator=(scan_arg_store&&) = delete;
~scan_arg_store() = default;

std::tuple<Args...> args;
argptrs_type argptrs;
};
Expand Down Expand Up @@ -5315,7 +5321,7 @@ class basic_scan_args {
}
SCN_NODISCARD constexpr bool is_only_builtin() const
{
return (m_desc & detail::is_builtin_only_bit) != 0;
return (m_desc & detail::has_custom_types_bit) == 0;
}

SCN_NODISCARD constexpr detail::arg_type type(std::size_t index) const
Expand All @@ -5330,7 +5336,7 @@ class basic_scan_args {
{
return SCN_LIKELY(is_packed()) ? detail::max_packed_args
: (m_desc & ~detail::is_unpacked_bit &
~detail::is_builtin_only_bit);
~detail::has_custom_types_bit);
}

size_t m_desc{0};
Expand Down Expand Up @@ -5647,6 +5653,12 @@ class scan_result : public detail::scan_result_base<Range>,

~scan_result() = default;

template <typename Context>
scan_result(range_type r, detail::scan_arg_store<Context, Args...>& store)
: range_base(SCN_MOVE(r)), value_base(SCN_MOVE(store.args))
{
}

scan_result(range_type r, tuple_type&& values)
: range_base(SCN_MOVE(r)), value_base(SCN_MOVE(values))
{
Expand All @@ -5661,6 +5673,16 @@ class scan_result : public detail::scan_result_base<Range>,
{
}

template <typename OtherR,
typename Context,
std::enable_if_t<std::is_constructible_v<range_type, OtherR>>* =
nullptr>
scan_result(OtherR&& r, detail::scan_arg_store<Context, Args...>& store)
: range_base(detail::scan_result_convert_tag{}, SCN_FWD(r)),
value_base(SCN_MOVE(store.args))
{
}

template <typename OtherR,
std::enable_if_t<
std::is_constructible_v<range_type, OtherR> &&
Expand Down Expand Up @@ -5722,6 +5744,9 @@ class scan_result : public detail::scan_result_base<Range>,

template <typename R, typename... Args>
scan_result(R, std::tuple<Args...>) -> scan_result<R, Args...>;
template <typename R, typename Ctx, typename... Args>
scan_result(R, detail::scan_arg_store<Ctx, Args...>&)
-> scan_result<R, Args...>;

namespace detail {
template <typename SourceRange>
Expand Down Expand Up @@ -8539,13 +8564,13 @@ SCN_GCC_POP // -Wnoexcept
*/
template <typename Result, typename Context, typename... Args>
auto make_scan_result(scan_expected<Result>&& result,
detail::scan_arg_store<Context, Args...>&& args)
detail::scan_arg_store<Context, Args...>& args)
-> scan_expected<scan_result<Result, Args...>>
{
if (SCN_UNLIKELY(!result)) {
return unexpected(result.error());
}
return scan_result{SCN_MOVE(*result), SCN_MOVE(args.args)};
return scan_result{SCN_MOVE(*result), args};
}

/**
Expand Down Expand Up @@ -8590,8 +8615,7 @@ SCN_NODISCARD auto scan(Source&& source,
-> scan_result_type<Source, Args...>
{
auto args = make_scan_args<scan_context, Args...>();
auto result = vscan(SCN_FWD(source), format, args);
return make_scan_result(SCN_MOVE(result), SCN_MOVE(args));
return make_scan_result(vscan(SCN_FWD(source), format, args), args);
}

/**
Expand Down Expand Up @@ -8621,8 +8645,7 @@ SCN_NODISCARD auto scan(Source&& source,
-> scan_result_type<Source, Args...>
{
auto args = make_scan_args<scan_context, Args...>(SCN_FWD(initial_args));
auto result = vscan(SCN_FWD(source), format, args);
return make_scan_result(SCN_MOVE(result), SCN_MOVE(args));
return make_scan_result(vscan(SCN_FWD(source), format, args), args);
}

/**
Expand Down Expand Up @@ -8657,8 +8680,7 @@ SCN_NODISCARD auto scan(const Locale& loc,
-> scan_result_type<Source, Args...>
{
auto args = make_scan_args<scan_context, Args...>();
auto result = vscan(loc, SCN_FWD(source), format, args);
return make_scan_result(SCN_MOVE(result), SCN_MOVE(args));
return make_scan_result(vscan(loc, SCN_FWD(source), format, args), args);
}

/**
Expand All @@ -8678,8 +8700,7 @@ SCN_NODISCARD auto scan(const Locale& loc,
-> scan_result_type<Source, Args...>
{
auto args = make_scan_args<scan_context, Args...>(SCN_FWD(initial_args));
auto result = vscan(loc, SCN_FWD(source), format, args);
return make_scan_result(SCN_MOVE(result), SCN_MOVE(args));
return make_scan_result(vscan(loc, SCN_FWD(source), format, args), args);
}

/**
Expand Down Expand Up @@ -8737,7 +8758,7 @@ SCN_NODISCARD auto input(scan_format_string<std::FILE*, Args...> format)
if (SCN_UNLIKELY(!err)) {
return unexpected(err);
}
return scan_result{stdin, SCN_MOVE(args.args)};
return scan_result{stdin, args};
}

/**
Expand Down
12 changes: 4 additions & 8 deletions include/scn/xchar.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,7 @@ SCN_NODISCARD auto scan(Source&& source,
-> scan_result_type<Source, Args...>
{
auto args = make_scan_args<wscan_context, Args...>();
auto result = vscan(SCN_FWD(source), format, args);
return make_scan_result(SCN_MOVE(result), SCN_MOVE(args));
return make_scan_result(vscan(SCN_FWD(source), format, args), args);
}

/**
Expand All @@ -105,8 +104,7 @@ SCN_NODISCARD auto scan(Source&& source,
-> scan_result_type<Source, Args...>
{
auto args = make_scan_args<wscan_context, Args...>(SCN_MOVE(initial_args));
auto result = vscan(SCN_FWD(source), format, args);
return make_scan_result(SCN_MOVE(result), SCN_MOVE(args));
return make_scan_result(vscan(SCN_FWD(source), format, args), args);
}

/**
Expand All @@ -125,8 +123,7 @@ SCN_NODISCARD auto scan(const Locale& loc,
-> scan_result_type<Source, Args...>
{
auto args = make_scan_args<wscan_context, Args...>();
auto result = vscan(loc, SCN_FWD(source), format, args);
return make_scan_result(SCN_MOVE(result), SCN_MOVE(args));
return make_scan_result(vscan(loc, SCN_FWD(source), format, args), args);
}

/**
Expand All @@ -146,8 +143,7 @@ SCN_NODISCARD auto scan(const Locale& loc,
-> scan_result_type<Source, Args...>
{
auto args = make_scan_args<wscan_context, Args...>(SCN_MOVE(initial_args));
auto result = vscan(loc, SCN_FWD(source), format, args);
return make_scan_result(SCN_MOVE(result), SCN_MOVE(args));
return make_scan_result(vscan(loc, SCN_FWD(source), format, args), args);
}

/**
Expand Down

0 comments on commit b38bc53

Please sign in to comment.