libstdc++: Cleanup and stabilize format _Spec<_CharT> and _Pres_type.
These patch makes following changes to _Pres_type values:
* _Pres_esc is replaced with separate _M_debug flag.
* _Pres_s, _Pres_p do not overlap with _Pres_none.
* hexadecimal presentation use same values for pointer, integer
and floating point types.
The members of _Spec<_CharT> are rearranged so the class contains 8 bits
reserved for future use (_M_reserved) and 8 bits of tail padding.
Derived classes (like _ChronoSpec<_CharT>) can reuse the storage for initial
members. We also add _SpecBase as the base class for _Spec<_CharT> to make
it non-C++98 POD, which allows tail padding to be reused on Itanium ABI.
Finally, the format enumerators are defined as enum class with unsigned
char as underlying type, followed by using enum to bring names in scope.
_Term_char names are adjusted for consistency, and enumerator values are
changed so it can fit in smaller bitfields.
The '?' is changed to separate _M_debug flag, to allow debug format to be
independent from the presentation type, and applied to multiple presentation
types. For example it could be used to trigger memberwise or reflection based
formatting.
The _M_format_character and _M_format_character_escaped functions are merged
to single function that handle normal and debug presentation. In particular
this would allow future support for '?c' for printing integer types as escaped
character. _S_character_width is also folded in the merged function.
Decoupling _Pres_s value from _Pres_none, allows it to be used for string
presentation for range formatting, and removes the need for separate _Pres_seq
and _Pres_str. This does not affect formatting of bool as __formatter_int::_M_parse
overrides default value of _M_type. And with separation of the _M_debug flag,
__formatter_str::format behavior is now agnostic to _M_type value.
The values for integer presentation types, are arranged so textual presentations
(_Prec_s, _Pres_c) are grouped together. For consistency floating point
hexadecimal presentation uses the same values as integer ones.
New _Pres_p and setting for _M_alt enables using some spec to configure formatting
of uintptr_t with __formatter_int, and const void* with __formatter_ptr.
Differentiating it from _Pres_none would allow future of formatter<T*, _CharT>
that would require explicit presentation type to be specified. This would allow
std::vector<T*> to be formatted directly with '{::p}' format spec.
The constructors for __formatter_int and _formatter_ptr from _Spec<_CharT>,
now also set default presentation modes, as format functions expects them.
libstdc++-v3/ChangeLog:
* include/bits/chrono_io.h (_ChronoSpec::_M_locale_specific):
Declare as bit fiekd in tail-padding..
* include/bits/formatfwd.h (__format::_Align): Defined as enum
class and add using enum.
* include/std/format (__format::_Pres_type, __format::_Sign)
(__format::_WidthPrec, __format::_Arg_t): Defined as enum class
and add using enum.
(_Pres_type::_Pres_esc): Replace with _Pres_max.
(_Pres_type::_Pres_seq, _Pres_type::_Pres_str): Remove.
(__format::_Pres_type): Updated values of enumerators as described
above.
(__format::_Spec): Rearranged members to have 8 bits of tail-padding.
(_Spec::_M_debug): Defined.
(_Spec::_M_reserved): Extended to 8 bits and moved at the end.
(_Spec::_M_reserved2): Removed.
(_Spec::_M_parse_fill_and_align, _Spec::_M_parse_sign)
(__format::__write_padded_as_spec): Adjusted default value checks.
(__format::_Term_char): Add using enum and adjust enumertors.
(__Escapes::_S_term): Adjusted for _Term_char values.
(__format::__should_escape_ascii): Adjusted _Term_char uses.
(__format::__write_escaped): Adjusted for _Term_char.
(__formatter_str::parse): Set _Pres_s if specifed and _M_debug
instead of _Pres_esc.
(__formatter_str::set_debug_format): Set _M_debug instead of
_Pres_esc.
(__formatter_str::format, __formatter_str::_M_format_range):
Check _M_debug instead of _Prec_esc.
(__formatter_str::_M_format_escaped): Adjusted _Term_char uses.
(__formatter_int::__formatter_int(_Spec<_CharT>)): Set _Pres_d if
default presentation type is not set.
(__formatter_int::_M_parse): Adjusted default value checks.
(__formatter_int::_M_do_parse): Set _M_debug instead of _Pres_esc.
(__formatter_int::_M_format_character): Handle escaped presentation.
(__formatter_int::_M_format_character_escaped)
(__formatter_int::_S_character_width): Merged into
_M_format_character.
(__formatter_ptr::__formatter_ptr(_Spec<_CharT>)): Set _Pres_p if
default presentation type is not set.
(__formatter_ptr::parse): Add default __type parameter, store _Pres_p,
and handle _M_alt to be consistent with meaning for integers.
(__foramtter_ptr<_CharT>::_M_set_default): Define.
(__format::__pack_arg_types, std::basic_format_args): Add necessary
casts.
(formatter<_CharT, _CharT>::set_debug_format)
(formatter<char, wchar_t>::set_debug_format): Set _M_debug instead of
_Pres_esc.
(formatter<_CharT, _CharT>::format, formatter<char, wchar_t>::format):
Simplify calls to _M_format_character.
(range_formatter<_Rg, _CharT>::parse): Replace _Pres_str with
_Pres_s and set _M_debug instead of _Pres_esc.
(range_formatter<_Rg, _CharT>::format): Replace _Pres_str with
_Pres_s.
Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>