Privatization

This commit is contained in:
Victor Zverovich 2023-12-31 15:06:17 -08:00
parent a5bacf3fef
commit 138a64bfb1

View File

@ -322,38 +322,44 @@ template <typename Context> class basic_scan_arg {
private: private:
using scan_type = detail::scan_type; using scan_type = detail::scan_type;
scan_type type_; scan_type type_;
public:
// TODO: make private
union { union {
int* int_value; int* int_value_;
unsigned* uint_value; unsigned* uint_value_;
long long* long_long_value; long long* long_long_value_;
unsigned long long* ulong_long_value; unsigned long long* ulong_long_value_;
std::string* string; std::string* string_;
fmt::string_view* string_view; fmt::string_view* string_view_;
detail::custom_scan_arg<Context> custom; detail::custom_scan_arg<Context> custom_;
// TODO: more types // TODO: more types
}; };
template <typename T>
static void scan_custom_arg(void* arg, scan_parse_context& parse_ctx,
Context& ctx) {
auto s = scanner<T>();
parse_ctx.advance_to(s.parse(parse_ctx));
ctx.advance_to(s.scan(*static_cast<T*>(arg), ctx));
}
public:
FMT_CONSTEXPR basic_scan_arg() FMT_CONSTEXPR basic_scan_arg()
: type_(scan_type::none_type), int_value(nullptr) {} : type_(scan_type::none_type), int_value_(nullptr) {}
FMT_CONSTEXPR basic_scan_arg(int& value) FMT_CONSTEXPR basic_scan_arg(int& value)
: type_(scan_type::int_type), int_value(&value) {} : type_(scan_type::int_type), int_value_(&value) {}
FMT_CONSTEXPR basic_scan_arg(unsigned& value) FMT_CONSTEXPR basic_scan_arg(unsigned& value)
: type_(scan_type::uint_type), uint_value(&value) {} : type_(scan_type::uint_type), uint_value_(&value) {}
FMT_CONSTEXPR basic_scan_arg(long long& value) FMT_CONSTEXPR basic_scan_arg(long long& value)
: type_(scan_type::long_long_type), long_long_value(&value) {} : type_(scan_type::long_long_type), long_long_value_(&value) {}
FMT_CONSTEXPR basic_scan_arg(unsigned long long& value) FMT_CONSTEXPR basic_scan_arg(unsigned long long& value)
: type_(scan_type::ulong_long_type), ulong_long_value(&value) {} : type_(scan_type::ulong_long_type), ulong_long_value_(&value) {}
FMT_CONSTEXPR basic_scan_arg(std::string& value) FMT_CONSTEXPR basic_scan_arg(std::string& value)
: type_(scan_type::string_type), string(&value) {} : type_(scan_type::string_type), string_(&value) {}
FMT_CONSTEXPR basic_scan_arg(fmt::string_view& value) FMT_CONSTEXPR basic_scan_arg(fmt::string_view& value)
: type_(scan_type::string_view_type), string_view(&value) {} : type_(scan_type::string_view_type), string_view_(&value) {}
template <typename T> template <typename T>
FMT_CONSTEXPR basic_scan_arg(T& value) : type_(scan_type::custom_type) { FMT_CONSTEXPR basic_scan_arg(T& value) : type_(scan_type::custom_type) {
custom.value = &value; custom_.value = &value;
custom.scan = scan_custom_arg<T>; custom_.scan = scan_custom_arg<T>;
} }
constexpr explicit operator bool() const noexcept { constexpr explicit operator bool() const noexcept {
@ -368,31 +374,30 @@ template <typename Context> class basic_scan_arg {
case scan_type::none_type: case scan_type::none_type:
break; break;
case scan_type::int_type: case scan_type::int_type:
return vis(*int_value); return vis(*int_value_);
case scan_type::uint_type: case scan_type::uint_type:
return vis(*uint_value); return vis(*uint_value_);
case scan_type::long_long_type: case scan_type::long_long_type:
return vis(*long_long_value); return vis(*long_long_value_);
case scan_type::ulong_long_type: case scan_type::ulong_long_type:
return vis(*ulong_long_value); return vis(*ulong_long_value_);
case scan_type::string_type: case scan_type::string_type:
return vis(*string); return vis(*string_);
case scan_type::string_view_type: case scan_type::string_view_type:
return vis(*string_view); return vis(*string_view_);
case scan_type::custom_type: case scan_type::custom_type:
// TODO: implement
break; break;
} }
return vis(monostate()); return vis(monostate());
} }
private: auto scan_custom(const char* parse_begin,
template <typename T> scan_parse_context& parse_ctx,
static void scan_custom_arg(void* arg, scan_parse_context& parse_ctx, Context& ctx) const -> bool {
Context& ctx) { if (type_ != scan_type::custom_type) return false;
auto s = scanner<T>(); parse_ctx.advance_to(parse_begin);
parse_ctx.advance_to(s.parse(parse_ctx)); custom_.scan(custom_.value, parse_ctx, ctx);
ctx.advance_to(s.scan(*static_cast<T*>(arg), ctx)); return true;
} }
}; };
@ -449,6 +454,7 @@ const char* parse_scan_specs(const char* begin, const char* end,
} }
struct default_arg_scanner { struct default_arg_scanner {
// TODO: storing a range can be more efficient
using iterator = scan_buffer::iterator; using iterator = scan_buffer::iterator;
iterator begin; iterator begin;
iterator end; iterator end;
@ -590,11 +596,8 @@ struct scan_handler : error_handler {
auto on_format_specs(int arg_id, const char* begin, const char* end) -> const auto on_format_specs(int arg_id, const char* begin, const char* end) -> const
char* { char* {
scan_arg arg = scan_ctx_.arg(arg_id); scan_arg arg = scan_ctx_.arg(arg_id);
if (arg.type() == scan_type::custom_type) { if (arg.scan_custom(begin, parse_ctx_, scan_ctx_))
parse_ctx_.advance_to(begin);
arg.custom.scan(arg.custom.value, parse_ctx_, scan_ctx_);
return parse_ctx_.begin(); return parse_ctx_.begin();
}
auto specs = format_specs<>(); auto specs = format_specs<>();
begin = parse_scan_specs(begin, end, specs, arg.type()); begin = parse_scan_specs(begin, end, specs, arg.type());
if (begin == end || *begin != '}') on_error("missing '}' in format string"); if (begin == end || *begin != '}') on_error("missing '}' in format string");