This document is still a work in progress. |
1. List of printable types
1.1. Strings
- Types
-
const CharT*
,std::basic_string_view<CharT, Traits>
andstd::basic_string<CharT, Traits, Alloc>
where:
-
CharT
is the character type. If it is not the same as the output character type, then it is necessary to use thetranscode
orsani
format function. -
Traits
can be any type that satisfies CharTraits -
Alloc
can be any type that satisfies Allocator
-
- Overridable
-
No
- Representative type
-
string_input_tag<CharT>
, wherestring_input_tag
is defined as below:namespace strf { struct string_input_tag_base {}; template <typename CharT> struct string_input_tag: string_input_tag_base{} } // namespace strf
- Influenced by facet categories
- Format functions
1.2. Single characters
- Type
-
The same as the output character type or
char32_t
. In the later case, the UTF-32 character is encoded to the destination charset. - Representative type
-
The same as the input type
- Overridable
-
No
- FormatSpecifier types
- Influenced by facet categories
-
-
charset_c<CharType>
: in two situations:-
when using alignment formatting
-
when the character type is
char32_t
and the destination character type is notchar32_t
.
-
1.3. bool
- Type
-
bool
- Representative type
-
bool
- Overridable
-
Yes
- FormatSpecifier types
- Influenced by facet categories
-
-
charset_c<CharType>
: Used to encode the fill character.
1.4. const void*
- Types
-
const void*
- Representative type
-
const void*
- Overridable
-
Yes
- FormatSpecifier types
- Influenced by facet categories
-
-
charset_c<CharType>
: Used to encode the fill character.
1.5. Integers
- Types
-
short
,int
,long int
,long long int
,unsigned short
,unsigned int
,unsigned long int
andunsigned long long int
- Representative type
-
The same as the input type (
short
,int
,long int
,long long int
,unsigned short
,unsigned int
,unsigned long int
orunsigned long long int
) - Overridable
-
No
- FormatSpecifier types
- Influenced by facet categories
-
-
numpunct_c<Base>
-
charset_c<CharType>
: Used to encode the fill character and the punctuation characters.
1.6. Floating Points
- Types
-
float
,double
- Representative type
-
The same as the input type (
float
ordouble
) - Overridable
-
Yes
- FormatSpecifier types
- Influenced by facet categories
-
-
numpunct_c<10>
-
numpunct_c<16>
-
charset_c<CharType>
: Used to encode the fill character and the punctuation characters.
1.7. Ranges
Without formatting
namespace strf {
template <typename Range>
/*...*/ range(const Range& r);
template <typename T, std::size_t N>
/*...*/ range(T (&array)[N]);
template <typename Iterator>
/*...*/ range(const Iterator& begin, const Iterator& end);
// With operation
template <typename Range, typename UnaryOperation>
/*...*/ range(const Range& r, UnaryOperation unary_op);
template <typename T, std::size_t N, typename UnaryOperation>
/*...*/ range(T (&array)[N], UnaryOperation unary_op);
template <typename Iterator, typename UnaryOperation>
/*...*/ range( const Iterator& begin
, const Iterator& end
, UnaryOperation unary_op );
// With separator:
template <typename Range, typename CharT>
/*...*/ separated_range(const Range& r, const CharT* separator);
template <typename T, std::size_t N, typename CharT>
/*...*/ separated_range(T (&array)[N], const CharT* separator);
template <typename Iterator, typename CharT>
/*...*/ separated_range( const Iterator& begin
, const Iterator& end
, const CharT* separator );
// With separator and operation
template <typename Range, typename CharT, typename UnaryOperation>
/*...*/ separated_range( const Range& r
, const CharT* separator
, UnaryOperation unary_op );
template <typename T, std::size_t N, typename CharT, typename UnaryOperation>
/*...*/ separated_range( T (&array)[N]
, const CharT* separator
, UnaryOperation unary_op );
template <typename Iterator, typename CharT, typename UnaryOperation>
/*...*/ separated_range( const Iterator& begin
, const Iterator& end
, const CharT* separator
, UnaryOperation unary_op );
} // namespace strf
int arr[3] = { 11, 22, 33 };
auto str = strf::to_string(strf::range(arr));
assert(str == "112233");
str = strf::to_string(strf::separated_range(arr, ", "));
assert(str == "11, 22, 33");
auto op = [](auto x){ return strf::join('(', +strf::fmt(x * 10), ')'); };
str = strf::to_string(strf::separated_range(arr, ", ", op));
assert(str == "(+110), (+220), (+330)");
With formatting
namespace strf {
template <typename Range>
/*...*/ fmt_range(const Range& r);
template <typename T, std::size_t N>
/*...*/ fmt_range(T (&array)[N], const Range& r);
template <typename Iterator>
/*...*/ fmt_range(const Iterator& begin, const Iterator& end);
// With separator
template <typename Range, typename CharT>
/*...*/ fmt_separated_range(const Range& r, const CharT* separator);
template <typename T, std::size_t N, typename CharT>
/*...*/ fmt_separated_range(T (&array)[N], const CharT* separator);
template <typename Iterator, typename CharT>
/*...*/ fmt_separated_range( const Iterator& begin
, const Iterator& end
, const CharT* separator );
} // namespace strf
Any format function applicable to the element type of the
range can also be applied to the
expression strf::fmt_range(/*...*/)
or
strf::fmt_separated_range(/*...*/)
.
This way the format functions is applied to all elements:
std::vector<int> vec = { 11, 22, 33 };
auto str1 = strf::to_string("[", +strf::fmt_separated_range(vec, " ;") > 4, "]");
assert(str1 == "[ +11 ; +22 ; +33]");
std::vector<int> vec = { 11, 22, 33 };
auto str2 = strf::to_string
( "["
, *strf::fmt_separated_range(vec, " / ").fill('.').hex() > 6,
" ]");
assert(str2 == "[..0xfa / ..0xfb / ..0xfc]");
1.8. Joins
Without alignment
namespace strf {
template <typename ... Args>
/*...*/ join(const Args& ... args);
}
With alignment
You can apply the alignment format functions
one the return type of join(args...)
auto str = strf::to_string
("---", strf::join("abc", "def", 123) > 15, "---");
assert(str == "--- abcdef123---");
The functions below provide an alternartive syntax to create aligned
join. Their return type has the operator()(const Args& ... args)
member function
that receives the elements of the join.
namespace strf {
enum class text_alignment {left, right, center};
/* ... */ join_align( std::int16_t width
, text_alignment align
, char32_t fillchar = U' ' );
/* ... */ join_center(int width, char32_t fillchar = U' ');
/* ... */ join_left(int width, char32_t fillchar = U' ');
/* ... */ join_right(int width, char32_t fillchar = U' ');
}
auto str = strf::to_string
("---", strf::join_right(15) ("abc", "def", 123), "---");
assert(str == "--- abcdef123---");
str = strf::to_string
("---", strf::join_center(15) ("abc", "def", 123), "---");
assert(str == "--- abcdef123 ---");
str = strf::to_string
( "---"
, strf::join_left(15, U'.') ("abc", strf::right("def", 5), 123)
, "---" );
assert(str == "---abc def123....---");
1.9. Tr-string
- Type
-
The return type of the
tr
function template which is described further - Overridable
-
No
- Influenced by facets category
The tr
function template
namespace strf {
template <typename StringType, typename… Args>
/*...*/ tr(const StringType& str, Args&&... args);
}
- Compile-time requirements
-
-
StringType
must be either:-
an instance of
std::basic_string
orstd::basic_string_view
whose first template paramenter ( the character type ) is the same as the output character type; or -
implicitly convertible to
std::basic_string_view<CharT>
, whereCharT
is the output character type
-
-
All types in
std::remove_cv_t<Args>...
must be Printable
-
- Effect
-
Returns a value that is printable. The content to be printed is the result of parsing
str
against the Tr-string syntax, as explained below.
Tr-string Syntax
A '{' followed by |
until | means |
---|---|---|
|
the next |
a comment |
a digit |
the next |
a positional argument reference |
another |
the second |
an escaped |
any other character |
the next |
a non positional argument reference |
Examples:
const char* tr_string =
"You can learn more about python{-the programming language, not the reptile} at {}";
auto str = strf::to_string( strf::tr(tr_string, "www.python.org" ) );
assert(str == "You can learn more about python at www.python.org");
const char* tr_string = "{1 a person} likes {0 a food type}";
auto str = strf::to_string(strf::tr(tr_string, "sandwich", "Paul"), '.');
assert(str == "Paul likes sandwich.");
const char* tr_string = "{a person} likes {a food type}"
auto str = strf::to_string(strf::tr(tr_string, "Paul", "sandwich"), '.');
assert(str == "Paul likes sandwich.");
auto str = strf::to_string(strf::tr("} {{x} {{{} {{{}}", "aaa", "bbb"));
assert(str == "} {x} {aaa {bbb}");
Syntax error handling
When the argument associated with a "{"
does not exist, the library does two things:
-
It prints a replacement character
"\uFFFD"
(�) ( or"?"
when the charset can’t represent it ) where the missing argument would be printed. -
It calls the
handle
function on the facet object correspoding to thetr_error_notifier_c
category.
Facet category tr_error_notifier_c
For a type to be a facet of the tr_error_notifier_c
, it must satisfy the
requirements of TrErrorHandling
namespace strf {
struct tr_error_notifier_c {
static constexpr default_tr_error_notifier get_default() noexcept
{
return default_tr_error_notifier{};
}
};
} // namespace strf
Struct default_tr_error_notifier
default_tr_error_notifier
is the default facet of the tr_error_notifier_c
category.
It’s a dummy error handler.
namespace strf {
struct default_tr_error_notifier {
using category = tr_error_notifier_c;
template <typename Charset>
void handle
( const typename Charset::code_unit* str
, std::ptrdiff_t str_len
, Charset charset
, std::ptrdiff_t err_pos ) noexcept
{
}
};
} // namespace strf
Type requirement TrErrorHandling
Given:
-
X
, a TrErrorHandling type -
x
, a value of typeX
-
CharsetT
, a Charset type. -
charset
, a value of typeCharsetT
-
str
, a value of typeconst CharsetT::code_unit*
pointing to string encoded according tocharset
-
str_len
, astd::ptrdiff_t
value equal to the length of the stringstr
-
err_pos
, astd::ptrdiff_t
value less than or equal tostr_len
The following must host:
-
X
is CopyConstructible. -
X::category
is a type alias totr_error_notifier_c
-
The following expression is supported:
x.handle(str, str_len, charset, err_pos)
Semantics |
|
1.10. Facets
It is possible to override facets to only a subset of the input arguments.
namespace strf {
template < typename FPack >
class inner_pack
{
public:
template <typename... Args>
/*...*/ operator()(const Args&... args) const;
//...
};
template <typename ... Facets>
inner_pack</*...*/> with(const Facets&... facets);
auto str = strf::to_string.with(strf::numpunct<10>(1))
( !strf::dec(10000)
, " "
, !strf::hex(0x10000)
, strf::with( strf::numpunct<10>(3)
, strf::numpunct<16>(4).thousands_sep('\'') )
( " { "
, !strf::dec(10000)
, " "
, !strf::hex(0x10000)
, " }" ) );
assert(str == "1,0,0,0,0 10000 { 10,000 1'0000 }");
auto fp = strf::pack
( strf::numpunct<10>(3)
, strf::numpunct<16>(4).thousands_sep('\'') );
auto str = strf::to_string.with(strf::numpunct<10>(1))
( !strf::dec(10000)
, " "
, !strf::hex(0x10000)
, strf::with(fp)
( " { "
, !strf::dec(10000)
, " "
, !strf::hex(0x10000)
, strf::with
(strf::numpunct<10>(2).thousands_sep('.'))
(" { ", !strf::dec(10000), " }")
, " }" ) );
assert(str == "1,0,0,0,0 10000 { 10,000 1'0000 { 1.00.00 } }");
2. Format functions
2.1. Global format functions
namespace strf {
inline namespace format_functions {
constexpr /*…*/ right {};
constexpr /*…*/ left {};
constexpr /*…*/ center {};
constexpr /*…*/ pad0 {};
constexpr /*…*/ punct {};
constexpr /*…*/ hex {};
constexpr /*…*/ dec {};
constexpr /*…*/ oct {};
constexpr /*…*/ bin {};
constexpr /*…*/ fixed {};
constexpr /*…*/ sci {};
constexpr /*…*/ gen {};
constexpr /*…*/ multi {};
constexpr /*…*/ sani {};
template <typename T>
constexpr /*…*/ transcode(T&& value);
template <typename T, typename Charset>
constexpr /*…*/ transcode(T&& value, Charset&& charset);
template <typename T>
constexpr /*…*/ unsafe_transcode(T&& value);
template <typename T, typename Charset>
constexpr /*…*/ unsafe_transcode(T&& value, Charset&& charset);
} // inline namespace format_functions
} // namespace strf
The format_functions
inline namespace contains callable objects
that work as alias to format functions
Expression | Equivalent Expression |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2.2. Type requirement FormatSpecifier
A type Fmt
is a FormatSpecifier if it has a member fn
that is a type template
with one template type parameter such that, given any types T
and U
:
-
Fmt::template fn<T>
is well-formed ifT
isvalue_and_format<ValueType, Fmts...>
. In this case, note thatFmt
is inFmts...
andT
derives fromFmt::template fn<T>
. -
Fmt::template fn<T>
is default constructible, assuming it is well-formed. -
Fmt::template fn<T>
can be constructed fromconst Fmt::template fn<U>&
, if both are well-formed.
2.3. FormatSpecifier alignment_format_specifier
The FormatSpecifier defines the following format functions:
Format functions | Effect |
---|---|
|
Aligns to the left ( Or to the right on right-to-left (RTL) scripts, like Arabic ) |
|
Aligns to the right ( Or to the left on RTL scripts ) |
|
Center alignment |
|
Sets the fill character. |
|
Set all alignment formatting options simultaneously. |
|
Set all alignment formatting options to default. |
|
Set all alignment formatting options to default. |
And the following observers:
Observers | Return type |
---|---|
|
|
|
|
Enumeration text_alignment
namespace strf {
enum class text_alignment {left, right, center};
}
struct alignment_format
namespace strf {
struct alignment_format {
char32_t fill = U' ';
width_t width = 0;
text_alignment alignment = text_alignment::right;
};
} // namespace strf
struct default_alignment_format
namespace strf {
struct default_alignment_format {
static constexpr char32_t fill = U' ';
static constexpr width_t width = 0;
static constexpr text_alignment alignment = text_alignment::right;
constexpr operator alignment_format () const noexcept
{
return {};
}
};
} // namespace strf
2.4. FormatSpecifier int_format_specifier
This FormatSpecifier defines the following format functions:
Member function | Effect |
---|---|
|
Uses the binary base. |
|
Uses the octal base. |
|
Uses the decimal base. |
|
Uses the hexadecimal base. |
|
Equivalent to the |
|
Equivalent to the |
|
Equivalent to |
|
Similar to the |
|
Applies the numeric punctuation according to the |
|
Equivalent to |
Inserts zeros after the sign or base indication and before the digits
such that at least |
|
Inserts zeros after the sign or base indication and before the digits
such that at least |
|
|
Set all integers formatting options simultaneously. |
|
Reset all integers formatting options to default. |
And the following observer:
Observer | Return type |
---|---|
|
|
Type requirements IntFormat
Given:
-
F
, a InttFormat type -
f
, a value of typeF
The following must hold:
-
F
is copy-constructible -
F
is convertible toint_format
-
F
has public member variables below:
Member | Type | Semantics / effect |
---|---|---|
|
|
Numeric base ( must be euqal to |
|
|
See |
|
|
See |
|
|
See enumeration |
|
|
Equivalent to the |
|
|
Activates numeric punctuation. |
Struct template int_format
namespace strf {
struct int_format {
int base = 10;
int precision = 0;
int pad0width = 0;
showsign sign = showsign::negative_only;
bool showbase = false;
};
} // namespace strf
Struct template default_int_format
namespace strf {
struct default_int_format {
constexpr static int base = 10;
constexpr static int precision = 0;
constexpr static int pad0width = 0;
constexpr static strf::showsign sign = strf::showsign::negative_only;
constexpr static bool showbase = false;
constexpr static bool punctuate = false;
constexpr operator int_format () const
{
return {};
}
};
} // namespace strf
Enumeration showsign
namespace strf {
enum class showsign {
negative_only = …, positive_also = …, fill_instead_of_positive = …
};
} // namespace strf
showsign::negative_only
-
A sign is printed only before negative numbers.
showsign::positive_also
-
Negatives numbers are prefixed with
'-'
and non-negatives number are prefixed with'+'
. showsign::fill_instead_of_positive
-
Negatives numbers are prefixed with
'-'
and non-negatives number are prefixed with the fill character ( from alignment formatting ).
2.5. FormatSpecifier float_format_specifier
The float_format_specifier
FormatSpecifier defines the following format functions:
Member function | Effect |
---|---|
|
Equivalent to the |
|
Equivalent to the |
|
Similar to the |
|
Equivalent to |
|
Applies the numeric punctuation according to the |
|
Equivalent to |
Similar to the For NaN and infinity, causes the the width ( from alignment
formatting ) to be at least equal to For valid numbers, prints zeros after the sign and the base
indication and before the digits such that at least |
|
|
Sets the precision. Effect varies according to the notation ( see below ). |
|
Sets the float notation ( see below ). |
|
Equivalent to |
|
Equivalent to |
|
Equivalent to |
|
Equivalent to |
|
Set all floating-point formatting options simultaneously. |
|
Reset all floating-point formatting options to default. |
And the following observers:
Observer | Return type |
---|---|
|
|
Enumeration float_notation
namespace strf {
enum class float_notation {fixed, scientific, general, hex};
};
float_notation::hex
-
Hexadecimal
float_notation::fixed
-
If precision is not set, prints the smallest number of digits such that the floating-point value can be exactly recovered. If precision is set, it is the number of fractional digits.
float_notation::scientific
-
If precision is not set, prints the smallest number of digits such that the floating-point value can be exactly recovered. If precision is set, it is the number of fractional digits.
float_notation::general
-
If precision is not set, chooses the notation ( scientific or fixed ) that leads to the smallest number or characters such that the floating-point value can be exactly recovered.
If precision is set, same effect as the'g'
format flags inprintf
( except that the lettercase is specified by the lettercase facet ):-
The precision is the number of significant digts
-
If precision is 0, it is treated as 1
-
Trailing fractional zeros are removed unless
operator*
is used. -
Selects the scientific notation iff the resulting exponent is less than -4 or greater than or equal to the precision
-
Type requirements FloatFormat
Given:
-
F
, a FloatFormat type -
f
, a value of typeF
The following must hold:
-
F
is copy-constructible -
F
is convertible tofloat_format
-
F
has public member variables below:
Member | Type | Semantics / effect |
---|---|---|
|
|
Floating-point precision. When negative, then precision is considered as not specified, which means that the number or significant digits is such that the value can be fully recovered by a parser. Otherwise, the effect depends on |
|
|
Same as of format function |
|
See enumeration |
|
|
|
See enumeration |
|
|
Equivalent to the |
|
|
Activates numeric punctuation. |
Struct template float_format
namespace strf {
enum class float_notation {fixed, scientific, general, hex};
struct float_format
{
int precision = -1;
int pad0width = 0;
float_notation notation = float_notation::general
showsign sign = showsign::negative_only;
bool showpoint = false;
bool showpos = false;
};
} // namespace strf
Struct template default_float_format
namespace strf {
struct default_float_format
{
constexpr static int precision = -1;
constexpr static int pad0width = 0;
constexpr static float_notation notation = float_notation::general;
constexpr static showsign sign = showsign::negative_only;
constexpr static bool showpoint = false;
constexpr static bool punctuate = false;
constexpr operator float_format () const noexcept;
};
} // namespace strf
2.6. FormatSpecifier quantity_format_specifier
The quantity_format_specifier
FormatSpecifier defines the following format functions:
Member function | Effect |
---|---|
|
Causes the content to be printed |
And the following observers:
Observer | Return type | Return value |
---|---|---|
|
|
|
|
|
|
2.7. String precision
( The FormatSpecifier that defines the function below is implementation-defined )
p(width_t limit)
-
Prints the whole string only if its width is not greater than
limit
. Otherwise, prints its longest leading sub-string whose width is not greater thanlimit
.
2.8. Transcoding format functions
( The FormatSpecifier that defines the functions below is implementation-defined )
template <typename Charset>
transcode(Charset cs)
Transcodes the input string if cs
is different from the
output charset, otherwise just copies it as in memcpy
.
( The output charset is defined by the facet value
of the {charset_c}<CharOut>
facet category,
where CharOut
is the destination character type )
template <typename Charset>
unsafe_transcode(Charset cs)
Same as in trancode(cs)
, except that the behaviour is
undefined if the input string is not fully conformant
to the encoding represent by cs
,
but it provides a better performance.
template <typename Charset>
sani(Charset cs)
If cs
is different from the ouput charset, transcodes the
input string just like in transcode
. If they
are the same, sanitizes the input string.
That is, in both cases, any non-conformity to the input charset
is replaced by the replacement character ( "\uFFFD"
or '?'
),
and causes the function
transcoding_error_notifier::invalid_sequence
to be called, if the TranscodingErrorNotifierPtr
facet object is not null.
transcode()
Equivalent to transcode(cs)
where cs
is the facet value
for the charset_c<CharIn>
facet category, where CharIn
is the character type of the input string.
unsafe_transcode()
Equivalent to unsafe_transcode(cs)
where cs
is the facet value
for the charset_c<CharIn>
facet category, where CharIn
is the character type of the input string.
sani()
Equivalent to sani(cs)
where cs
is the facet value
for the charset_c<CharIn>
facet category, where CharIn
is the character type of the input string.
auto str = strf::to_string(strf::center(u" Hello! ", 16, '*').transcode());
assert(str == "**** Hello! ****");
2.9. Callable object fmt
namespace strf {
template <typename T>
using fmt_value_type = typename fmt_type<T>::value_type;
constexpr struct /*…*/ {
template <typename T>
constexpr /*…*/ operator()(T&& value) const;
} fmt;
} // namespace strf
Member function
constexpr /* see below...*/ operator()(T&& value) const;
- Return value
-
-
value
, ifstd::remove_cvref_t<T>
is an instance ofvalue_and_format
-
fmt_type<T>{ fmt_value_type<T>{ (T&&)value } }
, otherwise
-
- Return type
-
-
T&&
, ifstd::remove_cvref<T>
is an instance ofvalue_and_format
-
fmt_type<T>
, otherwise
-
2.10. Type alias template fmt_type
namespace strf {
template <typename T>
using fmt_type = /*…*/;
} // namespace strf
fmt_type<T>
is:
-
fmt_type<T>
, ifT
is a reference or has any cv-qualifier -
otherwise, it is
T
, ifT
is an instance ofvalue_and_format
-
otherwise, it is
value_and_format<PrintableDef, Fmts...>
, where:-
PDef
isprintable_def_of<T>
-
Fmts...
is template paramenter pack used to definePrintableDef::format_specifiers
( as a type alias totag<Fmt...>
).-
If
PrintableDef::format_specifiers
is not defined,T
isvalue_and_format<PrintableDef>
.
-
-
2.11. Class template value_and_format
namespace strf {
template <typename PrintableDef, class... Fmts>
class value_and_format;
} // namespace strf
- Compile-time requirements
-
-
PrintableDef
satisfies PrintableDef. -
All types in
Fmt...
satisfy FormatSpecifier. -
All types in
Fmt...
are different.
-
Synopsis
namespace strf {
template <typename PrintableDef, class... Fmts>
class value_and_format
: public Fmts::template fn<value_and_format<ValueType, Fmts...>>...
{
public:
using printable_def = PrintableDef;
using value_type = typename PrintableDef::forwarded_type;
constexpr explicit value_and_format(const value_type& v);
template <typename... OtherFmts>
constexpr explicit value_and_format
( const value_and_format<PrintableDef, OtherFmts...>& f );
template <typename... OtherFmts>
constexpr explicit value_and_format
( value_and_format<PrintableDef, OtherFmts...>&& f );
template <typename OtherPrintableDef>
constexpr value_and_format
( const value_type& v
, const value_and_format<OtherPrintableDef, Fmts...>& f );
template <typename OtherPrintableDef>
constexpr value_and_format
( const value_type& v
, value_and_format<OtherPrintableDef, Fmts...>&& f );
template <typename... F, typename... FInit>
constexpr value_and_format
( const value_type& v
, tag<F...>
, FInit&&... finit );
template
< typename OtherPrintableDef
, typename... OtherFmts
, typename Fmt
, typename... FmtInitArgs >
constexpr value_and_format
( const value_and_format<PrintableDef, OtherFmts...>& other
, tag<Fmt>
, FmtInitArgs&&... fmt_init );
constexpr const value_type& value() const;
constexpr value_type& value();
private:
value_type value_; // exposition only
};
} // namespace strf
constexpr value_and_format(const value_type& v);
- Effects
-
-
Initializes
value_
withv
-
Default initializes all public base class subobjects
-
template <typename... OtherFmts>
constexpr explicit value_and_format
( const value_and_format<PrintableDef, OtherFmts...>& f );
- Effects
-
-
Initializes
value_
withf.value()
-
Initializes each public base class subobjects with the corresponding base class subobject of
f
-
template <typename... OtherFmts>
constexpr explicit value_and_format
( value_and_format<PrintableDef, OtherFmts...>&& f );
- Effects
-
-
Initializes
value_
withstatic_cast<value_type&&>(f.value())
-
Initializes each public base class subobjects
b
withstd::move(bf)
, wherebf
is the base class subobjects inf
that corresponds tob
-
template <typename OtherPrintableDef>
constexpr value_and_format
( const value_type& v
, const value_and_format<OtherPrintableDef, Fmts...>& f );
- Effects
-
-
Initializes
value_
withv
-
Initializes each public base class subobjects with the corresponding base class subobject of
f
-
template <typename OtherPrintableDef>
constexpr value_and_format
( const value_type& v
, value_and_format<OtherPrintableDef, Fmts...>&& f );
- Effects
-
-
Initializes
value_
withv
-
Initializes each public base class subobjects
b
withstd::move(bf)
, wherebf
is the base class subobjects inf
that corresponds tob
-
template <typename... F, typename... FInit>
constexpr value_and_format
( const value_type& v
, tag<F...>
, FInit&&... finit );
- Compile-time requirements
-
-
sizeof...(F) == sizeof...(FInit)
-
There is no repeated type in
F...
-
All types in
F...
are also inFmts...
-
- Effects
-
-
Initializes
value_
withv
-
For each type in
F...
, initializes the corresponding public base class subobjects with the corresponging value instd::forward<FInit>(finit)...
-
Default initializes the remaining public base class subobjects
-
template
< typename OtherPrintableDef
, typename... OtherFmts
, typename Fmt
, typename... FmtInitArgs >
template <typename Fmt, typename FmtInit, typename... OtherFmts>
constexpr value_and_format
( const value_and_format<PrintableDef, OtherFmts...>& other
, tag<Fmt>
, FmtInitArgs&&... args );
- Compile-time requirements
-
-
Fmt
is one the types inFmts...
-
sizeof...(OtherFmts) == sizeof...(Fmts)
is true -
value_type
must be constructible fromobject.value()
-
Each public base class of this type, except the one that corresponds to
Fmt
, must be constructible from a const lvalue reference of the corresponding base sub-object ofother
( the type first inFmts…
corresponds to the first in `OtherFmt…, the second to the second and so on ). -
Fmt
must be contructible fromFmtInitArgs&&...
-
- Effects
-
-
Initializes
value_
withother.value()
-
Initializes the public base class subobject that corresponds to
Fmt
withstd::forward<FmtInitArgs>(args)...
-
Initializes the other public base class subobjects with the corresponding base class subobject of
other
-
constexpr const value_type& value() const;
constexpr value_type& value();
Returns value_
3. Numeric punctuation
3.1. Facet category template numpunct_c
namespace strf {
template <int Base> struct numpunct_c {
constexpr static bool constrainable = true;
static constexpr default_numpunct<Base> get_default() noexcept;
};
} // namespace strf
For a type to be a facet of the numpunct_c<Base>
,
it must satisfy NumericPuntuation type requirements
3.2. Type requirement NumericPunctuation
Given
-
Base
, an integerconstexpr
equal to2
,8
,10
or16
-
X
, a NumericPunctuation type forBase
-
x
, a const value of typeX
The following must hold:
-
X is CopyConstructible
-
facet_category<X>
is a type alias tonumpunct_c<Base>
And following expressions are well-formed and satisfy the following corresponding conditions:
x.grouping()
Return type |
x.distribute(digcount)
Return type | |
Return value |
|
x.any_group_separation(digcount)
Return type |
|
Return value |
|
x.thousands_sep_count(digcount)
Return type |
|
Return value |
|
x.thousands_sep()
Return type |
|
x.decimal_point()
Return type |
|
3.3. Class template numpunct
numpunct<Base>
is a facet of the numpunct_c<_Base_>
category,
and it satisfies the requirements of NumericPunctuation.
template <int Base>
class numpunct {
public:
using category = numpunct_c<Base>;
// constructors
constexpr numpunct() noexcept;
constexpr numpunct(const numpunct& ) noexcept;
constexpr explicit numpunct(digits_grouping) noexcept;
template <typename... IntArgs>
constexpr explicit numpunct(int grp0, IntArgs... grps) noexcept;
// assignment
constexpr numpunct& operator=(const numpunct&) noexcept;
// comparison
constexpr bool operator==(const numpunct& other) const noexcept;
constexpr bool operator!=(const numpunct& other) const noexcept;
// observers
constexpr char32_t decimal_point() const noexcept;
constexpr char32_t thousands_sep() const noexcept;
constexpr digits_grouping grouping() const noexcept;
// modifiers
constexpr numpunct& decimal_point(char32_t ch) & noexcept;
constexpr numpunct&& decimal_point(char32_t ch) && noexcept;
constexpr numpunct& thousands_sep(char32_t ch) & noexcept;
constexpr numpunct&& thousands_sep(char32_t ch) && noexcept;
// utilities
constexpr digits_distribution distribute(int digcount) const noexcept;
constexpr bool any_group_separation(int digcount) const noexcept;
constexpr int thousands_sep_count(int digcount) const noexcept;
private:
char32_t decimal_point_ = U'.'; // exposition only
char32_t thousands_sep_ = U','; // exposition only
digits_grouping grouping_; // exposition only
};
Public members
constexpr numpunct() noexcept;
Postconditions |
|
constexpr numpunct(digits_grouping grpng) noexcept;
Postconditions |
|
template <typename... IntArgs>
constexpr numpunct(int grp0, IntArgs... grps) noexcept;
Preconditions |
Same as of the constructor of |
Postconditions |
|
int thousands_sep_count(int digcount) const;
Return value |
|
constexpr digits_distribution distribute(unsiged digcount) const noexcept;
Return value |
|
bool any_group_separation(int digcount) const;
Return value |
|
char32_t decimal_point() const noexcept;
Returns the decimal point.
char32_t thousands_sep() const noexcept;
Returns the thousands separator.
numpunct & decimal_point(char32_t ch) & noexcept;
numpunct && decimal_point(char32_t ch) && noexcept;
Effect |
Changes the decimal point to |
Postcondition |
|
Return value |
|
numpunct & thousands_sep(char32_t ch) & noexcept;
numpunct && thousands_sep(char32_t ch) && noexcept;
Effect |
Changes the thousands separtor to |
Postcondition |
|
Return value |
|
3.4. Class template default_numpunct
default_numpunct<Base>
is the default facet of the
numpunct_c<Base>
category.
It is an empty class, optimized to represent the default
state of numpunct<Base>
namespace strf {
template <int Base>
class default_numpunct: {
public:
using category = numpunct_c<Base>;
constexpr default_numpunct() noexcept= default; // no-op
constexpr default_numpunct(const default_numpunct& ) noexcept = default; // no-op
constexpr default_numpunct& operator=(const default_numpunct&) noexcept; // no-op
constexpr bool operator==(const default_numpunct& other) const noexcept;
constexpr bool operator!=(const default_numpunct& other) const noexcept;
constexpr digits_grouping grouping() const
constexpr digits_distribution distribute(unsiged digcount) const
constexpr bool any_group_separation(int digcount) const noexcept;
constexpr int thousands_sep_count(int digcount) const noexcept;
constexpr char32_t decimal_point() const noexcept;
constexpr char32_t thousands_sep() const noexcept;
};
} // namespace strf
Public members
constexpr bool operator==(const default_numpunct& other) const noexcept;
Return value |
|
constexpr bool operator!=(const default_numpunct& other) const noexcept;
Return value |
|
constexpr digits_grouping grouping() const
Return value |
constexpr digits_distribution distribute(unsiged digcount) const
Return value |
|
constexpr bool any_group_separation(int digcount) const noexcept;
Return value |
|
int thousands_sep_count(int digcount) const override;
Return value |
0 |
char32_t thousands_sep() const noexcept;
Return value |
|
char32_t decimal_point() const noexcept;
Return value |
|
3.5. Class template no_grouping
no_grouping<_Base_>
is a facet of the numpunct_c<_Base_
category. The only reason for one to use no_grouping
rather than numpunct
is optimization. It is not possible to
change the thousaunds separator nor the grouping in a no_grouping<_Base_>
object. It is only possible to change its decimal point.
namespace strf {
template <int Base>
class no_grouping {
public:
using category = numpunct_c<Base>;
constexpr no_grouping() = default;
constexpr no_grouping(const no_grouping& ) = default;
constexpr no_grouping& operator=(const no_grouping&) noexcept;
constexpr bool operator==(const no_grouping& other) const noexcept;
constexpr bool operator!=(const no_grouping& other) const noexcept;
constexpr digits_grouping grouping() const
constexpr digits_distribution distribute(unsiged digcount) const
constexpr bool any_group_separation(int digcount) const noexcept;
constexpr int thousands_sep_count(int digcount) const noexcept;
constexpr char32_t decimal_point() const noexcept;
constexpr no_grouping& decimal_point(char32_t ch) & noexcept;
constexpr no_grouping&& decimal_point(char32_t ch) && noexcept;
constexpr char32_t thousands_sep() const noexcept;
private:
char32_t decimal_point_ = U'.'; // exposition only
};
} // namespace strf
Public members
constexpr bool operator==(const no_grouping& other) const noexcept;
Return value |
|
constexpr bool operator!=(const no_grouping& other) const noexcept;
Return value |
|
constexpr digits_grouping grouping() const
Return value |
constexpr digits_distribution distribute(unsiged digcount) const
Return value |
|
constexpr bool any_group_separation(int digcount) const noexcept;
Return value |
|
int thousands_sep_count(int digcount) const override;
Return value |
0 |
int thousands_sep_count(int digcount) const override;
Return value |
0 |
char32_t thousands_sep() const noexcept;
Return value |
|
char32_t decimal_point() const noexcept;
Return value |
no_grouping & decimal_point(char32_t ch) & noexcept;
no_grouping && decimal_point(char32_t ch) && noexcept;
Effect |
Changes the decimal point to |
Postcondition |
|
Return value |
|
3.6. Class digits_grouping
namespace strf {
class digits_grouping {
public:
constexpr static int grp_max = 31;
constexpr static int grps_count_max = 6;
// constructors
constexpr digits_grouping() noexcept;
constexpr digits_grouping(const digits_grouping&) noexcept;
template <typename... IntArgs>
constexpr explicit digits_grouping(int grp0, IntArgs... grps) noexcept;
explicit digits_grouping(const char* str) noexcept;
// assignment
constexpr digits_grouping& operator=(const digits_grouping&) noexcept;
// comparison
constexpr bool operator==(const digits_grouping&) const noexcept;
constexpr bool operator!=(const digits_grouping&) const noexcept;
// observers and utilities
constexpr bool empty() const noexcept;
constexpr bool any_separator(int digcount) const noexcept;
constexpr int separators_count(int digcount) const noexcept;
constexpr digits_grouping_iterator get_iterator() const noexcept;
constexpr digits_distribution distribute(int digcount) const noexcept;
};
} // namespace strf
constexpr explicit digits_grouping() noexcept;
Equivalent to digits_grouping(-1)
Postcondition |
|
template <typename... IntArgs>
constexpr explicit digits_grouping(int grp0, IntArgs... grps) noexcept;
Specifies the groups from the least significant ( first argument ) to the most significant.
If the last argument is -1
, then the last group ( second-to-last argument ) is not to be repeated.
- Compile-time requirements
-
-
All arguments are convertible to
int
-
- Preconditions
-
-
The value
g
of last argument is such thatg == -1 || (0 < g && g <= grp_max)
istrue
. -
The value
g
of any argument but the last is such that(0 < g && g <= grp_max)
istrue
. -
The number of groups ( not counting the last argument if it’s
-1
) is not greater thangrps_count_max
-
dexplicit igits_grouping(const char* str) noexcept;
The characters in str
specify the groups, starting from the least significant one.
If the last character is '\xFF'
, then the last group is not repeated.
Passing the empty string (""
) has the same effect as passing as "\xFF"
, which has the same effect of the default constructor.
- Preconditions
-
-
str != nullptr
-
str
is a null terminated string -
For each character
ch
instr
that is not the last character,0 < ch && ch <= grp_max
istrue
-
If
ch
is the last characterstr
, thench == '\xFF' || (0 < ch && ch <= grp_max)
istrue
-
The number of groups ( not counting the last character if it is
'\xFF'
) must not be greater thangrps_count_max
.
-
constexpr bool empty() const noexcept;
If empty()
return true
, then there is no group. This means that
the thousands separator is absent regardless of the number of
digits.
constexpr bool any_separator(int digcount) const noexcept;
Return value |
|
constexpr int separators_count(int digcount) const noexcept;
Return value |
The quantity of thousands separators that would appear
in |
constexpr digits_grouping_iterator get_iterator() const noexcept;
Constructs a digits_grouping_iterator
from this object.
It is supposed to be used when the digits
are to be written backwards, i.e. from the the least to the
most significant.
constexpr digits_distribution distribute(int digcount) const noexcept;
Constructs a digits_distribution
from this object.
It is supposed to be used when the digits
are to be written forwards, i.e. from the the most to the
least significant.
digcount
is the quantity of digits.
- Precondition
-
digcount > 0
- Postconditions
-
The return value
dist
is such that-
dist.highest_group > 0
-
if
dist.middle_groups_count
is not0
, thendist.low_groups.empty()
isfalse
.
-
3.7. Class digits_grouping_creator
namespace strf {
class digits_grouping_creator {
public:
constexpr digits_grouping_creator() noexcept = default;
constexpr digits_grouping_creator(const digits_grouping_creator&) noexcept = delete;
constexpr void push_high(int grp) noexcept;
constexpr void push_high(int grp) noexcept;
constexpr bool failed() const noexcept;
constexpr digits_grouping finish_no_more_sep() noexcept;
constexpr digits_grouping finish() noexcept;
};
} // namespace strf
Sometimes it is not easy instantiate to digits_grouping
through
one of its constructors, since it requires you to pass all groups at once.
So digits_grouping_creator
provides an alternative and iterative way:
each group is passed one-by-one to push_high
function,
from the least to the most significant.
After all groups are passed, finish()
or finish_no_more_sep()
shall be called to create the resulting digits_grouping
object.
finish()
is used when the last group is supposed to be repeated,
while finish_no_more_sep()
is for the opposite case.
Calling push_high()
after that has undefined behaviour.
strf::digits_grouping_creator creator;
creator.push_high(1);
creator.push_high(2);
creator.push_high(3);
assert(creator.finish() == strf::digits_grouping(1, 2, 3));
If something wrong happens ( push_high
called more than
digits_grouping::grps_count_max
, or with an invalid argument
( 0 or greater than digits_grouping::grp_max
) )
, the return value of failed()
becames true
, and the return
value of finish()
and finish_no_more_sep()
becames digits_grouping{}
.
3.8. Class digits_grouping_iterator
This class provides a way to iterate through the groups of a digits_grouping
object, from the least to the most significant.
namespace strf {
class digits_grouping_iterator {
public:
// constructors
digits_grouping_iterator() = delete;
constexpr digits_grouping_iterator(const digits_grouping_iterator&) noexcept = default;
constexpr explicit digits_grouping_iterator(digits_grouping) noexcept;
// assignment
constexpr digits_grouping_iterator& operator=(const digits_grouping_iterator&) noexcept;
// comparison
constexpr bool operator==(const digits_grouping_iterator&) const noexcept;
constexpr bool operator!=(const digits_grouping_iterator&) const noexcept;
// iteration
constexpr int current() const noexcept;
constexpr void advance() noexcept;
constexpr bool is_last() const noexcept;
constexpr bool shall_repeat_current() const noexcept;
constexpr bool is_final() const noexcept;
constexpr bool ended() const noexcept;
};
} // namespace strf
constexpr int current() noexcept;
Returns the current group.
Precondition |
|
constexpr void advance() noexcept;
Effect |
Moves to the next (more significant) group. |
Precondition |
|
Postconditions |
If the return value of |
constexpr bool is_last() const noexcept;
Return value |
|
constexpr bool shall_repated_current() const noexcept;
Return value |
|
constexpr bool is_final() const noexcept;
Return value |
|
constexpr bool ended() const noexcept;
Returns true
when there is no group left.
strf::digits_grouping grouping{1, 2, 3};
strf::digits_grouping_iterator it = grouping.get_iterator();
assert(it.current() == 1 && ! it.is_last());
it.advance();
assert(it.current() == 2 && ! it.is_last());
it.advance();
assert(it.current() == 3 && it.shall_repeat_current());
it.advance();
assert(it.ended());
strf::digits_grouping grouping{1, 2, 3, -1};
strf::digits_grouping_iterator it = grouping.get_iterator();
assert(it.current() == 1 && ! it.is_last());
it.advance();
assert(it.current() == 2 && ! it.is_last());
it.advance();
assert(it.current() == 3 && it.is_final());
it.advance();
assert(it.ended());
strf::digits_grouping grouping{};
strf::digits_grouping_iterator it = grouping.get_iterator();
assert(it.ended());
3.9. Class digits_distribution
This struct is designed to be used in algoritms that print groups of digits separated by the thousands separator from the most to the least significant.
namespace strf {
struct digits_distribution {
reverse_digits_groups low_groups;
int middle_groups_count;
int highest_group;
};
} // namespace strf
-
highest_group
is the most significant group. -
low_groups
contains the least signficant groups. -
middle_groups_count
how many groups equal tolow_groups.highest_groups()
follow the highest group.
strf::numpunct<Base> punct = …;
strf::digits_distribution dist = punct.distribute(digits_count);
assert(dist.highest_groups != 0);
// step 1
… // print the most significant dist.highest_group digits
// step 2 - print middle groups
if (dist.middle_groups_count) {
auto mg = dist.low_groups.highest_group();
dist.low_groups.pop_high();
do {
… // print the separator, then mg digits
} while (--dist.middle_groups_count);
}
// step 3 - least significant groups
while( ! dist.low_groups.empty()) {
auto g = dist.low_groups.highest_group();
dist.low_groups.pop_high();
… // prints the separator, then g digits
}
3.10. Class reverse_digits_groups
The class reverse_digits_groups
aims to be used in loops that
print groups of digits separated by the thousand separator from
the most to the least significant.
namespace strf {
class reverse_digits_groups {
public:
constexpr static int grp_max = digits_grouping::grp_max;
constexpr static int grps_count_max = digits_grouping::grps_count_max;
constexpr reverse_digits_groups() noexcept;
constexpr reverse_digits_groups(const reverse_digits_groups&) noexcept;
constexpr bool operator==(const reverse_digits_groups& other) const noexcept;
constexpr bool operator!=(const reverse_digits_groups& other) const noexcept;
constexpr reverse_digits_groups& operator=(const reverse_digits_groups& other) noexcept;
constexpr void push_low(int group) noexcept;
constexpr void pop_high() noexcept;
constexpr int highest_group() const noexcept;
constexpr bool empty() const noexcept;
};
} // namespace strf
The meaning of "group" used in The value returned by On the other hand, there is no similar need when you create a
|
constexpr int highest_group() const noexcept;
Return the actual number of digits in the current group.
- Postconditions
-
The return value is zero when
empty()
returnstrue
. Otherwise, it is non-zero and not greater thangrp_max
;
constexpr void pop_high() noexcept;
- Effects
-
None when
empty()
returnstrue
. Otherwise, moves the return value ofhighest_group()
to the next (less significant) group.
4. Character encodings
4.1. Enumeration charset_id
namespace strf {
enum class charset_id : unsigned { };
constexpr charset_id scid_ascii = /* ... */;
constexpr charset_id scid_utf8 = /* ... */;
constexpr charset_id scid_utf16 = /* ... */;
constexpr charset_id scid_utf32 = /* ... */;
constexpr charset_id scid_iso_8859_1 = /* ... */;
constexpr charset_id scid_iso_8859_2 = /* ... */;
constexpr charset_id scid_iso_8859_3 = /* ... */;
constexpr charset_id scid_iso_8859_4 = /* ... */;
constexpr charset_id scid_iso_8859_5 = /* ... */;
constexpr charset_id scid_iso_8859_6 = /* ... */;
constexpr charset_id scid_iso_8859_7 = /* ... */;
constexpr charset_id scid_iso_8859_8 = /* ... */;
constexpr charset_id scid_iso_8859_9 = /* ... */;
constexpr charset_id scid_iso_8859_10 = /* ... */;
constexpr charset_id scid_iso_8859_11 = /* ... */;
constexpr charset_id scid_iso_8859_13 = /* ... */;
constexpr charset_id scid_iso_8859_14 = /* ... */;
constexpr charset_id scid_iso_8859_15 = /* ... */;
constexpr charset_id scid_iso_8859_16 = /* ... */;
constexpr charset_id scid_windows_1250 = /* ... */;
constexpr charset_id scid_windows_1251 = /* ... */;
constexpr charset_id scid_windows_1252 = /* ... */;
constexpr charset_id scid_windows_1253 = /* ... */;
constexpr charset_id scid_windows_1254 = /* ... */;
constexpr charset_id scid_windows_1255 = /* ... */;
constexpr charset_id scid_windows_1256 = /* ... */;
constexpr charset_id scid_windows_1257 = /* ... */;
constexpr charset_id scid_windows_1258 = /* ... */;
} // namespace strf
4.2. Facet category transcoding_error_notifier_c
A facet of the transcoding_error_notifier_c
category must satisfy the
TranscodingErrorNotifierPtr type requirements.
namespace strf {
struct transcoding_error_notifier_c {
static constexpr bool constrainable = false;
static constexpr transcoding_error_notifier_nullptr get_default() noexcept {
return {};
}
};
} // namespace strf
Type requirement TranscodingErrorNotifierPtr
Given
-
X
, a TranscodingErrorNotifierPtr type -
x
, a const value of typeX
The following must hold:
-
facet_category<X>
is a type alias totranscoding_error_notifier_c
-
X
is MoveConstructible
x.get()
Return type |
Struct transcoding_error_notifier_nullptr
namespace strf {
struct transcoding_error_notifier_nullptr {
using category = transcoding_error_notifier_c;
constexpr transcoding_error_notifier* get() const { return nullptr; }
};
} // namespace strf
Struct transcoding_error_notifier_ptr
namespace strf {
struct transcoding_error_notifier_ptr {
using category = transcoding_error_notifier_c;
constexpr transcoding_error_notifier* get() const { return ptr; }
transcoding_error_notifier* ptr = nullptr;
};
} // namespace strf
Class transcoding_error_notifier
namespace strf {
class transcoding_error_notifier {
public:
virtual ~transcoding_error_notifier() {}
virtual void invalid_sequence
( int code_unit_size
, const char* source_charset_name
, const void* sequence_ptr
, std::ptrdiff_t code_units_count )
{
}
virtual void unsupported_codepoint
( const char* destination_charset_name
, unsigned codepoint )
{
}
};
} // namespace strf
4.3. Enum transcode_flags
namespace strf {
enum class transcode_flags {
none = 0,
lax_surrogate_policy = 1,
stop_on_invalid_sequence = 1 << 1,
stop_on_unsupported_codepoint = 1 << 2
};
constexpr transcode_flags operator|(transcode_flags a, transcode_flags b) noexcept;
constexpr transcode_flags operator&(transcode_flags a, transcode_flags b) noexcept;
constexpr transcode_flags& operator|=(transcode_flags& a, transcode_flags b) noexcept;
constexpr transcode_flags& operator&=(transcode_flags& a, transcode_flags b) noexcept;
constexpr bool with_strict_surrogate_policy(transcode_flags f) noexcept;
constexpr bool with_lax_surrogate_policy(transcode_flags f) noexcept;
constexpr bool with_stop_on_invalid_sequence(transcode_flags f) noexcept;
constexpr bool with_stop_on_unsupported_codepoint(transcode_flags f) noexcept;
} // namespace strf
The transcode_flags
is a flags enum, i.e. the value of a
transcode_flags
can be a combination the above values.
4.4. Enum transcode_stop_reason
namespace strf {
enum class transcode_stop_reason : std::uint32_t {
completed,
insufficient_output_space,
unsupported_codepoint,
invalid_sequence
};
The transcode_stop_reason
is used in the return type of the several trancode
functions of the library with the following semantics:
-
transcode_stop_reason::completed
implies that all input has been transcoded (though some parts of it might be invalid and thus been replaced by the replacement character U+FFFD or'?'
) -
transcode_stop_reason::insufficient_output_space
implies that the transcoding stopped because the destination is too small ( in case the destination is range of character pointers ), or that the state of thedestination<DstCharT>
object is (or became) bad. -
transcode_stop_reason::invalid_sequence
implies that both the input has an invalid sequence (i.e. it is not conformant to its encoding ) and the flagtranscode_flags::stop_on_invalid_sequence
was set. -
transcode_stop_reason::unsupported_codepoint
implies that both the input has a condepoint that not encodable in the destination character encoding ( though it is this a valid in the source character encoding, which may happen, for instance, when converting UTF-8 to ISO 8859-1) and the flagtranscode_flags::stop_on_unsupported_codepoint
was set.
The transcode_stop_reason
is not a flags enum, i.e. the value of a
transcode_stop_reason
is always expected to one of the above values ( never a
combination of them )
4.5. Facet category template charset_c
namespace strf {
template <typename CharT>
struct charset_c {
static constexpr bool constrainable = false;
static constexpr utf<CharT> get_default() noexcept;
};
template <typename CharT, charset_id CSId>
struct facet_tratis<static_charset<CharT, CSId>>
{
using category = charset_c<CharT>;
};
template <typename CharT>
struct facet_tratis<dynamic_charset<CharT>>
{
using category = charset_c<CharT>;
};
} // namespace strf
For a type to be a facet of charset_c<CharT>
it has
to be a Charset type for CharT
. The library provides
two class templates that satisfy that: static_charset
and dynamic_charset
4.6. Type alias template transcode_dest
namespace strf {
template <typename CharT>
using transcode_dest = output_buffer<CharT, 3>;
} // namespace strf
4.7. Struct template transcode_result
namespace strf {
template <typename SrcCharT, typename DstCharT>
struct transcode_result {
const SrcCharT* src_ptr;
DstCharT* dst_ptr;
transcode_stop_reason stop_reason;
};
} // namespace strf
4.8. Struct template transcode_size_result
namespace strf {
template <typename CharT>
struct transcode_size_result {
std::ptrdiff_t ssize;
const CharT* src_ptr;
transcode_stop_reason stop_reason;
};
} // namespace strf
4.9. Struct template count_codepoints_result
namespace strf {
template <typename CharT>
struct count_codepoints_result {
std::ptrdiff_t count;
const CharT* ptr;
};
} // namespace strf
4.10. Aliases for pointers to functions
namespace strf {
template <typename SrcCharT, typename DstCharT>
using transcode_f = transcode_result<CharT> (*)
( const SrcCharT* src
, const SrcCharT* src_end
, DstCharT* dst
, DstCharT* dst_end
, transcoding_error_notifier* err_notifier
, transcode_flags flags );
template <typename SrcCharT>
using transcode_size_f = transcode_size_result<ScrCharT> (*)
( const SrcCharT* src
, const SrcCharT* src_end
, std::ptrdiff_t limit
, transcode_flags flags );
template <typename CharT>
using write_replacement_char_f = void(*)( transcode_dest<CharT>& );
using validate_f = int (*)(char32_t ch);
using encoded_char_size_f = int (*) (char32_t ch);
template <typename CharT>
using encode_char_f = CharT*(*) (CharT* dest, char32_t ch);
template <typename CharT>
using encode_fill_f = void (*)
( transcode_dest<CharT>&
, std::ptrdiff_t count
, char32_t ch );
template <typename CharT>
using count_codepoints_fast_f = count_codepoints_result<CharT> (*)
( const CharT* src
, const CharT* src_end
, std::ptrdiff_t max_count );
template <typename CharT>
using count_codepoints_f = count_codepoints_result<CharT> (*)
( const CharT* src
, const CharT* src_end
, std::ptrdiff_t max_count );
template <typename CharT>
using decode_unit_f = char32_t (*) ( CharT );
template <typename SrcCharT, typename DstCharT>
using find_transcoder_f = dynamic_transcoder<SrcCharT, DstCharT> (*)
( charset_id );
} // namespace strf
4.11. Type requirement Transcoder
Given
-
SrcCharT
, one of the types:char
,char8_t
,char16_t
,char32_t
orwchar_t
-
DstCharT
, one of the types:char
,char8_t
,char16_t
,char32_t
orwchar_t
-
X
, a Transcoder type fromSrcCharT
toDstCharT
-
x
, an expression of typeX
orconst X
-
src
, a value of typeconst SrcCharT*
-
src_end
, a value of typeconst SrcCharT*
pointing immediately after the last character of the string that begins atstr
-
dst
, a value of typeDstCharT*
-
dst_end
, a value of typeDstCharT*
pointing immediately after the last element of the array that begins atdst
-
limit
is value of typestd::ptrdiff_t
-
err_notifier
, is a pointer of typetranscoding_error_notifier
-
flags
, a value of typetranscode_flags
The following must hold:
-
X
is CopyConstructible. -
X
supports the following syntax and semantics:
X::src_code_unit
A type alias to SrcCharT
X::dst_code_unit
A type alias to DstCharT
x.transcode(src, src_end, dst, dst_end, err_notifier, flags)
- Precondition
-
x.transcode_func() != nullptr
istrue
- Return type
- Effect
-
Converts the content of
src
from one encoding to another writing the result todst
.As this function iterates from
src
tosrc_end
, if it reads a sequence that is invalid ( non-conformant to the source character encoding ) then it callserr_notifier->invalid_sequence(ch_size, name, seq, count)
, iferr_notifer
is not null, where:-
ch_size
is equal tosizeof(SrcCharT)
-
name
is the name of the source character encoding (e.g.,"UTF-8"
) -
seq
points to the first character of the invalid sequence. -
count
is number of code units of the invalid sequence-
Note: The value of both following expression shall be
true
:(const SrcCharT*)seq >= src
(const SrcCharT*)seq + count <= src_end
-
After that, if
flags
has the bit flagstop_on_invalid_sequence
, then the function shall stop and return a value withstop_reason
equal totranscode_stop_reason::invalid_sequence
. Otherwise, the function shall write a replacement character (which is U+FFFD or'?'
, depending on the destination encoding) and continue the iteration after the invalid sequence. Note: the presence of a surrogate codepoint ( that is considered to be and invalid sequence ) shall not be considered an invalid sequence if the flagtranscode_flags::lax_surrogate_policy
is set inflags
.Similarly, when the function reads a codepoint that is not supported by the destination encoding but also not equal U+FFFD, it calls (if
err_notifier
is not null)err_notifier->unsupported_codepoint(dst_charset_name, code)
, wheredst_charset_name
is the name of the destination character encoding, andcode
is such codepoint.After that, if
flags
has the flagstop_on_unsupported_codepoint
, then the function shall stop and return a value withstop_reason
equal totranscode_stop_reason::unsupported_codepoint
. Otherwise, the function shall write a replacement character (which is U+FFFD or'?'
, depending on the destination encoding) and continue the iteration after the usupported codepoint.If the input contains the U+FFFD codepoint then it should not be treated as unsupported even if it is. This means that
err_notifier->unsupported_codepoint
shall not be called in this case, nor should this cause the interation to stop. Instead, the function should just write'?'
when the destination encoding does not support U+FFFDtranscode_stop_reason::insufficient_output_space
should only be returned if there is still something to be written but there is no space left (i.e., the distance(dst_end - dst)
is too small). For instance, if the input starts with an invalid sequence andflags
hasstop_on_invalid_sequence
set, then, even ifdst_end
is equal todst
the returnedstop_reason
shall not betranscode_stop_reason::insufficient_space
; it should instead be shall betranscode_stop_reason::invalid_sequence
. -
- Return value
-
A value
res
such that-
res.stop_reason
istranscode_stop_reason::completed
unless for any of the cases explained above. -
res.src_ptr
points immediately after the last element in the range[src, src_end)
that has been transcoded. -
res.dst_ptr
points immediately after the last element in the range[dst, dst_end)
that has been written
-
x.unsafe_transcode(src, src_end, dst, dst_end, err_notifier, flags)
- Preconditions
-
-
The input has no invalid sequence
-
x.unsafe_transcode_() != nullptr
istrue
-
- Return type
- Effect
-
Exactly the same as
x.transcode(src, src_end, dst, dst_end, err_notifier, flags)
, except that the behaviour is undefined if the input contains any invalid sequence.Note that if the flag
transcode_flags::lax_surrogate_policy
is set inflags
, then the presence of a surrogate codepoint in[src, src_end)
is not to be considered as an invalid sequence, and thus shall not cause undefined behaviour.
x.transcode_size(src, src_end, limit, flags)
- Precondition
-
x.transcode_func() != nullptr
istrue
- Return type
- Return value
-
A value
res
such that-
res.src_ptr
is equal totr_res.src_ptr
( see below ) -
res.stop_reason
is equal totr_res.stop_reason
-
res.ssize
equals totr_res.dst_ptr - dst
, where
tr_res
is the value thatx.transcode(src, src_end, dst, dst + limit, nullptr, flags)
would return, assuming[dst, dst + limit)
is a valid memory area. -
x.unsafe_transcode_size(src, src_end, limit, flags)
Precondition |
|
Return type | |
Effect |
Exactly the same as Note that if the flag |
x.transcode_func()
Return type |
|
Return value |
A function pointer such that
|
x.unsafe_transcode_func()
Return type |
|
Return value |
A function pointer such that
|
x.transcode_size_func()
Return type |
|
Return value |
A function pointer such that
|
x.unsafe_transcode_size_func()
Return type |
|
Return value |
A function pointer such that
|
A null transcoder is an object of an Transcoder
type where the transcode_func
function returns nullptr
.
There are two class templates that satisfy Transcoder:
static_transcoder and dynamic_transcoder .
|
4.12. Type requirement Charset
An object whose type is a Charset represents a character encoding. In this documentation the terms charset, encoding and character encoding are used interchangeably.
Given
-
CharT
, one of the follwoing types:char
,char8_t
,char16_t
,char32_t
orwchar_t
-
OtherCharT
, one of the folowing types :char
,char8_t
,char16_t
orwchar_t
-
X
, a Charset type for typeCharT
-
x
, an expression of typeX
orconst X
-
ptr
, a value of typeCharT*
-
src
, a value of typeconst CharT*
-
src_end
, a value of typeconst SrcCharT*
pointing immediately after the last character of the string that begins atstr
-
dest
, an lvalue reference of typetranscode_dest<CharT>
-
src_size
, a value of typestd::ptrdiff_t
equal to the size of the array pointed bysrc
-
count
, a value of typestd::ptrdiff_t
-
max_count
, a value of typestd::ptrdiff_t
-
ch32
, a value of typechar32_t
-
ch
, a value of typeCharT
-
cs_id
, value of typecharset_id
The following must hold:
-
X
is either an instance of thestatic_transcoder
ordynamic_charset
class template -
X
is CopyConstructible -
facet_category<X>
must becharset_c<CharT>
-
X
satisfies the following syntax and semantics:
X::code_unit
Type alias to CharT
x.id()
Return type | |
Return value |
The |
x.name()
Return type |
|
Return value |
The name of this encoding. Examples: |
x.replacement_char()
Return type |
|
Return value |
The character used to signalize an error. Usually it is the replacement character � if it is supported by this encoding, or the question mark |
x.write_replacement_char(dest)
Effect |
Writes into |
Return type |
|
x.replacement_char_size()
Return type |
|
Return value |
The number of characters that |
x.encoded_char_size(ch32)
Return type |
|
Return value |
The size of the string containing the UTF-32 character |
Postcondition |
The return value must be greater than zero. |
Note |
This function does not check whether |
x.validate(ch32)
Return type |
|
Return value |
The size of the string encoding |
x.encode_char(ptr, ch32)
Effect |
Encodes into |
Return type |
|
Postcondition |
|
Return value |
The position just after the last writen character. |
Note |
This function does not check whether |
x.encode_fill(dest, count, ch32)
Effect |
Writes |
Return type |
|
Note |
|
x.count_codepoints_fast(src, src_end, max_count)
Return type |
|
Return value |
|
Posconditions |
|
Note |
If the input is non-conformant to the corresponding character encoding, this function may return an incorrect value. For instance, for UTF-8 this function may simply count the bytes that are not continuation bytes. |
x.count_codepoints(src, src_end, max_count)
Effect |
Counts the codepoints until it is equal to |
Return type |
|
Return value |
|
Posconditions |
|
x.decode_unit(ch)
Effect |
Decodes |
Return type |
|
x.encode_char_func()
Return type |
|
Return value |
A function pointer such that |
x.encode_fill_func()
Return type |
|
Return value |
A function pointer such that |
x.write_replacement_char_func()
Return type |
|
Return value |
A function pointer such that |
x.validate_func()
Return type | |
Return value |
A function pointer such that |
x.from_u32()
Return type |
A Transcoder type |
Return value |
A transcoder that converts UTF-32 to this encoding. |
x.to_u32()
Return type |
A Transcoder type |
Return value |
A transcoder that converts this encoding to UTF-32. |
x.sanitizer()
Return type |
A Transcoder from |
Return value |
A transcoder that converts this encoding to this encoding, i.e. a sanitizer of this encoding. |
x.find_transcoder_to(tag<OtherCharT>, cs_id)
Return type |
|
Return value |
A transcoder that converts this encoding to the encoding
corresponding to |
x.find_transcoder_from(tag<OtherCharT>, cs_id)
Return type |
|
Return value |
A transcoder that converts the encoding corresponding to
|
x.to_dynamic()
Return type |
|
Return value |
A |
You shall not create an Charset for char32_t , since char32_t
is reserved for UTF-32.
The library internaly assumes in many occasions that the encoding
is UTF-32 when CharT is char32_t .
|
4.13. Class template static_transcoder
template <class SrcCharT, class DstCharT, charset_id Src, charset_id Dest>
class static_transcoder;
// sanitizers
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_ascii, scid_ascii>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_iso_8859_1, scid_iso_8859_1>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_iso_8859_2, scid_iso_8859_2>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_iso_8859_3, scid_iso_8859_3>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_iso_8859_4, scid_iso_8859_4>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_iso_8859_5, scid_iso_8859_5>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_iso_8859_6, scid_iso_8859_6>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_iso_8859_7, scid_iso_8859_7>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_iso_8859_8, scid_iso_8859_8>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_iso_8859_9, scid_iso_8859_9>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_iso_8859_10, scid_iso_8859_10>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_iso_8859_11, scid_iso_8859_11>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_iso_8859_13, scid_iso_8859_13>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_iso_8859_14, scid_iso_8859_14>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_iso_8859_15, scid_iso_8859_15>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_iso_8859_16, scid_iso_8859_16>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_windows_1250, scid_windows_1250>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_windows_1251, scid_windows_1251>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_windows_1252, scid_windows_1252>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_windows_1253, scid_windows_1253>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_windows_1254, scid_windows_1254>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_windows_1255, scid_windows_1255>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_windows_1256, scid_windows_1256>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_windows_1257, scid_windows_1257>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_windows_1258, scid_windows_1258>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_utf8, scid_utf8>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_utf16, scid_utf16>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_utf32, scid_utf32>;
// to UTF-32
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_ascii, scid_utf32>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_iso_8859_1, scid_utf32>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_iso_8859_2, scid_utf32>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_iso_8859_3, scid_utf32>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_iso_8859_4, scid_utf32>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_iso_8859_5, scid_utf32>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_iso_8859_6, scid_utf32>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_iso_8859_7, scid_utf32>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_iso_8859_8, scid_utf32>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_iso_8859_9, scid_utf32>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_iso_8859_10, scid_utf32>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_iso_8859_11, scid_utf32>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_iso_8859_13, scid_utf32>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_iso_8859_14, scid_utf32>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_iso_8859_15, scid_utf32>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_iso_8859_16, scid_utf32>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_windows_1250, scid_utf32>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_windows_1251, scid_utf32>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_windows_1252, scid_utf32>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_windows_1253, scid_utf32>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_windows_1254, scid_utf32>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_windows_1255, scid_utf32>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_windows_1256, scid_utf32>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_windows_1257, scid_utf32>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_windows_1258, scid_utf32>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_utf8, scid_utf32>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_utf16, scid_utf32>;
// from UTF-32
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_utf32, scid_ascii>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_utf32, scid_iso_8859_1>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_utf32, scid_iso_8859_2>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_utf32, scid_iso_8859_3>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_utf32, scid_iso_8859_4>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_utf32, scid_iso_8859_5>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_utf32, scid_iso_8859_6>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_utf32, scid_iso_8859_7>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_utf32, scid_iso_8859_8>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_utf32, scid_iso_8859_9>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_utf32, scid_iso_8859_10>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_utf32, scid_iso_8859_11>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_utf32, scid_iso_8859_13>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_utf32, scid_iso_8859_14>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_utf32, scid_iso_8859_15>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_utf32, scid_iso_8859_16>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_utf32, scid_windows_1250>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_utf32, scid_windows_1251>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_utf32, scid_windows_1252>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_utf32, scid_windows_1253>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_utf32, scid_windows_1254>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_utf32, scid_windows_1255>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_utf32, scid_windows_1256>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_utf32, scid_windows_1257>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_utf32, scid_windows_1258>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_utf32, scid_utf8>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_utf32, scid_utf16>;
// others
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_utf8, scid_utf16>;
template <class SrcCharT, class DstCharT>
class static_transcoder<SrcCharT, DstCharT, scid_utf16, scid_utf8>;
static_transcoder
class template has no generic implementation.
Instead, the library provides the template specializations listed above.
All of them are empty classes, and are Transcoder, and their
member functions transcode_func
and transcode_size_func
never return nullptr
.
4.14. Class template static_charset
template <class CharT, charset_id>
class static_charset;
template <class CharT> class static_charset<CharT, scid_ascii>;
template <class CharT> class static_charset<CharT, scid_iso_8859_1>;
template <class CharT> class static_charset<CharT, scid_iso_8859_2>;
template <class CharT> class static_charset<CharT, scid_iso_8859_3>;
template <class CharT> class static_charset<CharT, scid_iso_8859_4>;
template <class CharT> class static_charset<CharT, scid_iso_8859_5>;
template <class CharT> class static_charset<CharT, scid_iso_8859_6>;
template <class CharT> class static_charset<CharT, scid_iso_8859_7>;
template <class CharT> class static_charset<CharT, scid_iso_8859_8>;
template <class CharT> class static_charset<CharT, scid_iso_8859_9>;
template <class CharT> class static_charset<CharT, scid_iso_8859_10>;
template <class CharT> class static_charset<CharT, scid_iso_8859_11>;
template <class CharT> class static_charset<CharT, scid_iso_8859_13>;
template <class CharT> class static_charset<CharT, scid_iso_8859_14>;
template <class CharT> class static_charset<CharT, scid_iso_8859_15>;
template <class CharT> class static_charset<CharT, scid_iso_8859_16>;
template <class CharT> class static_charset<CharT, scid_windows_1250>;
template <class CharT> class static_charset<CharT, scid_windows_1251>;
template <class CharT> class static_charset<CharT, scid_windows_1252>;
template <class CharT> class static_charset<CharT, scid_windows_1253>;
template <class CharT> class static_charset<CharT, scid_windows_1254>;
template <class CharT> class static_charset<CharT, scid_windows_1255>;
template <class CharT> class static_charset<CharT, scid_windows_1256>;
template <class CharT> class static_charset<CharT, scid_windows_1257>;
template <class CharT> class static_charset<CharT, scid_windows_1258>;
template <class CharT> class static_charset<CharT, scid_utf8>;
template <class CharT> class static_charset<CharT, scid_utf16>;
template <class CharT> class static_charset<CharT, scid_utf32>;
static_charset
class template has no generic implementation.
Instead, the library provides the template specializations listed above.
All of them are empty classes, and are Charset.
4.15. Class template dynamic_transcoder
namespace strf {
template <class SrcCharT, class DstCharT>
class dynamic_transcoder {
public:
constexpr dynamic_transcoder() noexcept;
constexpr dynamic_transcoder
( const dynamic_transcoder& other) noexcept = default;
template <charset_id SrcCh, charset_id DstCh>
constexpr explicit dynamic_transcoder
( static_transcoder<SrcCh, DestCh> st );
transcode_result<SrcCharT, DstCharT> transcode
( const SrcCharT* src
, const SrcCharT* src_end
, DstCharT* dst
, DstCharT* dst_end
, transcoding_error_notifier* err_notifier
, transcode_flags flags ) const;
transcode_result<SrcCharT, DstCharT> unsafe_transcode
( const SrcCharT* src
, const SrcCharT* src_end
, DstCharT* dst
, DstCharT* dst_end
, transcoding_error_notifier* err_notifier
, transcode_flags flags ) const;
transcode_size_result<SrcCharT> transcode_size
( const SrcCharT* src
, const SrcCharT* src_end
, std::ptrdiff_t limit
, transcode_flags flags ) const;
transcode_size_result<SrcCharT> unsafe_transcode_size
( const SrcCharT* src
, const SrcCharT* src_end
, std::ptrdiff_t limit
, transcode_flags flags ) const;
constexpr transcode_f<SrcCharT, DstCharT> transcode_func() const noexcept;
constexpr transcode_size_f<SrcCharT> transcode_size_func() const noexcept;
};
} // namespace strf
constexpr dynamic_transcoder() noexcept;
Default constructor
Postconditions |
|
constexpr dynamic_transcoder
( const dynamic_transcoder& other) noexcept;
Trivial copy constructor
Postconditions |
|
template <charset_id Src, charset_id Dest>
constexpr explicit dynamic_transcoder
( static_transcoder<Src, Dest> other );
Postconditions |
|
transcode_result<SrcCharT, DstCharT> transcode
( const SrcCharT* src
, const SrcCharT* src_end
, DstCharT* dst
, DstCharT* dst_end
, transcoding_error_notifier* err_notifier
, transcode_flags flags ) const;
Effect |
Calls |
transcode_result<SrcCharT, DstCharT> unsafe_transcode
( const SrcCharT* src
, const SrcCharT* src_end
, DstCharT* dst
, DstCharT* dst_end
, transcoding_error_notifier* err_notifier
, transcode_flags flags ) const;
Effect |
Calls |
transcode_size_result<SrcCharT> transcode_size
( const SrcCharT* src
, const SrcCharT* src_end
, std::ptrdiff_t limit
, transcode_flags flags ) const;
Effect |
Calls |
transcode_size_result<SrcCharT> unsafe_transcode_size
( const SrcCharT* src
, const SrcCharT* src_end
, std::ptrdiff_t limit
, transcode_flags flags ) const;
Effect |
Calls |
4.16. Struct template dynamic_charset_data
template <class CharT>
struct dynamic_charset_data {
const char* name;
charset_id id;
char32_t replacement_char;
int replacement_char_size;
validate_f validate_func;
encoded_char_size_f encoded_char_size_func;
encode_char_f<CharT> encode_char_func;
encode_fill_f<CharT> encode_fill_func;
count_codepoints_fast_f<CharT> count_codepoints_fast_func;
count_codepoints_f<CharT> count_codepoints_func;
write_replacement_char_f<CharT> write_replacement_char_func;
decode_unit_f<CharT> decode_unit_func;
dynamic_transcoder<CharT, CharT> sanitizer;
dynamic_transcoder<char32_t, CharT> from_u32;
dynamic_transcoder<CharT, char32_t> to_u32;
find_transcoder_f<wchar_t, CharT> find_transcoder_from_wchar;
find_transcoder_f<CharT, wchar_t> find_transcoder_to_wchar;
find_transcoder_f<char16_t, CharT> find_transcoder_from_char16;;
find_transcoder_f<CharT, char16_t> find_transcoder_to_char16;
find_transcoder_f<char, CharT> find_transcoder_from_char;
find_transcoder_f<CharT, char> find_transcoder_to_char;
#if defined (__cpp_char8_t)
find_transcoder_f<char8_t, CharT> find_transcoder_from_char8;
find_transcoder_f<CharT, char8_t> find_transcoder_to_char8;
#else
void* find_transcoder_from_char8 = nullptr;
void* find_transcoder_to_char8 = nullptr;
#endif
};
4.17. Class template dynamic_charset
template <class CharT>
class dynamic_charset {
public:
using code_unit = CharT;
explicit dynamic_charset(const dynamic_charset& other) = default;
explicit dynamic_charset(const dynamic_charset_data<CharT>& d );
template <charset_id CharsetID>
explicit dynamic_charset(const static_charset<CharT, CharsetID>& d );
dynamic_charset& operator=(const dynamic_charset& other) noexcept;
bool operator==(const dynamic_charset& other) const noexcept;
bool operator!=(const dynamic_charset& other) const noexcept;
void swap(dynamic_charset& other) noexcept;
dynamic_charset to_dynamic() const noexcept;
const char* name() const noexcept;
constexpr charset_id id() const noexcept;
constexpr char32_t replacement_char() const noexcept;
constexpr int replacement_char_size() const noexcept;
constexpr int validate(char32_t ch) const; // noexcept
constexpr int encoded_char_size(char32_t ch) const; // noexcept
code_unit* encode_char(code_unit* dest, char32_t ch) const; // noexcept
void encode_fill
( transcode_dest<CharT>& dest, std::ptrdiff_t count, char32_t ch ) const;
std::ptrdiff_t count_codepoints_fast
( const code_unit* src, const code_unit* src_end
, std::ptrdiff_t max_count ) const;
std::ptrdiff_t count_codepoints
( const code_unit* src, const code_unit* src_end
, std::ptrdiff_t max_count ) const;
void write_replacement_char(transcode_dest<CharT>& dest) const;
char32_t decode_unit(code_unit ch) const;
encode_char_f<CharT> encode_char_func() const noexcept;
encode_fill_f<CharT> encode_fill_func() const noexcept;
write_replacement_char_f<CharT> write_replacement_char_func() const noexcept;
dynamic_transcoder<char32_t, CharT> from_u32() const;
dynamic_transcoder<CharT, char32_t> to_u32() const;
dynamic_transcoder<CharT, CharT> sanitizer() const;
dynamic_transcoder<CharT, wchar_t> find_transcoder_to
( tag<wchar_t>, charset_id id) const;
dynamic_transcoder<wchar_t, CharT> find_transcoder_from
( tag<wchar_t>, charset_id id) const;
dynamic_transcoder<CharT, char16_t> find_transcoder_to
( tag<char16_t>, charset_id id) const;
dynamic_transcoder<char16_t, CharT> find_transcoder_from
( tag<char16_t>, charset_id id) const;
dynamic_transcoder<CharT, char> find_transcoder_to
( tag<char>, charset_id id) const;
dynamic_transcoder<char, CharT> find_transcoder_from
( tag<char>, charset_id id) const;
#if defined (__cpp_char8_t)
dynamic_transcoder<CharT, char8_t> find_transcoder_to
( tag<char8_t>, charset_id id) const;
dynamic_transcoder<char8_t, CharT> find_transcoder_from
( tag<char8_t>, charset_id id) const;
#endif
private:
const dynamic_charset_data* data; // exposition only
};
dynamic_charset(const dynamic_charset& other);
Trivial copy constructor.
Effect |
|
dynamic_charset(const dynamic_charset_data<CharT>& d);
Effect |
|
template <charset_id CharsetID>
dynamic_charset(const static_charset<CharT, CharsetID>& cs);
Equivalent to dynamic_charset(cs.to_dynamic())
dynamic_charset& operator=(const dynamic_charset& other) noexcept
Effect |
|
bool operator==(const dynamic_charset& other) const noexcept;
Return value |
|
bool operator!=(const dynamic_charset& other) const noexcept;
Return value |
|
void swap(dynamic_charset& other) noexcept;
Effect |
Equivalent to |
dynamic_charset to_dynamic() const noexcept;
Return value |
|
const char* name() const noexcept;
Return value |
|
constexpr charset_id id() const noexcept;
Return value |
|
constexpr char32_t replacement_char() const noexcept;
Return value |
|
constexpr int replacement_char_size() const noexcept;
Return value |
|
constexpr int validate(char32_t ch) const; // noexcept
Effect |
Calls and returns |
constexpr int encoded_char_size(char32_t ch) const; // noexcept
Effect |
Calls and returns |
code_unit* encode_char(code_unit* dest, char32_t ch) const; // noexcept
Effect |
Calls and returns |
void encode_fill
( transcode_dest<CharT>& dest, std::ptrdiff_t count, char32_t ch ) const;
Effect |
Calls and returns
|
std::ptrdiff_t count_codepoints_fast
( const code_unit* src, const code_unit* src_end
, std::ptrdiff_t max_count ) const;
Effect |
Calls and returns |
std::ptrdiff_t count_codepoints
( const code_unit* src, const code_unit* src_end
, std::ptrdiff_t max_count ) const;
Effect |
Calls and returns
|
void write_replacement_char(transcode_dest<CharT>& dest) const;
Effect |
Calls |
char32_t decode_unit(code_unit ch) const;
Effect |
Calls and returns |
encode_char_f<CharT> encode_char_func() const noexcept;
encode_fill_f<CharT> encode_fill_func() const noexcept;
Return value |
|
write_replacement_char_f<CharT> write_replacement_char_func() const noexcept;
Return value |
|
dynamic_transcoder<char32_t, CharT> from_u32() const;
Return value |
|
dynamic_transcoder<CharT, char32_t> to_u32() const;
Return value |
|
dynamic_transcoder<CharT, CharT> sanitizer() const;
Return value |
|
dynamic_transcoder<CharT, char> find_transcoder_to
( tag<char>, charset_id id ) const;
Return value |
|
dynamic_transcoder<char, CharT> find_transcoder_from
( tag<char>, charset_id id ) const;
Return value |
|
dynamic_transcoder<CharT, char8_t> find_transcoder_to
( tag<char8_t>, charset_id id ) const;
Return value |
|
dynamic_transcoder<char8_t, CharT> find_transcoder_from
( tag<char8_t>, charset_id id ) const;
Return value |
|
dynamic_transcoder<CharT, char16_t> find_transcoder_to
( tag<char16_t>, charset_id id ) const;
Return value |
|
dynamic_transcoder<char16_t, CharT> find_transcoder_from
( tag<char16_t>, charset_id id ) const;
Return value |
|
dynamic_transcoder<CharT, wchar_t> find_transcoder_to
( tag<wchar_t>, charset_id id ) const;
Return value |
|
dynamic_transcoder<wchar_t, CharT> find_transcoder_from
( tag<wchar_t>, charset_id id ) const;
Return value |
|
4.18. Function template find_transcoder
template <class SrcCharset, class DstCharset>
auto find_transcoder(SrcCharset src, DstCharset dest);
- Requirements
-
SrcCharset
andDstCharset
are Charset types. - Return type
-
A type that is Transcoder
- Return value
-
-
Returns the default value of
static_transcoder<SrcID, DestID>
if such template instantiation is defined andSrcCharset
is ( or derives from )static_charset<SrcID>
andDstCharset
is ( or derives from )static_charset<DestID>
; -
otherwise, returns
src.sanitizer()
ifsrc.id()
is equal todest.id()
andSrcCharset::code_unit
is the same type asDstCharset::code_unit
; -
otherwise, returns
src.to_u32()
ifDstCharset::code_unit
ischar32_t
; -
otherwise, returns
dest.from_u32()
ifSrcCharset::code_unit
ischar32_t
; -
otherwise, returns
src.find_transcoder_to(dest_ch, dest.id())
if such expression is well-formed and returns a non null transcoder , wheredest_ch
istag<DstCharset::code_unit>{}
-
otherwise, returns
dest.find_transcoder_from(src_ch, src.id())
if such expression is well-formed, wheresrc_sh
istag<SrcCharset::code_unit>{}
-
otherwise returns
dynamic_transcoder<SrcCharset::code_unit, DstCharset::code_unit>{}
, i.e. an null transcoder.
-
When find_transcoder returns an null transcoder
, you still can use decode_encode and decode_encode_size .
|
4.19. Struct template decode_encode_result
namespace strf {
template <typename CharT>
struct decode_encode_result {
const CharT* stale_src_ptr;
DstCharT* dst_ptr;
std::int32_t u32dist;
transcode_stop_reason stop_reason;
};
} // namespace strf
4.20. Struct template decode_encode_size_result
namespace strf {
template <typename CharT>
struct decode_encode_size_result {
std::ptrdiff_t ssize;
const CharT* stale_src_ptr;
std::int32_t u32dist;
transcode_stop_reason stop_reason;
};
} // namespace strf
4.21. Function template decode_encode
The purpose of the following function templates
( decode_encode
, decode_encode_size
,
unsafe_decode_encode
, unsafe_decode_encode_size
) is to
compensate the fact that the library does not provide a
specialization of static_transcoder
for every possible combination of two character encodings.
In other words, while find_transcoder
may fail
( i.e., return a null transcoder ),
decode_encode
works with any
combinations of two Charset objects.
decode_encode
transcodes from one encoding to another using a pivot
buffer; i.e. it transcodes the input string to UTF-32 and then
from UTF-32 to the destination encoding.
The perfomance is naturally expected to be lower than of the trancode
function of a Transcoder object with the same source and destination
encodings ( assuming there is one ).
That’s why it’s usually better to use the
transcode
global function template instead, which delegates to
decode_encode
only when find_transcoder
fails.
There is two main sets of overloads:
-
Overload group 1: whose destination is a range of pointers
-
Overload group 2: whose destination is a
destination
object reference ====decode_encode
overloads that write to a range of pointers
namespace strf {
template <typename SrcCharT, typename DstCharT>
decode_encode_result<SrcCharT> decode_encode
( transcode_f<SrcCharT, char32_t> to_u32
, transcode_f<char32_t, DstCharT> from_u32
, const SrcCharT* src
, const SrcCharT* src_end
, DstCharT* dst
, DstCharT* dst_end
, transcoding_error_notifier* notifier = nullptr
, transcode_flags flags = transcode_flags::none );
}
- Preconditions
-
-
to_u32
is the value returned bysrc_charset.to_u32().transcode_func()
, wheresrc_charset
is a Charset object that represents the source character encoding. -
from_u32
is the value returned bydst_charset.from_u32().transcode_func()
ordst_charset.from_u32().unsafe_transcode_func()
, wheredst_charset
is a Charset object that represents the destination character encoding.
-
- Effect
-
decode_encode
has the same effects as callingT::transcode(src, src_end, dst, dst_end, notifier, flags)
, ifT
were a Transcoder class that transcodes from the source character encoding to the destination character encoding. - Return value
-
A
decode_encode_result
valueres
, such that-
res.stop_reason
( seetranscode_stop_reason
) -
res.stale_src_ptr
is not the pointer past the last read element in the input range[src, src_end)
. Instead, it pointsres.u32dist
codepoints before that.The pointer past the last read element would actually be:
src_charset .to_u32() .transcode_size (res.stale_ptr, src_end, res.u32dist, flags) .src_ptr
, where:
-
src_charset
is a Charset object that describes the source character encoding
-
-
namespace strf {
template < typename SrcCharset, typename DstCharset
, typename SrcCharT, typename DstCharT >
decode_encode_result<SrcCharT> decode_encode
( SrcCharset src_charset
, DstCharset dst_charset
, const SrcCharT* src
, const SrcCharT* src_end
, DstCharT* dst
, DstCharT* dst_end
, transcoding_error_notifier* notifier = nullptr
, transcode_flags flags = transcode_flags::none );
}
- Effect
-
Equivalent to
decode_encode
( src_charset.{to_u32}().{Transcoder_transcode_func}()
, dst_charset.{from_u32}().{Transcoder_transcode_func}()
, src, src_end, dst, dst_end, err_notifier, flags )
- Compile-time requirements
-
-
SrcCharset
andDstCharset
satisfy Charset -
SrcCharset::code_unit
is the same type asSrcCharT
-
DstCharset::code_unit
is the same type asDstCharT
-
namespace strf {
template < template <class> class SrcCharsetTmpl
, template <class> class DstCharsetTmpl
, typename SrcCharT
, typename DstCharT >
decode_encode_result<SrcCharT> decode_encode
( const SrcCharT* src
, const SrcCharT* src_end
, DstCharT* dst
, DstCharT* dst_end
, transcoding_error_notifier* notifier = nullptr
, transcode_flags flags = transcode_flags::none );
}
- Effect and postconditions
-
Equivalent to
decode_encode
( SrcCharsetTmpl<SrcCharT>(), DstCharsetTmpl<DstCharT>()
, src, src_end, dst, dst_end, err_notifier, flags )
- Compile-time requirements
-
-
SrcCharsetTmpl<SrcCharT>
is an instance ofstatic_charset
-
DstCharsetTmpl<DstCharT>
is an instance ofstatic_charset
-
SrcCharsetTmpl<SrcCharT>::code_unit
isSrcCharT
-
DstCharsetTmpl<DstCharT>::code_unit
isDstCharT
-
decode_encode
overloads that write to a destination<DestCharT>&
namespace strf {
template <typename SrcCharT, typename DstCharT>
decode_encode_size_result<SrcCharT> decode_encode
( transcode_f<SrcCharT, char32_t> to_u32
, transcode_f<char32_t, DstCharT> from_u32
, const SrcCharT* src
, const SrcCharT* src_end
, destination<DstCharT>& dst
, transcoding_error_notifier* err_notifier = nullptr
, transcode_flags flags = transcode_flags::none );
}
Equivalent to the decode_encode
overload that writes to a range of pointers
( see here ), but writes instead to a
destination<DstCharT>&
.
namespace strf {
template < typename SrcCharset, typename DstCharset
, typename SrcCharT, typename DstCharT >
inline STRF_HD decode_encode_size_result<SrcCharT> decode_encode
( SrcCharset src_charset
, DstCharset dst_charset
, const SrcCharT* src
, const SrcCharT* src_end
, destination<DstCharT>& dst
, transcoding_error_notifier* err_notifier = nullptr
, transcode_flags flags = transcode_flags::none )
}
Equivalent to:
decode_encode
( src_charset.{to_u32}().{Transcoder_transcode_func}()
, dst_charset.{from_u32}().{Transcoder_unsafe_transcode_func}()
, src, src_end, dst, err_notifier, flags )
namespace strf {
template < template <class> class SrcCharsetTmpl
, template <class> class DstCharsetTmpl
, typename SrcCharT
, typename DstCharT >
decode_encode_size_result<SrcCharT> decode_encode
( const SrcCharT* src
, const SrcCharT* src_end
, destination<DstCharT>& dst
, DstCharT* dst_end
, transcoding_error_notifier* notifier = nullptr
, transcode_flags flags = transcode_flags::none );
}
Equivalent to
decode_encode
( SrcCharsetTmpl<SrcCharT>(), DstCharsetTmpl<DstCharT>()
, src, src_end, dst, err_notifier, flags )
4.22. Function template decode_encode_size
decode_encode_size
is used to calculate the ammount of
characters that decode_encode
writes. It also uses a pivot
buffer, which is why it’s usually better to use transcode_size
instead.
namespace strf {
template <typename SrcCharT>
decode_encode_size_result<SrcCharT> decode_encode_size
( transcode_f<SrcCharT, char32_t> to_u32
, transcode_size_f<char32_t> size_calc_func
, const SrcCharT* src
, const SrcCharT* src_end
, std::ptrdiff_t limit
, transcode_flags flags = transcode_flags::none );
}
- Preconditions
-
-
to_u32
is the value returned bysrc_charset.to_u32().transcode_func()
, wheresrc_charset
is a Charset object that represents the source character encoding. -
size_calc_func
is the value returned bydst_charset.from_u32().transcode_size_func()
ordst_charset.from_u32().unsafe_transcode_size_func()
wheredst_charset
is a Charset object that represents the destination character encoding. -
All the preconditions of
src_charset.to_u32().transcode_func()
-
- Return value
-
A
decode_encode_result
valueres
, such that-
res.ssize
is equal tores2.ssize
-
res.stop_reason
is equal tores2.stop_reason
-
res.stale_src_ptr
is not the pointer past the last read element in the input range[src, src_end)
. Instead, it pointsres.u32dist
codepoints before that.
, where
res2
is the value that would be returned byT::transcode_size(src, src_end, limit, flags)
, itT
were a Transcoder class that transcodes from the source character encoding to the destination character encoding. -
namespace strf {
template < typename SrcCharset, typename DstCharset, typename SrcCharT >
decode_encode_size_result<SrcCharT> decode_encode_size
( SrcCharset src_charset
, DstCharset dst_charset
, const SrcCharT* src
, const SrcCharT* src_end
, std::ptrdiff_t limit
, transcode_flags flags = transcode_flags::none );
}
- Return value
-
Same as:
decode_encode_size
( src_charset.to_u32().transcode_func()
, dst_charset.from_u32().unsafe_transcode_size_func()
, src, src_end, limit, flags )
- Compile-time requirements
-
-
SrcCharset
andDstCharset
satisfy Charset -
SrcCharset::code_unit
is the same type asSrcCharT
-
namespace strf {
template < template <class> class SrcCharsetTmpl
, typename DstCharset
, typename SrcCharT >
decode_encode_size_result<SrcCharT> decode_encode_size
( const SrcCharT* src
, const SrcCharT* src_end
, std::ptrdiff_t limit
, transcode_flags flags = transcode_flags::none );
}
- Return value
-
Same as:
decode_encode_size
( SrcCharsetTmpl<SrcCharT>(), DstCharset(), src, src_end, limit, flags )
- Compile-time requirements
-
-
SrcCharsetTmpl<SrcCharT>
is an instance ofstatic_charset
-
SrcCharset::code_unit
is the same type asSrcCharT
-
DstCharset
satisfy Charset
-
4.23. Function template unsafe_decode_encode
namespace strf {
1template <typename SrcCharT, typename DstCharT>
decode_encode_result<SrcCharT> unsafe_decode_encode
( transcode_f<SrcCharT, char32_t> to_u32
, transcode_f<char32_t, DstCharT> from_u32
, const SrcCharT* src
, const SrcCharT* src_end
, DstCharT* dst
, DstCharT* dst_end
, transcoding_error_notifier* notifier = nullptr
, transcode_flags flags = transcode_flags::none );
}
- Preconditions
-
to_u32
is the value returned bysrc_charset.to_u32().unsafe_transcode_func()
, wheresrc_charset
is a Charset object that represents the sournce character encoding. -
from_u32
is the value returned bydst_charset.from_u32().unsafe_transcode_func()
, wheredst_charset
is a Charset object that represents the destination character encoding. -
All the perconditions of
src_charset.to_u32().unsafe_transcode_func()
.
- Effect
unsafe_decode_encode
has the same effects as calling
T::unsafe_transcode(src, src_end, dst, dst_end, notifier, flags)
,
if T
were a Transcoder class that transcodes from
the source character encoding to the destination character encoding.
- Return value
-
A
decode_encode_result
valueres
, such that-
res.stop_reason
is equal tores2.ssize
-
res.dst_ptr
is equal tores2.dst_ptr
-
res.stale_src_ptr
is not the pointer past the last read element in the input range[src, src_end)
. Instead, it pointsres.u32dist
codepoints before that.
, where
res2
is the value that would be returned byT::unsafe_transcode(src, src_end, dst, dst_end, notifier, flags)
, ifT
were a Transcoder class that transcodes from the source character encoding to the destination character encoding. -
namespace strf {
template < typename SrcCharset, typename DstCharset
, typename SrcCharT, typename DstCharT >
decode_encode_result<SrcCharT> unsafe_decode_encode
( SrcCharset src_charset
, DstCharset dst_charset
, const SrcCharT* src
, const SrcCharT* src_end
, DstCharT* dst
, DstCharT* dst_end
, transcoding_error_notifier* notifier = nullptr
, transcode_flags flags = transcode_flags::none );
}
- Effect
-
Equivalent to
unsafe_decode_encode
( src_charset.to_u32().unsafe_transcode_func()
, dst_charset.from_u32().unsafe_transcode_func()
, src, src_end, dst, dst_end, err_notifier, flags )
- Compile-time requirements
-
-
SrcCharset
andDstCharset
satisfy Charset -
SrcCharset::code_unit
is the same type asSrcCharT
-
DstCharset::code_unit
is the same type asDstCharT
-
namespace strf {
template < template <class> class SrcCharsetTmpl
, template <class> class DstCharsetTmpl
, typename SrcCharT
, typename DstCharT >
decode_encode_result<SrcCharT> unsafe_decode_encode
( const SrcCharT* src
, const SrcCharT* src_end
, DstCharT* dst
, DstCharT* dst_end
, transcoding_error_notifier* notifier = nullptr
, transcode_flags flags = transcode_flags::none );
}
- Effect and postconditions
-
Equivalent to
unsafe_decode_encode
( SrcCharsetTmpl<SrcCharT>(), DstCharsetTmpl<DstCharT>()
, src, src_end, dst, dst_end, err_notifier, flags )
- Compile-time requirements
-
-
SrcCharsetTmpl<SrcCharT>
is an instance ofstatic_charset
-
DstCharsetTmpl<DstCharT>
is an instance ofstatic_charset
-
SrcCharsetTmpl<SrcCharT>::code_unit
isSrcCharT
-
DstCharsetTmpl<DstCharT>::code_unit
isDstCharT
-
4.24. Function template unsafe_decode_encode_size
unsafe_decode_encode_size
is used to calculate the ammount of
characters that unsafe_decode_encode
writes.
namespace strf {
template <typename SrcCharT>
decode_encode_size_result<SrcCharT> unsafe_decode_encode_size
( transcode_f<SrcCharT, char32_t> to_u32
, transcode_size_f<char32_t> size_calc_func
, const SrcCharT* src
, const SrcCharT* src_end
, std::ptrdiff_t limit
, transcode_flags flags = transcode_flags::none );
}
- Preconditions
-
to_u32
is the value returned bysrc_charset.to_u32().unsafe_transcode_func()
, wheresrc_charset
is a Charset object that represents the source character encoding. -
size_calc_func
is the value returned bydst_charset.from_u32().unsafe_transcode_size_func()
wheredst_charset
is a Charset object that represents the destination character encoding. -
All the preconditions of
src_charset.to_u32().unsafe_transcode_func()
- Return value
-
A
decode_encode_result
valueres
, such that-
res.ssize
is equal tores2.ssize
-
res.stop_reason
is equal tores2.stop_reason
-
res.stale_ptr
is not the pointer past the last read element in the input range[src, src_end)
. Instead, it pointsres.u32dist
codepoints before that.
, where
res2
is the value that would be returned byT::unsafe_transcode_size(src, src_end, limit, flags)
, ifT
were a Transcoder class that transcodes from the source character encoding to the destination character encoding. -
namespace strf {
template < typename SrcCharset, typename DstCharset, typename SrcCharT >
decode_encode_size_result<SrcCharT> unsafe_decode_encode_size
( SrcCharset src_charset
, DstCharset dst_charset
, const SrcCharT* src
, const SrcCharT* src_end
, std::ptrdiff_t limit
, transcode_flags flags = transcode_flags::none );
}
- Return value
-
Same as:
unsafe_decode_encode_size
( src_charset.to_u32().unsafe_transcode_func()
, dst_charset.from_u32().unsafe_transcode_size_func()
, src, src_end, limit, flags )
- Compile-time requirements
-
-
SrcCharset
andDstCharset
satisfy Charset -
SrcCharset::code_unit
is the same type asSrcCharT
-
namespace strf {
template < template <class> class SrcCharsetTmpl
, typename DstCharset
, typename SrcCharT >
decode_encode_size_result<SrcCharT> unsafe_decode_encode_size
( const SrcCharT* src
, const SrcCharT* src_end
, std::ptrdiff_t limit
, transcode_flags flags = transcode_flags::none );
}
- Return value
-
Same as:
unsafe_decode_encode_size
( SrcCharsetTmpl<SrcCharT>(), DstCharset(), src, src_end, limit, flags )
- Compile-time requirements
-
-
SrcCharsetTmpl<SrcCharT>
is an instance ofstatic_charset
-
SrcCharset::code_unit
is the same type asSrcCharT
-
DstCharset
satisfy Charset
-
4.25. Function template transcode
There is two main sets of overloads:
-
Overload group 1: whose destination is a range of pointers
-
Overload group 2: whose destination is a
destination
object reference
transcode
overloads that write to a range of pointers
namespace strf {
template < typename SrcCharset, typename DstCharset
, typename SrcCharT, typename DstCharT >
decode_encode_result<SrcCharT> transcode
( SrcCharset src_charset
, DstCharset dst_charset
, const SrcCharT* src
, const SrcCharT* src_end
, DstCharT* dst
, DstCharT* dst_end
, transcoding_error_notifier* err_notifier = nullptr
, transcode_flags flags = transcode_flags::none );
}
- Effect
auto func = find_transcoder(src_charset, dst_charset).transcode_func()
if (func != nullptr) {
auto result = func(src, src_end, dst, dst_end, err_notifier, flags);
return {result.ptr, result.dst_ptr, 0, result.stop_reason};
}
return decode_encode ( src_charset, dst_charset, src, src_end
, dst, dst_end, err_notifier, flags );
- Compile-time requirements
-
-
SrcCharset
andDstCharset
satisfy Charset -
SrcCharset::code_unit
is the same type asSrcCharT
-
DstCharset::code_unit
is the same type asDstCharT
-
namespace strf {
template < template <class> class SrcCharsetTmpl
, template <class> class DstCharsetTmpl
, typename SrcCharT, typename DstCharT >
decode_encode_result<SrcCharT> transcode
( const SrcCharT* src
, const SrcCharT* src_end
, DstCharT* dst
, DstCharT* dst_end
, transcoding_error_notifier* err_notifier = nullptr
, transcode_flags flags = transcode_flags::none );
}
- Effect
-
Same as:
transcode
( SrcCharsetTmpl<SrcCharT>()
, DstCharsetTmpl<DstCharT>()
, src, src_end, dst, dst_end, err_notifier, flags );
- Compile-time requirements
-
-
SrcCharsetTmpl<SrcCharT>
is an instance ofstatic_charset
-
DstCharsetTmpl<DstCharT>
is an instance ofstatic_charset
-
SrcCharsetTmpl<SrcCharT>::code_unit
isSrcCharT
-
DstCharsetTmpl<DstCharT>::code_unit
isDstCharT
-
transcode
overloads that write to destination<DestCharT>&
namespace strf {
template <typename SrcCharT, typename DstCharT>
{ transcode_size_result<SrcCharT> transcode
( transcode_f<SrcCharT, DstCharT> func
, const SrcCharT* src
, const SrcCharT* src_end
, destination<DstCharT>& dst
, transcoding_error_notifier* err_notifier = nullptr
, transcode_flags flags = transcode_flags::none );
}
Contrary to the other overloads of transcode
global function template,
this one never calls any overload of decode_encode
.
- Effect
-
Uses
func
to transcode the input range (src, src_end
), writting the result todst
- Return value
-
A
transcode_size_result
valueres
, such that:-
res.stop_reason
( seetranscode_stop_reason
) -
res.src_ptr
points immediately after the last element in the range[src, src_end)
that has been transcoded. -
res.ssize
is the amount of code units written todst
-
namespace strf {
template < typename SrcCharset, typename DstCharset
, typename SrcCharT, typename DstCharT >
decode_encode_size_result<SrcCharT> transcode
( SrcCharset src_charset
, DstCharset dst_charset
, const SrcCharT* src
, const SrcCharT* src_end
, destination<DstCharT>& dst
, transcoding_error_notifier* err_notifier = nullptr
, transcode_flags flags = transcode_flags::none );
}
- Effect
auto func = find_transcoder(src_charset, dst_charset).transcode_func();
if (func != nullptr) {
auto result = trancode(src, src_end, dst, err_notifier, flags);
return {result.ssize, result.src_ptr, 0, result.stop_reason};
}
const auto src_to_u32 = src_charset.to_u32().transcode_func();
const auto u32_to_dst = dst_charset.from_u32().unsafe_transcode_func();
return decode_encode
( src_to_u32, u32_to_dst
, src, src_end, dst, err_notifier, flags );
- Compile-time requirements
-
-
SrcCharset
andDstCharset
satisfy Charset -
SrcCharset::code_unit
is the same type asSrcCharT
-
DstCharset::code_unit
is the same type asDstCharT
-
namespace strf {
template < template <class> class SrcCharsetTmpl
, template <class> class DstCharsetTmpl
, typename SrcCharT, typename DstCharT >
decode_encode_result<SrcCharT> transcode
( const SrcCharT* src
, const SrcCharT* src_end
, destination<DstCharT>& dst
, transcoding_error_notifier* err_notifier = nullptr
, transcode_flags flags = transcode_flags::none );
}
- Effect
-
Same as:
transcode
( SrcCharsetTmpl<SrcCharT>()
, DstCharsetTmpl<DstCharT>()
, src, src_end, dst, err_notifier, flags );
- Compile-time requirements
-
-
SrcCharsetTmpl<SrcCharT>
is an instance ofstatic_charset
-
DstCharsetTmpl<DstCharT>
is an instance ofstatic_charset
-
SrcCharsetTmpl<SrcCharT>::code_unit
isSrcCharT
-
DstCharsetTmpl<DstCharT>::code_unit
isDstCharT
-
4.26. Function template transcode_size
namespace strf {
template < typename SrcCharset, typename DstCharset, typename SrcCharT >
decode_encode_size_result<SrcCharT> transcode_size
( SrcCharset src_charset
, DstCharset dst_charset
, const SrcCharT* src
, const SrcCharT* src_end
, std::ptrdiff_t limit
, strf::transcode_flags flags = transcode_flags::none );
}
- Effect and Return value
auto func = find_transcoder(src_charset, dst_charset).transcode_size_func()
if (func != nullptr) {
auto result = func(src, src_end, limit, flags);
return {result.ssize, result.src_ptr, 0, result.stop_reason};
}
return decode_encode_size (src_charset, dst_charset, src, src_end, limit, flags);
- Compile-time requirements
-
-
SrcCharset
andDstCharset
satisfy Charset -
SrcCharset::code_unit
is the same type asSrcCharT
-
namespace strf {
template < template <class> class SrcCharsetTmpl
, typename DstCharset
, typename SrcCharT >
decode_encode_size_result<SrcCharT> transcode_size
( const SrcCharT* src
, const SrcCharT* src_end
, std::ptrdiff_t limit
, strf::transcode_flags flags = transcode_flags::none );
}
- Effect and Return value
-
Same as
transcode_size
( SrcCharsetTmpl<SrcCharT>(), DstCharset(), src, src_end, limit, flags )
- Compile-time requirements
-
-
SrcCharsetTmpl<SrcCharT>
is an instance ofstatic_charset
-
DstCharset
is an instance ofstatic_charset
-
SrcCharsetTmpl<SrcCharT>::code_unit
isSrcCharT
-
4.27. Function template unsafe_transcode
There is two main sets of overloads:
-
Overload group 1: whose destination is a range of pointers
-
Overload group 2: whose destination is a
destination
object reference
unsafe_transcode
overloads that write to a range of pointers
namespace strf {
template < typename SrcCharset, typename DstCharset
, typename SrcCharT, typename DstCharT >
void unsafe_transcode
( SrcCharset src_charset
, DstCharset dst_charset
, const SrcCharT* src
, const SrcCharT* src_end
, DstCharT* dst
, DstCharT* dst_end
, transcoding_error_notifier* err_notifier = nullptr
, transcode_flags flags = transcode_flags::none );
}
- Effect
auto func = find_transcoder(src_charset, dst_charset).unsafe_transcode_func()
if (func != nullptr) {
auto res = func(src, src_end, dst, dst_end, err_notifier);
return {res.src_ptr, res.dst_ptr, 0, res.stop_reason};
}
return unsafe_decode_encode
( src_charset, dst_charset, src, src_end, dst, dst_end, err_notifier, flags );
- Compile-time requirements
-
-
SrcCharset
andDstCharset
satisfy Charset -
SrcCharset::code_unit
is the same type asSrcCharT
-
DstCharset::code_unit
is the same type asDstCharT
-
namespace strf {
template < template <class> class SrcCharsetTmpl
, template <class> class DstCharsetTmpl
, typename SrcCharT, typename DstCharT >
void unsafe_transcode
( const SrcCharT* src
, const SrcCharT* src_end
, DstCharT* dst
, DstCharT* dst_end
, transcoding_error_notifier* err_notifier = nullptr
, transcode_flags flags = transcode_flags::none );
}
- Effect
-
Same as:
unsafe_transcode
( SrcCharsetTmpl<SrcCharT>()
, DstCharsetTmpl<DstCharT>()
, src, src_end, dst, dst_end, err_notifier, flags );
- Compile-time requirements
-
-
SrcCharsetTmpl<SrcCharT>
is an instance ofstatic_charset
-
DstCharsetTmpl<DstCharT>
is an instance ofstatic_charset
-
SrcCharsetTmpl<SrcCharT>::code_unit
isSrcCharT
-
DstCharsetTmpl<DstCharT>::code_unit
isDstCharT
-
unsafe_transcode
overloads that write to destination<DestCharT>&
namespace strf {
template < typename SrcCharset, typename DstCharset
, typename SrcCharT, typename DstCharT >
decode_encode_size_result<SrcCharT> unsafe_transcode
( SrcCharset src_charset
, DstCharset dst_charset
, const SrcCharT* src
, const SrcCharT* src_end
, destination<DstCharT>& dst
, transcoding_error_notifier* err_notifier = nullptr
, transcode_flags flags = transcode_flags::none );
}
- Effect
auto func = find_transcoder(src_charset, dst_charset).unsafe_transcode_func();
if (func != nullptr) {
auto result = trancode(src, src_end, dst, err_notifier, flags);
return {result.ssize, result.src_ptr, 0, result.stop_reason};
}
const auto src_to_u32 = src_charset.to_u32().unsafe_transcode_func();
const auto u32_to_dst = dst_charset.from_u32().unsafe_transcode_func();
return decode_encode
( src_to_u32, u32_to_dst
, src, src_end, dst, err_notifier, flags );
- Compile-time requirements
-
-
SrcCharset
andDstCharset
satisfy Charset -
SrcCharset::code_unit
is the same type asSrcCharT
-
DstCharset::code_unit
is the same type asDstCharT
-
namespace strf {
template < template <class> class SrcCharsetTmpl
, template <class> class DstCharsetTmpl
, typename SrcCharT, typename DstCharT >
decode_encode_result<SrcCharT> unsafe_transcode
( const SrcCharT* src
, const SrcCharT* src_end
, destination<DstCharT>& dst
, transcoding_error_notifier* err_notifier = nullptr
, transcode_flags flags = transcode_flags::none );
}
- Effect
-
Same as:
unsafe_transcode
( SrcCharsetTmpl<SrcCharT>()
, DstCharsetTmpl<DstCharT>()
, src, src_end, dst, err_notifier, flags );
- Compile-time requirements
-
-
SrcCharsetTmpl<SrcCharT>
is an instance ofstatic_charset
-
DstCharsetTmpl<DstCharT>
is an instance ofstatic_charset
-
SrcCharsetTmpl<SrcCharT>::code_unit
isSrcCharT
-
DstCharsetTmpl<DstCharT>::code_unit
isDstCharT
-
4.28. Function template unsafe_transcode_size
namespace strf {
template < typename SrcCharset, typename DstCharset, typename SrcCharT >
std::ptrdiff_t unsafe_transcode_size
( SrcCharset src_charset
, DstCharset dst_charset
, const SrcCharT* src
, const SrcCharT* src_end
, std::ptrdiff_t limit
, transcode_flags flags = transcode_flags::none );
}
- Effect and Return value
auto func = find_transcoder(src_charset, dst_charset).unsafe_transcode_size_func()
if (func != nullptr) {
auto res = func(src, src_end, limit, flags);
return {res.ssize, res.src_ptr, 0, res.stop_reason}
}
return unsafe_decode_encode_size (src_charset, dst_charset, src, src_end, limit, flags);
- Compile-time requirements
-
-
SrcCharset
andDstCharset
satisfy Charset -
SrcCharset::code_unit
is the same type asSrcCharT
-
namespace strf {
template < template <class> class SrcCharsetTmpl
, typename DstCharset
, typename SrcCharT >
std::ptrdiff_t unsafe_transcode_size
( const SrcCharT* src
, const SrcCharT* src_end
, std::ptrdiff_t limit
, transcode_flags flags = transcode_flags::none );
}
- Effect and Return value
-
Same as
unsafe_transcode_size
( SrcCharsetTmpl<SrcCharT>(), DstCharset(), src, src_end, limit, flags )
- Compile-time requirements
-
-
SrcCharsetTmpl<SrcCharT>
is an instance ofstatic_charset
-
DstCharset
is an instance ofstatic_charset
-
SrcCharsetTmpl<SrcCharT>::code_unit
isSrcCharT
-
4.29. Type aliases for charsets
namespace strf {
template <class CharT>
using ascii_t = static_charset<CharT, scid_ascii>;
template <class CharT>
using iso_8859_1_t = static_charset<CharT, scid_iso_8859_1>;
template <class CharT>
using iso_8859_2_t = static_charset<CharT, scid_iso_8859_2>;
template <class CharT>
using iso_8859_3_t = static_charset<CharT, scid_iso_8859_3>;
template <class CharT>
using iso_8859_4_t = static_charset<CharT, scid_iso_8859_4>;
template <class CharT>
using iso_8859_5_t = static_charset<CharT, scid_iso_8859_5>;
template <class CharT>
using iso_8859_6_t = static_charset<CharT, scid_iso_8859_6>;
template <class CharT>
using iso_8859_7_t = static_charset<CharT, scid_iso_8859_7>;
template <class CharT>
using iso_8859_8_t = static_charset<CharT, scid_iso_8859_8>;
template <class CharT>
using iso_8859_9_t = static_charset<CharT, scid_iso_8859_9>;
template <class CharT>
using iso_8859_10_t = static_charset<CharT, scid_iso_8859_10>;
template <class CharT>
using iso_8859_11_t = static_charset<CharT, scid_iso_8859_11>;
template <class CharT>
using iso_8859_13_t = static_charset<CharT, scid_iso_8859_13>;
template <class CharT>
using iso_8859_14_t = static_charset<CharT, scid_iso_8859_14>;
template <class CharT>
using iso_8859_15_t = static_charset<CharT, scid_iso_8859_15>;
template <class CharT>
using iso_8859_16_t = static_charset<CharT, scid_iso_8859_16>;
template <class CharT>
using windows_1250_t = static_charset<CharT, scid_windows_1250>;
template <class CharT>
using windows_1251_t = static_charset<CharT, scid_windows_1251>;
template <class CharT>
using windows_1252_t = static_charset<CharT, scid_windows_1252>;
template <class CharT>
using windows_1253_t = static_charset<CharT, scid_windows_1253>;
template <class CharT>
using windows_1254_t = static_charset<CharT, scid_windows_1254>;
template <class CharT>
using windows_1255_t = static_charset<CharT, scid_windows_1255>;
template <class CharT>
using windows_1256_t = static_charset<CharT, scid_windows_1256>;
template <class CharT>
using windows_1257_t = static_charset<CharT, scid_windows_1257>;
template <class CharT>
using windows_1258_t = static_charset<CharT, scid_windows_1258>;
template <class CharT>
using utf8_t = static_charset<CharT, scid_utf8>;
template <class CharT>
using utf16_t = static_charset<CharT, scid_utf16>;
template <class CharT>
using utf32_t = static_charset<CharT, scid_utf32>;
template <class CharT>
using utf_t = /* see below */;
} // namespace strf
template <class CharT>
using utf_t = /* ... */;
utf_t<CharT>
is an alias to utf8_t<CharT>
, utf16_t<CharT>
or utf32_t<CharT>
,
depending on the value of sizeof(CharT)
.
4.30. Template variable for charsets
namespace strf {
template <class CharT> constexpr ascii_t<CharT> ascii = {};
template <class CharT> constexpr iso_8859_1_t<CharT> iso_8859_1 = {};
template <class CharT> constexpr iso_8859_2_t<CharT> iso_8859_2 = {};
template <class CharT> constexpr iso_8859_3_t<CharT> iso_8859_3 = {};
template <class CharT> constexpr iso_8859_4_t<CharT> iso_8859_4 = {};
template <class CharT> constexpr iso_8859_5_t<CharT> iso_8859_5 = {};
template <class CharT> constexpr iso_8859_6_t<CharT> iso_8859_6 = {};
template <class CharT> constexpr iso_8859_7_t<CharT> iso_8859_7 = {};
template <class CharT> constexpr iso_8859_8_t<CharT> iso_8859_8 = {};
template <class CharT> constexpr iso_8859_9_t<CharT> iso_8859_9 = {};
template <class CharT> constexpr iso_8859_10_t<CharT> iso_8859_10 = {};
template <class CharT> constexpr iso_8859_11_t<CharT> iso_8859_11 = {};
template <class CharT> constexpr iso_8859_13_t<CharT> iso_8859_13 = {};
template <class CharT> constexpr iso_8859_14_t<CharT> iso_8859_14 = {};
template <class CharT> constexpr iso_8859_15_t<CharT> iso_8859_15 = {};
template <class CharT> constexpr iso_8859_16_t<CharT> iso_8859_16 = {};
template <class CharT> constexpr windows_1250_t<CharT> windows_1250 = {};
template <class CharT> constexpr windows_1251_t<CharT> windows_1251 = {};
template <class CharT> constexpr windows_1252_t<CharT> windows_1252 = {};
template <class CharT> constexpr windows_1253_t<CharT> windows_1253 = {};
template <class CharT> constexpr windows_1254_t<CharT> windows_1254 = {};
template <class CharT> constexpr windows_1255_t<CharT> windows_1255 = {};
template <class CharT> constexpr windows_1256_t<CharT> windows_1256 = {};
template <class CharT> constexpr windows_1257_t<CharT> windows_1257 = {};
template <class CharT> constexpr windows_1258_t<CharT> windows_1258 = {};
template <class CharT> constexpr utf8_t<CharT> utf8 = {};
template <class CharT> constexpr utf16_t<CharT> utf16 = {};
template <class CharT> constexpr utf32_t<CharT> utf32 = {};
template <class CharT> constexpr utf_t<CharT> utf = {};
} // namespace strf
5. Width Calculation
5.1. Facet category width_calculator_c
namespace strf {
struct width_calculator_c
{
static constexpr bool constrainable = true;
static constexpr width_as_u32len get_default() noexcept;
};
} // namespace strf
For a type to be a facet of the width_calculator_c
category, it has to
satisfy the WidthCalculator requirements.
Type requirement WidthCalculator
Given
-
CharT
, one of the types:char
,char8_t
,char16_t
,char32_t
orwchar_t
-
CharsetT
, a Charset type for typeCharT
-
charset
, a value of typeCharsetT
-
ch
a value of typeCharT
-
limit
, a value of typewidth_t
-
str
, a value of typeconst CharT*
pointing to a string encoded according tocharset
. -
str_end
, a value of typeconst CharT*
pointing immediately after the last character of the string that begin atstr
For a type X
to be a WidthCalculator, given an object x
of type X
,
the following syntax and requirements have to be satisfied:
X::category
A type alias to width_calculator_c
.
x.char_width(charset, ch)
Return type | |
Return value |
The width of |
x.str_width(charset, limit, str, str_end)
Return type | |
Return value |
The width of the string |
x.str_width_and_pos(charset, limit, str, str_end)
Effect |
Calculates the size and width of the longest substring
of [ |
Return type |
|
Return value |
A value
|
The library provides three classes that
satisfy WidthCalculator: fast_width , width_as_fast_u32len ,
width_as_u32len .
|
Struct width_and_ptr
template <typename CharT>
struct width_and_ptr {
width_t width;
const CharT* ptr = nullptr;
};
5.2. Class fast_width_t
Class fast_width_t
is a facet of the category width_calculator_c
that evaluates the width of a string as its size.
class fast_width_t final
{
public:
using category = width_calculator_c;
template <typename Charset>
constexpr width_t char_width
( Charset
, typename Charset::code_unit ) const noexcept;
template <typename Charset>
constexpr width_t str_width
( Charset
, width_t limit
, const typename Charset::code_unit* str
, const typename Charset::code_unit* str_end ) const noexcept;
template <typename Charset>
auto str_width_and_pos
( Charset
, width_t limit
, const typename Charset::code_unit* str
, const typename Charset::code_unit* str_end ) const noexcept
-> width_and_ptr<typename Charset::code_unit>;
};
constexpr fast_width_t fast_width {};
Return value |
|
template <typename Charset>
auto str_width_and_pos
( Charset
, width_t limit
, const typename Charset::code_unit* str
, const typename Charset::code_unit* str_end ) const noexcept
-> width_and_ptr<typename Charset::code_unit>;
Return value |
The return value
|
5.3. Class width_as_fast_u32len_t
Class width_as_fast_u32len_t
is a facet of the category width_calculator_c
.
It evaluates the width of a string as the number of Unicode code points.
However, to gain performance, differently from width_as_u32len
,
it assumes that the string is totally conformant to its encoding.
For example, if the charset is UTF-8 then str_width
may simply return the number of bytes whose bit pattern does not
characterizes it as a continuation byte
( 10xxxxxx
).
class width_as_fast_u32len_t final
{
public:
using category = width_calculator_c;
template <typename Charset>
constexpr width_t char_width
( Charset cs
, typename Charset::code_unit ) const noexcept;
template <typename Charset>
width_t str_width
( Charset cs
, width_t limit
, const typename Charset::code_unit* str
, const typename Charset::code_unit* str_end ) const noexcept;
template <typename Charset>
auto str_width_and_pos
( Charset cs
, width_t limit
, const typename Charset::code_unit* str
, const typename Charset::code_unit* str_end ) const noexcept
-> width_and_ptr<typename Charset::code_unit>;
};
constexpr width_as_fast_u32len_t width_as_fast_u32len {};
Return value |
|
template <typename Charset>
auto str_width_and_pos
( Charset cs
, width_t limit
, const typename Charset::code_unit* str
, const typename Charset::code_unit* str_end ) const noexcept
-> width_and_ptr<typename Charset::code_unit>;
Return value |
The return value
|
5.4. Class width_as_u32len_t
Class width_as_fast_u32len_t
is a facet of the category width_calculator_c
.
It evaluates the width of a string as the number of Unicode code points,
assuming that any non-conformity to its corresponding charset is replaced
by one codepoint ( since it should be replaced by the
replacement character "\uFFFD"
(�) ).
class width_as_u32len_t final
{
public:
using category = width_calculator_c;
template <typename Charset>
constexpr width_t char_width
( Charset cs
, typename Charset::code_unit ) const noexcept;
template <typename Charset>
width_t str_width
( Charset cs
, width_t limit
, const typename Charset::code_unit* str
, const typename Charset::code_unit* str_end ) const noexcept;
template <typename Charset>
auto str_width_and_pos
( Charset cs
, width_t limit
, const typename Charset::code_unit* str
, const typename Charset::code_unit* str_end ) const noexcept
-> width_and_ptr<typename Charset::code_unit>;
};
constexpr width_as_u32len_t width_as_u32len = {};
Return value |
|
template <typename Charset>
auto str_width_and_pos
( Charset cs
, width_t limit
, const typename Charset::code_unit* str
, const typename Charset::code_unit* str_end ) const noexcept
-> width_and_ptr<typename Charset::code_unit>;
Return value |
The return value
|
5.5. Class std_width_calc
The facet std_width_calc
calculates the width just as
specified to std::format
.
class std_width_calc {
public:
using category = width_calculator_c;
template <typename Charset>
static width_t char_width
( Charset cs
, typename Charset::code_unit ) const;
template <typename Charset>
static width_t str_width
( Charset cs
, width_t limit
, const typename Charset::code_unit* str
, const typename Charset::code_unit* str_end ) const;
template <typename Charset>
static auto str_width_and_pos
( Charset cs
, width_t limit
, const typename Charset::code_unit* str
, const typename Charset::code_unit* str_end ) const
-> width_and_ptr<typename Charset::code_unit>;
};
Member functions
Return value |
( (0x1100 <= ch32 && ch32 <= 0x115F)
|| (0x2329 <= ch32 && ch32 <= 0x232A)
|| (0x2E80 <= ch32 && ch32 <= 0x303E)
|| (0x3040 <= ch32 && ch32 <= 0xA4CF)
|| (0xAC00 <= ch32 && ch32 <= 0xD7A3)
|| (0xF900 <= ch32 && ch32 <= 0xFAFF)
|| (0xFE10 <= ch32 && ch32 <= 0xFE19)
|| (0xFE30 <= ch32 && ch32 <= 0xFE6F)
|| (0xFF00 <= ch32 && ch32 <= 0xFF60)
|| (0xFFE0 <= ch32 && ch32 <= 0xFFE6)
|| (0x1F300 <= ch32 && ch32 <= 0x1F64F)
|| (0x1F900 <= ch32 && ch32 <= 0x1F9FF)
|| (0x20000 <= ch32 && ch32 <= 0x2FFFD)
|| (0x30000 <= ch32 && ch32 <= 0x3FFFD) ) ? width_t(2) : width_t(1)
, where ch32
is the return value of cs.decode_unit(ch)
- Return value
-
std::min(limit, w)
, wherew
is the sum of the grapheme clusters widths in the UTF-32 string obtained by convertingstr
to UTF-32 viacs
, i.e. by callingThe width of each grapheme cluster is assumed to be equal to the width of its first codepoints
ch32
, which is assumed to equal tochar_width(utf<char32_t>, ch32)
.
template <typename Charset>
static auto str_width_and_pos
( Charset cs
, width_t limit
, const typename Charset::code_unit* str
, const typename Charset::code_unit* str_end ) const
-> width_and_ptr<typename Charset::code_unit>;
- Return value
-
a value
r
such that-
r.width
is same value returned bystr_width(cs, limit, str, str_end )
-
r.ptr
is greatest pointer not greater thanstr_end
such that the expression below evaluates totrue
:str_width(cs, strf::width_t::max(), str, r.ptr) <= limit
-
5.6. Class width_t
width_t
is an signed type that implements
Q16.16 arithmetics and
is used to represent width of textual content when
text alignment formatting is used.
The value of width_t(1)
corresponds to one en.
namespace strf {
class width_t {
public:
struct from_underlying_tag{};
constexpr width_t() noexcept;
constexpr width_t(std::integral auto) noexcept;
constexpr width_t(const width_t&) noexcept;
constexpr width_t(from_underlying_tag, std::int32_t) noexcept;
constexpr width_t& operator=(const width_t& other) noexcept;
constexpr width_t& operator=(std::int16_t& x) noexcept;
constexpr bool operator==(const width_t& other) const noexcept;
constexpr bool operator!=(const width_t& other) const noexcept;
constexpr bool operator<(const width_t& other) const noexcept;
constexpr bool operator>(const width_t& other) const noexcept;
constexpr bool operator<=(const width_t& other) const noexcept;
constexpr bool operator>=(const width_t& other) const noexcept;
constexpr std::int16_t floor() const noexcept;
constexpr std::int32_t ceil() const noexcept;
constexpr std::int32_t round() const noexcept;
constexpr width_t operator-() const noexcept;
constexpr width_t operator+() const noexcept;
constexpr width_t& operator+=(width_t other) noexcept;
constexpr width_t& operator-=(width_t other) noexcept;
constexpr width_t& operator*=(std::int16_t m) noexcept;
constexpr width_t& operator/=(std::int16_t d) noexcept;
constexpr width_t& operator*=(width_t other) noexcept;
constexpr width_t& operator/=(width_t other) noexcept;
constexpr std::int32_t underlying_value() const noexcept;
constexpr static width_t from_underlying(std::int32_t) noexcept;
constexpr static width_t max() noexcept; // maximum possible value
constexpr static width_t min() noexcept; // minimum possible value
private:
std::int32_t _underlying_value; // exposition only
};
constexpr width_max = width_t::max();
constexpr width_min = width_t::min();
constexpr bool operator==(width_t lhs, std::int16_t rhs) noexcept;
constexpr bool operator==(std::int16_t lhs, width_t rhs) noexcept;
constexpr bool operator!=(width_t lhs, std::int16_t rhs) noexcept;
constexpr bool operator!=(std::int16_t lhs, width_t rhs) noexcept;
constexpr bool operator< (width_t lhs, std::int16_t rhs) noexcept;
constexpr bool operator< (std::int16_t lhs, width_t rhs) noexcept;
constexpr bool operator<=(width_t lhs, std::int16_t rhs) noexcept;
constexpr bool operator<=(std::int16_t lhs, width_t rhs) noexcept;
constexpr bool operator> (width_t lhs, std::int16_t rhs) noexcept;
constexpr bool operator> (std::int16_t lhs, width_t rhs) noexcept;
constexpr bool operator>=(width_t lhs, std::int16_t rhs) noexcept;
constexpr bool operator>=(std::int16_t lhs, width_t rhs) noexcept;
constexpr width_t operator+(width_t lhs, width_t rhs) noexcept;
constexpr width_t operator+(std::int16_t lhs, width_t rhs) noexcept;
constexpr width_t operator+(width_t lhs, std::int16_t rhs) noexcept;
constexpr width_t operator-(width_t lhs, width_t rhs) noexcept;
constexpr width_t operator-(std::int16_t lhs, width_t rhs) noexcept;
constexpr width_t operator-(width_t lhs, std::int16_t rhs) noexcept;
constexpr width_t operator*(width_t lhs, width_t rhs) noexcept;
constexpr width_t operator*(std::int16_t lhs, width_t rhs) noexcept;
constexpr width_t operator*(width_t lhs, std::int16_t rhs) noexcept;
constexpr width_t operator/(width_t lhs, width_t rhs) noexcept;
constexpr width_t operator/(std::int16_t lhs, width_t rhs) noexcept;
constexpr width_t operator/(width_t lhs, std::int16_t rhs) noexcept;
constexpr width_t sat_add(width_t, width_t) noexcept;
constexpr width_t sat_add(width_t w, std::integral auto i) noexcept;
constexpr width_t sat_add(std::integral auto i, width_t w) noexcept;
constexpr width_t sat_sub(width_t, width_t) noexcept;
constexpr width_t sat_sub(width_t w, std::integral auto i) noexcept;
constexpr width_t sat_sub(std::integral auto i, width_t w) noexcept;
constexpr width_t sat_mul(width_t, width_t) noexcept;
constexpr width_t sat_mul(width_t w, std::integral auto i) noexcept;
constexpr width_t sat_mul(std::integral auto i, width_t w) noexcept;
constexpr /* integral type */ compare(width_t, width_t) noexcept;
constexpr /* integral type */ compare(width_t w, std::integral auto i) noexcept;
constexpr /* integral type */ compare(std::integral auto i, width_t w) noexcept;
} // namespace strf
to-do
5.7. width_t
literal _w
namespace strf {
namespace width_literal {
template <char...C>
constexpr width_t operator "" _w()
} // namespace width_literal
} // namespace strf
The suffix _w
can be aplied in floating-points literals in fixed notations as well
as integer literals.
using namespace strf::width_literal;
strf::width_t x = 1.5_w;
x += 0.25_w;
x += 1_w;
assert(x == 2.75_w);
6. Requirements of printable types
This section provides what one needs to be known to add a new printable type or override an existing one.
6.1. Type requirement Printable
A type T
is Printable if:
-
printable_def_of<T>
is defined and is a PrintableDef type -
printable_def_of<T>::forwarded_type
is implicitly convertible fromT
6.2. Type alias template printable_def_of
namespace strf {
struct printable_tag;
template <typename T> struct printable_def;
template <typename T> using printable_def_of = /* see below... */;
} // namespace strf
printable_def_of<T>
is:
-
printable_def_of<std::remove_cvref<T>>
, ifT
is a reference type or has any cv-qualifier -
otherwise, it is
PrintableDef
, whenT
isvalue_and_format<PrintableDef, /*... */>
-
otherwise, it is
printable_def<T>
if such template specialization is defined -
otherwise, it is
decltype(get_printable_def(printable_tag{}, std::declval<T>()))
6.3. Type requirement PrintableDef
Given
-
T
, a PrintableDef type. -
P
, a Printable type such thatprintable_def_of<P>
isT
.
Member types
T::representative
The type used as the template argument in get_facet
.
This means it is the type that is tested by the
the UnaryTypeTrait template argument passed to
constrain
or constrained_fpe
.
T::representative
is optional if T
is an intance of prinatable_def
.
When prinatable_def<R>
does not define representative
,
it assumed to be R
.
T::forwarded_type
forwarded_type
must be implicitly convertible from P
,
and must be copy-constructible. And its copy-constructor should be fast.
( forwarded_type
is usually P
or const P&
)
forwarded_type
is used intead of P
as the storage type in some
situations ( for example, the objects created by fmt
and join
).
T::is_overridable
A type alias to either std::true_type
or std::false_type
.
It influences the behavior of make_printer
.
Assumed to be std::false_type
if not defined.
T::format_specifiers
A type alias to tag<F...>
, where all types in F...
satisfy
FormatSpecifier.
It affects the return type of fmt
.
Assumed to be tag<>
if not defined.
Member static function templates
Given
-
T
, a PrintableDef type. -
CharT
, a character type -
fpack
, a value of typefacets_pack</*... */>
-
pre
, a value of typepremeasurements</*... */>
-
dst
, an non-const lvalue reference of typedestination<CharT>
-
v
, a value of typeT::forwarded_type
orvalue_and_format<T, F...>
, whereF...
is such thatT::format_specifiers
is an alias totag<F...>
.
At least one of the function templates below must be defined:
T::print(dst, fpack, v);
Return Type |
void |
Effect |
Prints |
auto c = T::make_printer(tag<CharT>{}, pre, fpack, v);
The make_printer
function has two purposes:
-
to return a callable object
c
such thatc(dst)
printsv
intodst
taking into account the facets infpack
-
To measure the size and/or width (or none, depeding on the type
pre
) of the content thatc
prints when invoked.
pre
acts as an output variable:
If pre->width_demanded
is true
, then the width of content
that c
prints shall be added to the accumulated_size of pre
.
If pre->size_demanded
is true
, then the size of content that
c
prints ( or a value greater than that ) shall be added into the
accumulated_size of pre
.
c(dst)
must not call dst.recycle()
if the value of dst.space()
immediately before calling c(dst)
is greater than or equal to such calculated size.
6.4. Type alias template representative_of_printable
namespace strf {
template <typename T>
using representative_of_printable = /* see bellow */ ;
} // namespace strf
Given PDef
, the type printable_def_of<T>
, representative_of_printable<T>
is an alias to
PDef::representative
, assuming such
type member alias is defined.
Otherwise, it is R
, if PDef
is printable_def<R>
.
6.5. Variable template is_printable_and_overridable
namespace strf {
template <typename T>
using is_printable_and_overridable = … /*see below*/;
template <typename T>
constexpr bool is_printable_and_overridable_v = is_printable_and_overridable<T>::value;
} // namespace strf
is_printable_and_overridable<T>
is an alias to
printable_def_of<T>::is_overridable
if such type is defined, otherwise it is an alias to std::false_type
.
6.6. Type alias template forwarded_printable_type
namespace strf {
template <typename T>
using forwarded_printable_type = typename printable_def_of<T>::forwarded_type;
} // namespace strf
6.7. Template facet category printable_overrider_c
namespace strf {
template <typename R>
struct printable_overrider_c {
static constexpr bool constrainable = true;
constexpr static dont_override<R> get_default() noexcept {
return {};
}
};
} // namespace strf
The template parameter R
shall be the same as the representative_of_printable<P>
,
where P
the printable type to be overriden.
6.8. Type alias printable_overrider_c_of
namespace strf {
template <typename Printable>
using printable_overrider_c_of =
printable_overrider_c< representative_of_printable<Printable> >;
}
6.9. Struct template dont_override
dont_override<_T_>
is the default facet of printable_overrider_c<_T>
category.
namespace strf {
template <typename T>
struct dont_override {
using category = printable_overrider_c<R>;
};
} // namespace strf
6.10. Function template make_printer
namespace strf {
template <typename CharT, typename Pre, typename FPack, typename Arg>
constexpr /*...*/ make_printer(Pre* pre, const FPack& facets, const Arg& arg);
} // namespace strf
If printable_def_of<Arg>::is_overridable::value
is true
,
make_printer
returns
get_facet
< printable_overrider_c<representative_of_printable<Arg>>
, representative_of_printable<Arg> >
(facets)
.make_printer(tag<CharT>{}, pre, facets, arg);
Otherwise, it returns
{printable_def _of}<Arg>::make_printer(tag<CharT>{}, pre, facets, arg)
6.11. Class template premeasurements
namespace strf {
enum class width_presence: bool { no = false, yes = true };
enum class size_presence : bool { no = false, yes = true };
template <size_presence SizePresence, width_presence WidthPresence>
class premeasurements
: public size_accumulator<static_cast<bool>(SizePresence)>
, public width_accumulator<static_cast<bool>(WidthPresence)>
{
public:
static constexpr bool size_demanded = static_cast<bool>(SizePresence);
static constexpr bool width_demanded = static_cast<bool>(WidthPresence);
static constexpr bool no_demands = ! size_demanded && ! width_demanded;
static constexpr bool something_demanded = size_demanded || width_demanded;
static constexpr bool size_and_width_demanded = size_demanded && width_demanded;
constexpr premeasurements() noexcept = default;
constexpr explicit premeasurements(width_t initial_width) noexcept;
~premeasurements() = default;
};
} // namespace strf
Constructors
constexpr premeasurements() noexcept;
Effect |
Default-construct each of the base classes. |
constexpr explicit premeasurements(width_t width_limit) noexcept;
- Compile-time requirement
-
WidthPresence
iswidth_presence::yes
, otherwise this constructor does not participate in overload resolution. - Effect
-
Initializes
width_accumulator
base withwidth_limit
.
6.12. Class template size_accumulator
namespace strf {
template <bool Active>
class size_accumulator
{
public:
explicit constexpr size_accumulator() noexcept;
explicit constexpr size_accumulator(std::integral auto initial_size) noexcept;
constexpr void add_size(std::integral auto s) noexcept;
constexpr std::ptrdiff_t accumulated_ssize() const noexcept;
constexpr std::size_t accumulated_usize() const noexcept;
};
} // namespace strf
Member functions
explicit constexpr size_accumulator() noexcept;
- Postcondition
-
accumulated_ssize() == 0
explicit constexpr size_accumulator(std::integral auto initial_size) noexcept;
- Compile-time requirement
-
Active
istrue
, otherwise this constructor does not participate in overload resolution. - Postcondition
-
accumulated_ssize() == initial_size >= 0 ? initial_size : 0
constexpr void add_size(std::integral auto s) noexcept;
- Effects
-
- When
Active
isfalse
-
None
- When
Active
istrue
-
The internally stored size value ( that is returned by
accumulated_ssize()
) is incremented by the value(s >= 0 ? s : 0)
.
- When
constexpr std::size_t accumulated_usize() const noexcept;
- When
Active
isfalse
-
0
- When
Active
istrue
-
The internally stored size value.
constexpr std::ptrdiff_t accumulated_ssize() const noexcept;
- Return value
-
static_cast<std::ptrdiff_t>(accumulated_usize())
6.13. Class template width_accumulator
namespace strf {
template <bool Active>
class width_accumulator
{
public:
constexpr width_accumulator() noexcept;
constexpr explicit width_accumulator(width_t width_limit) noexcept;
constexpr void add_width(width_t) noexcept;
constexpr void checked_add_width(width_t) noexcept;
constexpr width_t accumlated_width() const noexcept;
constexpr width_t remaining_width() const noexcept;
constexpr bool has_remaining_width() const noexcept;
constexpr bool remaining_width_greater_than(width_t w) const noexcept
constexpr saturate_width(width_t w) noexcept;
private:
width_t limit_ = width_max; // exposition-only
width_t width_ = 0; // exposition-only
}
} // namespace strf
Member functions
constexpr explicit width_accumulator(width_t width_limit) noexcept;
- Compile-time requiment
-
Active
istrue
, otherwise this constructor does not participate in overload resolution. - Postcondition
-
remaining_width() == width_limit > 0 ? width_limit : 0
constexpr width_accumulator() noexcept;
- Postcondition
-
remaining_width() == (Active ? width_max : 0)
constexpr void checked_add_width(width_t w) noexcept;
- Effect
-
None if
Active
isfalse
, otherwise doesif (w > 0 && width_ < limit_) { width_ = ( w >= limit_ - width_ ? limit_ : width_ + w ); }
constexpr void add_width(width_t w) noexcept;
- Effect
-
None if
Active
isfalse
, otherwise doeswidth_ += w
constexpr width_t accumulated_width() noexcept;
- Return value
-
Active ? (width_ ⇐ limit_ ? width_ : limit_) : 0
constexpr width_t remaining_width() noexcept;
- Return value
-
Active ? (width_ < limit_ ? limit_ - width_ : 0) : 0
constexpr bool has_remaining_width() noexcept;
- Return value
-
Active && width_ < limit_
constexpr bool remaining_width_greater_than(strf::width_t w) const noexcept
- Return value
-
Active && width_ + w < limit_
constexpr saturate_width(width_t w) noexcept;
Effect: None if Active
is false
, otherwise do width_ = limit_
Postcondition:: remaining_width() == 0
6.14. Function template measure
template < typename CharT
, size_presence SizePresence
, width_presence WidthPresence
, typename... FPE
, typename... Args >
void measure
( premeasurements<SizePresence, WidthPresence>* pre
, const facets_pack<FPE...>& facets
, const Args&... args );
Calculates the size and/or width of the result of printing the arguments args...
- Compile-time requirements
-
-
All types in
Args...
are Printable -
All types in
FPE...
are FacetsPackElement ( since this is a requirement offacets_pack
).
-
- Effects
-
-
When
SizePresence
issize_presence::yes
, do the equivalent to the following fold expression:(..., make_printer<CharT>(pre, facets, args) );
-
When
WidthPresence
iswidth_presence::yes
butSizePresence
issize_presence::no
, domake_printer<CharT>(pre, facets, a)
for each argumenta
inargs
pre->has_remaining_width()
returnsfalse
. This implies that not necessarily all arguments inargs...
are used. -
Does nothing if
SizePresence
issize_presence::no
andWidthPresence
iswidth_presence::no
-
7. facets_pack
7.1. Class template facets_pack
template <typename ... FPE>
class facets_pack;
- Compile-time requirements
-
All types in
FPE...
satisfy FacetsPackElement.
Member functions
Constructors
constexpr facets_pack(const facets_pack& other) = default;
- Effects
-
Initializes each element in this object with the corresponding element in
other
- Compile-time requirements
-
(std::is_copy_constructible_v<FPE> && ...)
istrue
, otherwise this constructor does not participate in overload resolution.
constexpr facets_pack(facets_pack&& other) = default;
- Effects
-
Initializes each element from the rvalue reference of the corresponding element in
other
- Compile-time requirements
-
(std::is_move_constructible_v<FPE> && ...)
istrue
, otherwise this constructor does not participate in overload resolution.
constexpr facets_pack() = default;
- Effects
-
Default-initializes each element
- Compile-time requirements
-
(std::is_default_constructible_v<FPE> && ...)
istrue
, otherwise this constructor does not participate in overload resolution.
template <typename... U>
constexpr explicit facets_pack(U&&... u)
- Effects
-
Initializes each element with the corresponding value in
std::forward<U>(u)...
. - Compile-time requirements
-
This constructor does not participate in overload resolution, unless the following conditions are met
-
sizeof...(U) != 0
istrue
-
sizeof...(U) == sizeof...(FPE)
istrue
-
( std::is_constructible_v<FPE, U> && ... )
istrue
-
if
sizeof...(U) == 1
istrue
, thenstd::remove_cvref_t<U…>
is notfacets_pack<FPE….>
.
-
Assignment operators (deleted)
facets_pack& operator=(const facets_pack&) = delete
facets_pack& operator=(facets_pack&&) = delete;
Assignments are deleted because it is unclear what would be the correct
behavior when there is a reference type in FPE...
.
7.2. Function template pack
template <typename ... T>
constexpr /* see below */ pack(const T& ... args)
- Return type
-
facets_pack<std::remove_cvref_t<T>>...>
- Return value
-
A
facets_pack
object initialized withstd::forward<T>(args)...
7.3. Function template get_facet
template <typename FCat, typename Tag, typename ... T>
constexpr decltype(auto) get_facet(const facets_pack<T...>& fp);
- Effects
-
If
has_facet<FCat, Tag>(fp)
returnstrue
then returnsdo_get_facet<FCat, Tag>(fp)
, otherwise returnFCat::get_default()
. - Compile-time requirements
-
FCat
is a FacetCategory type.
7.4. Hypothetical function template has_facet
This function template does not exist in this library.
It is only documented to help to explain the
get_facet function template.
|
template <typename FCat, typename Tag, typename FPE>
constexpr bool has_facet(const FPE& fpe)
- Effects
-
-
If
FPE
is an instance offacets_pack
, then returns wheter there is any elementeelm
infpe
such thathas_facet<FCat, Tag>(elm)
istrue
. -
If
FPE
is an instance ofconstrained_fpe<FPE, Filter>
, then returnsFilter<Tag>::value && has_facet<FCat, Tag>(fpe.get())
. -
If
FPE
is a Facet type, returnsstd::is_same_v<FCat, facet_category<FPE>>
-
- Compile-time requirements
-
-
FCat
is a FacetCategory type. -
FPE
satisfies FacetsPackElement.
-
7.5. Hypothetical function template do_get_facet
This function template is not part of the library.
It is only documented to help to explain the
get_facet function template
|
template <typename FCat, typename Tag, typename FPE>
constexpr decltype(auto) do_get_facet(const FPE& fpe);
- Compile-time requirements
-
-
FCat
satisfies FacetCategory. -
FPE
satisfies FacetsPackElement. -
has_facet<FCat, Tag>(fpe)
istrue
.
-
7.6. Class template constrained_fpe
template <template <class> class Filter, typename FPE>
class constrained_fpe;
The class template constrained_fpe
is designed to be used in
facets_pack
. constrained_fpe<Filter, FPE>
holds a value of FPE
that will only be returned by
get_facet<Category, Tag>
if Filter<Tag>::value
is true
.
- Compile-time requirements
-
-
Filter
is a UnaryTypeTrait. For any typeT
, the expressionFilter<T>::value
must be well-formed and convertible tobool
. -
FPE
satisfies ConstrainableFacetsPackElement.
-
Synopsis
namespace strf {
template <template <class> class Filter, typename FPE>
class constrained_fpe
{
public:
// constructors
constexpr constrained_fpe(const constrained_fpe&) = default;
constexpr constrained_fpe(constrained_fpe&& other) = default;
constexpr constrained_fpe() = default;
template <typename U>
constexpr constrained_fpe(U&&);
// element access
constexpr const FPE& get() const;
private:
FPE element; // exposition only;
};
} // namespace strf
Member functions
Constructors
constexpr constrained_fpe(const constrained_fpe& other);
- Effect
-
Initializes the element of the
constrained_fpe
from the const reference of the element ofother
. - Compile-time requirements
-
std::is_copy_constructible<FPE>::value
istrue
, otherwise this constructor does not participate in overload resolution.
constexpr constrained_fpe(constrained_fpe&& other);
- Effect
-
Initializes the element of the
constrained_fpe
from the rvalue reference of the element ofother
. - Compile-time requirements
-
std::is_move_constructible<FPE>::value
istrue
, otherwise this constructor does not participate in overload resolution.
constexpr constrained_fpe();
- Effect
-
Default-initializes
element
. - Compile-time requirements
-
std::is_default_constructible<FPE>::value
istrue
, otherwise this constructor does not participate in overload resolution.
template <typename U>
constexpr explicit constrained_fpe(U&& arg);
- Effect
-
Initializes element with
std::forward<U>(arg)
. - Compile-time requirements
-
std::is_constructible<FPE, U>::value
istrue
, otherwise this constructor does not participate in overload resolution.
Element access
constexpr const FPE& get() const;
- Effect
-
Return the stored element;
7.7. Function template constrain
template <template <class> class Filter, typename T>
constexpr constrained_fpe<Filter, U> constrain(const T& arg);
constrain
is just a syntatic sugar to create a constrained_fpe
object.
- Return type
-
constrained_fpe<Filter, U>
, whereU
isstd::remove_cv_t<std::remove_reference_t<T>>
. - Return value
-
constrained_fpe<Filter, U>{ std::forward<T>(arg) }
- Compile-time requirements
-
T
is such thatU
satisfies FacetsPackElement.
7.8. Type requirement FacetsPackElement
A given type F
satisfies FacetsPackElement if, and only if, one of the following conditions is true:
-
F
is a Facet type. -
F
is an instance offacets_pack
. -
F
is an instance ofconstrained_fpe
.
7.9. Type requirement ConstrainableFacetsPackElement
A given a type F
is a ConstrainableFacetsPackElement if, and only if,
one of the following conditions is true:
-
F
is a Facet type andfacet_category<F>::constrainable
istrue
. -
F
isfacets_pack<F2...>
and all types inF2...
are ConstrainableFacetsPackElement. -
F
is an instance ofconstrained_fpe
.
7.10. Type requirement Facet
A given a type F
satisfies Facet
if all of the following conditions are met:
-
F
is MoveConstructible -
facet_category<F>
satisfies the FacetCategory requirements.
7.11. Type requirement FacetCagory
A given a type FCat
satisfies FacetCategory
if:
-
FCat
has a static member function namedget_default
that takes no argument and whose return type is eitherF
orconst F&
, whereF
is a type that satisfies the requirements associated toFCat
. -
FCat
has a member namedconstrainable
that is a static constexpr value convertible tobool
. ( If this value isfalse
then the facets associatedFCat
can not be constrained ).
7.12. Class template facet_traits
This class template provides the Facet informations.
If you create a new facet, you can either define such informations as
members of the facet, or specialize facet_traits
.
template <typename F>
class facet_traits
{
public:
using category = /* Facet::category or void */;
};
Public members
typename /* */ category;
Same as Facet::category
if such member exist and is a type,
otherwise it is an alias to void
.
Specialization
template <typename F>
class facet_traits<const F>
{
public:
using category = typename facet_traits<F>::category;
};
7.13. Type alias facet_category
facet_category
is just a syntatic sugar:
template <typename Facet>
using facet_category = facet_traits<Facet>::typename category;
8. Printing syntax
The printing_syntax
class template implement the
functions availabe in the basic usage syntax of the library:
The target is an expression that is or creates a printing_syntax
object.
The header <strf.hpp>
provides the following target expressions:
namespace strf {
/* see below */ to(char8_t* begin, char8_t* end);
/* see below */ to(char* begin, char* end);
/* see below */ to(char16_t* begin, char16_t* end);
/* see below */ to(char32_t* begin, char32_t* end);
/* see below */ to(wchar_t* begin, wchar_t* end);
} // namespace strf
- Return type
-
printing_syntax<DestCreator>
, whereDestCreator
is an implementation-defined type that satifies DestinationCreator. - Return value
-
An object whose
DestCreator
object_dest_creator
is such that_dest_creator.create()
returnsbasic_cstr_destination<char_type>{begin, end}
namespace strf {
/* see below */ to(char8_t* dest, std::size_t count);
/* see below */ to(char* dest, std::size_t count);
/* see below */ to(char16_t* dest, std::size_t count);
/* see below */ to(char32_t* dest, std::size_t count);
/* see below */ to(wchar_t* dest, std::size_t count);
} // namespace strf
Return type and value |
Same as of |
namespace strf {
template<std::size_t N> /* see below */ to(char8_t (&dest)[N]);
template<std::size_t N> /* see below */ to(char (&dest)[N]);
template<std::size_t N> /* see below */ to(char16_t (&dest)[N]);
template<std::size_t N> /* see below */ to(char32_t (&dest)[N]);
template<std::size_t N> /* see below */ to(wchar_t (&dest)[N]);
} // namespace strf
Return type and value |
Same as of |
namespace strf {
template <typename CharT>
/* see below */ to_range(CharT* begin, CharT* end);
} // namespace strf
- Return type
-
printing_syntax<DestCreator>
, whereDestCreator
is an implementation-defined type that satifies DestinationCreator. - Return value
-
An object whose
DestCreator
object_dest_creator
is such that_dest_creator.create()
returnsbasic_char_array_writer<char_type>{begin, end}
namespace strf {
template <typename CharT, std::size_t N>
/* see below */ to_range(CharT (&dest)[N]);
} // namespace strf
Return type and value |
Same as of |
namespace strf {
template <typename CharT>
/* see below */ to_range(CharT* dest, std::size_t count);
} // namespace strf
Return type and value |
Same as of |
8.1. Class template printing_syntax
namespace strf {
template < typename DestCreator
, typename ReservePolicy = no_reserve
, typename... FPE>
class printing_syntax;
}
- Compile-time requirements
-
-
DestCreator
satisfy either DestinationCreator or SizedDestinationCreator. -
ReservePolicy
isno_reserve
,reserve_given_space
orreserve_calc
-
All types in
FPE...
satisfy FacetsPackElement.
-
Synopsis
namespace strf {
struct no_reserve {};
struct reserve_calc {};
struct reserve_given_space {
constexpr explicit reserve_given_space(std::size_t s) : space(s) {}
std::size_t space;
};
template < typename DestCreator
, typename ReservePolicy = no_reserve
, typename... FPE>
class printing_syntax
{
public:
// constructors
constexpr printing_syntax();
constexpr explicit printing_syntax(const DestCreator& dest_creator);
constexpr explicit printing_syntax(DestCreator&& dest_creator);
template <typename... U>
constexpr printing_syntax
( const DestCreator& dest_creator, ReservePolicy poli, U&&... fpes );
template <typename... U>
constexpr printing_syntax
( DestCreator&& dest_creator, ReservePolicy poli, U&&... fpes );
// printing
using return_type = /* ... */;
return_type operator()(Args&& ... args) const;
return_type line(Args&&... args) const;
return_type tr(Args&&... args) const;
return_type trline(Args&&... args) const;
// change reserve policy
constexpr /* ... */ reserve(std::integral auto capacity) /* ... */;
constexpr /* ... */ reserve_calc() /* ... */;
constexpr /* ... */ no_reserve() /* ... */;
// add facets
template <typename... U>
constexpr /* ... */ with(U&&...) const &;
constexpr const printing_syntax& with() const &;
constexpr const printing_syntax& with() const && ;
constexpr printing_syntax& with() &;
constexpr printing_syntax&& with() &&;
};
Member types
return_type
decltype(std::declval<const typename DestCreator::destination_type&>().finish()
,
if such type is well-formed, otherwise void
char_type
A type alias to DestCreator::char_type
Constructors
constexpr printing_syntax() = default;
Only participates in overload resolution if DestCreator
and all types
in FPE...
are default-constructible and ReservePolicy
is not
reserve_given_space
.
constexpr printing_syntax(const DestCreator& dest_creator)
- Effects
-
Initializes the inther
DestCreator
object withdest_creator
- Compile time requirements
-
Only participates in overload resolution if
DestCreator
is copy-constructible and all types inFPE...
are default-constructible andReservePolicy
is notreserve_given_space
.
constexpr printing_syntax(DestCreator&& dest_creator)
- Effects
-
Initializes the inther
DestCreator
object withdest_creator
- Compile time requirements
-
Only participates in overload resolution if
DestCreator
is move-constructible and all types inFPE...
are default-constructible andReservePolicy
is notreserve_given_space
.
constexpr printing_syntax(const DestCreator& dest_creator, ReservePolicy poli, U&&... fpes)
- Effects
-
-
Initializes the internal
DestCreator
object withdest_creator
, -
Initializes the internal
ReservePolicy
object withpoli
, -
Initializes the of the internal
FPE...
object with the correspoding value in(U&&)fpes...
-
- Compile time requirements
-
Only participates in overload resolution if:
-
DestCreator
is copy-constructible -
Each type in
FPE...
is constructible from the corresponding type inU...
-
constexpr printing_syntax(DestCreator&& dest_creator, ReservePolicy poli, U&&... fpes
- Effects
-
-
Initializes the internal
DestCreator
object withdest_creator
, -
Initializes the internal
ReservePolicy
object withpoli
, -
Initializes the of the internal
FPE...
object with the correspoding value in(U&&)fpes...
-
- Compile time requirements
-
Only participates in overload resolution if:
-
DestCreator
is move-constructible -
Each type in
FPE...
is constructible from the corresponding type inU...
-
Member functions for printing
return_type operator()(Args&&... args) const;
Effect
Executes the following steps:
-
Distinguish the leading arguments in
args...
that specify facets, from the remaining ones that specify values to be printed. Let the first sub-list be here calledfargs...
and the secondpargs...
-
Create a facets_pack object from the the internal
FPE...
objects andfargs...
. Let it be here calledfpack
, an let its type beFPack
( which isfacets_pack<FPE..., std::remove_cvref_t<decltype(fargs)>...>
When ReservePolicy is strf::reserve_given_space |
---|
|
When ReservePolicy is strf::reserve_calc |
---|
|
When ReservePolicy is strf::no_reserve |
---|
|
return_type line(Args&& ... args) const;
- Effect
-
Equivalent to
return operator() ((Args&&)args..., (char_type)'\n');
return_type tr(Args&&... args) const;
- Effect
-
Equivalent to
return operator() ( (Facets&&)facets..., strf::tr( (PArgs&&)pargs... ) );
where:
-
Facets...
are the leading types inArgs...
are FacetsPackElements. -
PArgs...
are the remaining types inArgs...
, and they are expected to be Printable. -
facets...
are the arguments inargs...
that correspond toFacets...
-
pargs...
are the remaining arguments inargs...
.
-
return_type trline(Args&& ... args) const;
- Effect
-
Equivalent to
return operator() ( (Args&&)args..., (char_type)'\n' );
Member functions to change Reserve Policy
constexpr /* ... */ reserve(std::integral auto space) /* ... */;
When ReservePolicy is strf::reserve_given_space |
---|
Changes the space stored in the internal |
Returns a new |
When ReservePolicy is not strf::reserve_calc |
---|
Returns a new |
constexpr /* ... */ reserve_calc() /* ... */;
When ReservePolicy is strf::reserve_calc |
---|
Just returns |
When ReservePolicy is not strf::reserve_calc |
---|
Returns a new |
constexpr /* ... */ no_reserve() /* ... */;
When ReservePolicy is strf::no_reserve |
---|
Just returns |
When ReservePolicy is not strf::no_reserve |
---|
Returns a new |
Member functions to add facet values
template <typename... U>
constexpr /* ... */ with(U&&... fpes) const &;
template <typename... U>
constexpr /* ... */ with(U&&... fpes) &&;
- Compile-time requirements
-
-
sizeof...(U)
is not zero, otherwise this overload does not participate in overload resolution. -
All types in
std::remove_cvref_t<U>...
are FacetsPackElement -
( In the
const &&
overload )DestCreator
and all types inFPE...
are copy-constructible. -
( In the
&&
overload )DestCreator
and all types inFPE...
are move-constructible.
-
- Return type
-
printing_syntax<DestCreator, ReservePolicy, FPE..., std::remove_cvref_t<U>...>
- Effect
-
Returns a new
printing_syntax
whose internalDestCreator
andFPE...
objects are copy-constructed or move-constructed ( depedending on the overload used ) from the internalDestCreator
andFPE...
objects of this object. and each the internalstd::remove_cvref_t<U>...
object is initialized with the correspoding value in(U&&)fpes...
.
constexpr const printing_syntax& with() const &;
constexpr const printing_syntax& with() const && ;
constexpr printing_syntax& with() &;
constexpr printing_syntax&& with() &&;
Just returns *this
or std::move(*this)
8.2. Type requirement DestinationCreator
Given
-
char_type
, a character type -
X
, an DestinationCreator type forchar_type
-
x
, an expression of typeX
orconst X
The following must hold:
-
X
is CopyConstructible -
X
has a member type aliasX::char_type
defined aschar_type
-
X
has theX::destination_type
that is a type alias to a concrete type that is derives fromdestination<X::char_type>
And the following expression must be well-formed:
typename X::destination_type{x.create()}
8.3. Type requirement SizedDestinationCreator
Given
-
char_type
, a character type -
size
, a value of thestd::size_t
-
X
, an SizedDestinationCreator type forchar_type
-
x
, an expression of typeX
orconst X
The following must hold:
-
X
is CopyConstructible -
X
has a member type aliasT::char_type
defined aschar_type
-
X
has theX::sized_destination_type
that is a type alias to a concrete type that derives fromdestination<X::char_type>
And the following expression must be well-formed:
typename X::sized_destination_type{x.create(size)}
9. Miscellaneous
9.1. The lettercase
facet
namespace strf {
enum class lettercase { lower = /*…*/, mixed = /*…*/, upper = /*…*/ };
constexpr lettercase lowercase = lettercase::lower;
constexpr lettercase mixedcase = lettercase::mixed;
constexpr lettercase uppercase = lettercase::upper;
struct lettercase_c {
static constexpr bool constrainable = true;
constexpr static lettercase get_default() noexcept
{
return lettercase::lower;
}
};
template <>
struct facet_traits<lettercase> {
using category = lettercase_c;
};
} // namespace strf
9.2. Type traits
The table below list class templates that satisfy
UnaryTypeTrait.
They are created to be used in the constrain
function template to filter
printable types.
|
matches |
|
matches |
|
matches strings. |
to-do
9.3. Class template tag
namespace strf {
template <typename... >
struct tag
{
explicit tag() = default;
};
template <typename T>
struct tag<T>
{
explicit constexpr tag() noexcept { }
using type = T;
};
} // namespace strf