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> and std::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 the transcode or sani 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>, where string_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

1.3. bool

Type

bool

Representative type

bool

Overridable

Yes

FormatSpecifier types
Influenced by facet categories

1.4. const void*

Types

const void*

Representative type

const void*

Overridable

Yes

FormatSpecifier types
Influenced by facet categories

1.5. Integers

Types

short, int, long int, long long int, unsigned short, unsigned int, unsigned long int and unsigned 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 or unsigned long long int )

Overridable

No

FormatSpecifier types
Influenced by facet categories

1.6. Floating Points

Types

float, double

Representative type

The same as the input type ( float or double )

Overridable

Yes

FormatSpecifier types
Influenced by facet categories

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
Examples
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:

Example 1
std::vector<int> vec = { 11, 22, 33 };
auto str1 = strf::to_string("[", +strf::fmt_separated_range(vec, " ;") > 4, "]");
assert(str1 == "[ +11 ; +22 ; +33]");
Example 2
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' ');
}
Example
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

tr_error_notifier_c

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 or std::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>, where CharT 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 '}' or end of string

a comment

a digit

the next '}' or end of string

a positional argument reference

another '{'

the second '{'

an escaped '{'

any other character

the next '}' or end of string

a non positional argument reference

Examples:

Comments
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");
Positional arguments
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.");
Non positional arguments
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.");
Escapes
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 the tr_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 type X

  • CharsetT, a Charset type.

  • charset, a value of type CharsetT

  • str, a value of type const CharsetT::code_unit* pointing to string encoded according to charset

  • str_len, a std::ptrdiff_t value equal to the length of the string str

  • err_pos, a std::ptrdiff_t value less than or equal to str_len

The following must host:

  • X is CopyConstructible.

  • X::category is a type alias to tr_error_notifier_c

  • The following expression is supported:

x.handle(str, str_len, charset, err_pos)
Semantics

str is a tr-string that contains an error. err_pos is the position of the '{' character in str that starts the invalid argument reference.

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);
Example 1
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 }");
Example 2
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

left(arg, width)

fmt(arg) < width

right(arg, width)

fmt(arg) > width

center(arg, width)

fmt(arg) ^ width

left(arg, width, ch)

fmt(arg).fill(ch) < width

right(arg, width, ch)

fmt(arg).fill(ch) > width

center(arg, width, ch)

fmt(arg).fill(ch) ^ width

pad0(arg, count)

fmt(arg).pad0(count)

punct(arg)

fmt(arg).punct()

hex(arg)

fmt(arg).hex()

oct(arg)

fmt(arg).dec()

dec(arg)

fmt(arg).oct()

bin(arg)

fmt(arg).bin()

sci(arg)

fmt(arg).sic()

fixed(arg)

fmt(arg).fixed()

gen(arg)

fmt(arg).gen()

sci(arg, precision)

fmt(arg).sic().p(precision)

fixed(arg, precision)

fmt(arg).fixed().p(precision)

gen(arg, precision)

fmt(arg).gen().p(precision)

multi(arg, count)

fmt(arg).multi(count)

transcode(arg, charset)

fmt(arg).transcode(charset)

transcode(arg)

fmt(arg).transcode()

unsafe_transcode(arg, charset)

fmt(arg).unsafe_transcode(charset)

unsafe_transcode(arg)

fmt(arg).unsafe_transcode()

sani(arg, charset)

fmt(arg).sani(charset)

sani(arg)

fmt(arg).sani()

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 if T is value_and_format<ValueType, Fmts...>. In this case, note that Fmt is in Fmts... and T derives from Fmt::template fn<T>.

  • Fmt::template fn<T> is default constructible, assuming it is well-formed.

  • Fmt::template fn<T> can be constructed from const 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

operator<(width_t width)

Aligns to the left ( Or to the right on right-to-left (RTL) scripts, like Arabic )

operator>(width_t width)

Aligns to the right ( Or to the left on RTL scripts )

operator^(width_t width)

Center alignment

fill(char32_t ch)

Sets the fill character.

set_alignment_format(alignment_format)

Set all alignment formatting options simultaneously.

set_alignment_format(default_alignment_format)

Set all alignment formatting options to default.

clear_alignment_format()

Set all alignment formatting options to default.

And the following observers:

Observers Return type

width()

width_t

get_alignment_format()

default_text_alignment or text_alignment, depending on whether any alignment format function has been previously invoked.

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

bin()

Uses the binary base.

oct()

Uses the octal base.

dec()

Uses the decimal base.

hex()

Uses the hexadecimal base.

operator*()

Equivalent to the '#' format flag in printf. Only applicable in non-decimal bases.

operator+()

Equivalent to the '+' format flag in printf. Only applicable in decimal base.

operator~()

Equivalent to fill_sign()

fill_sign()

Similar to the ' ' format flag in printf: prints an extra fill character ( specified by some of the alignment format function ) before non-negative numbers. Only applicable in decimal base.

punct()

Applies the numeric punctuation according to the numpunct_c facet

operator!()

Equivalent to punct()

pad0(int w)

Inserts zeros after the sign or base indication and before the digits such that at least w characters are printed ( not counting the fill characters caused by alignment formatting, but still counting the extra fill character caused by fill_sign() ).

p(int precision)

Inserts zeros after the sign or base indication and before the digits such that at least precision digits are printed

set_int_format(int_format)

Set all integers formatting options simultaneously.

set_int_format(default_int_format)

Reset all integers formatting options to default.

And the following observer:

Observer Return type

get_int_format()

int_format, default_int_format or an implementation-defined IntFormat type.

Type requirements IntFormat

Given:

  • F, a InttFormat type

  • f, a value of type F

The following must hold:

  • F is copy-constructible

  • F is convertible to int_format

  • F has public member variables below:

Member Type Semantics / effect

f.base

int

Numeric base ( must be euqal to 2, 8, 10 or 16 )

f.precision

int

See p format function.

f.pad0wdith

int

See pad0 format function.

f.sign

showsign

See enumeration showsign

f.showbase

bool

Equivalent to the '#' format flag in printf

f.punctuate

bool

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

operator*()

Equivalent to the '#' format flag in printf

operator+()

Equivalent to the '+' format flag in printf

fill_sign()

Similar to the ' ' format flag in printf: prints an extra fill character ( from the alignment formatting ) before non-negative numbers.

operator~()

Equivalent to fill_sign()

punct()

Applies the numeric punctuation according to the numpunct_c facet

operator!()

Equivalent to punct()

pad0(int w)

Similar to the '0' format flag in printf:

For NaN and infinity, causes the the width ( from alignment formatting ) to be at least equal to w.

For valid numbers, prints zeros after the sign and the base indication and before the digits such that at least w characters are printed ( not counting the fill characters caused by alignment formatting, but still counting the extra fill character caused by fill_sign() ).

p(int precision)

Sets the precision. Effect varies according to the notation ( see below ).

set_float_notation(float_notation)

Sets the float notation ( see below ).

hex()

Equivalent to set_float_notation(float_notation::hex).

fixed()

Equivalent to set_float_notation(float_notation::fixed).

sci()

Equivalent to set_float_notation(float_notation::scientific).

gen()

Equivalent to set_float_notation(float_notation::general).

set_float_format(float_format)

Set all floating-point formatting options simultaneously.

set_float_format(default_float_format)

Reset all floating-point formatting options to default.

And the following observers:

Observer Return type

get_float_format()

float_format, {default_float_format} or an implementation-defined type that sastisfies FloatFormat requirements.

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 in printf ( 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 type F

The following must hold:

  • F is copy-constructible

  • F is convertible to float_format

  • F has public member variables below:

Member Type Semantics / effect

f.precision

int

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 notation.

f.pad0wdith

int

Same as of format function pad0

f.notation

float_notation

See enumeration float_notation

f.sign

showsign

See enumeration showsign

f.showpoint

bool

Equivalent to the '#' format flag in printf

f.punctuate

bool

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

multi(std::integral auto count)

Causes the content to be printed count consecutives times

And the following observers:

Observer Return type Return value

count()

std::size_t

scount()

std::ptrdiff_t

(std::ptrdiff_t) count()

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 than limit.

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.

Example
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, if std::remove_cvref_t<T> is an instance of value_and_format

  • fmt_type<T>{ fmt_value_type<T>{ (T&&)value } }, otherwise

Return type
  • T&&, if std::remove_cvref<T> is an instance of value_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:

2.11. Class template value_and_format

namespace strf {

template <typename PrintableDef, class... Fmts>
class value_and_format;

} // namespace strf
Compile-time requirements

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_ with v

  • 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_ with f.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_ with static_cast<value_type&&>(f.value())

  • Initializes each public base class subobjects b with std::move(bf), where bf is the base class subobjects in f that corresponds to b

template <typename OtherPrintableDef>
constexpr value_and_format
    ( const value_type& v
    , const value_and_format<OtherPrintableDef, Fmts...>& f );
Effects
  • Initializes value_ with v

  • 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_ with v

  • Initializes each public base class subobjects b with std::move(bf), where bf is the base class subobjects in f that corresponds to b

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 in Fmts...

Effects
  • Initializes value_ with v

  • For each type in F..., initializes the corresponding public base class subobjects with the corresponging value in std::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 in Fmts...

  • sizeof...(OtherFmts) == sizeof...(Fmts) is true

  • value_type must be constructible from object.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 of other ( the type first in Fmts…​ corresponds to the first in `OtherFmt…​, the second to the second and so on ).

  • Fmt must be contructible from FmtInitArgs&&...

Effects
  • Initializes value_ with other.value()

  • Initializes the public base class subobject that corresponds to Fmt with std::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 integer constexpr equal to 2, 8, 10 or 16

  • X, a NumericPunctuation type for Base

  • x, a const value of type X

The following must hold:

And following expressions are well-formed and satisfy the following corresponding conditions:

static_cast<numpunct<Base>>(x)

( X is explicitly convertible to numpunct<Base> )

x.grouping()
Return type

digits_grouping

x.distribute(digcount)
Return type

digits_distribution

Return value

x.grouping().distribute(digcount)

x.any_group_separation(digcount)
Return type

bool

Return value

x.grouping().any_separator(digcount)

x.thousands_sep_count(digcount)
Return type

int

Return value

x.grouping().separators_count(digcount)

x.thousands_sep()
Return type

char32_t

x.decimal_point()
Return type

char32_t

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
  • decimal_point() == U'.'

  • thousands_separator() == U','

  • grouping().empty()

constexpr numpunct(digits_grouping grpng) noexcept;
Postconditions
  • decimal_point() == U'.'

  • thousands_separator() == U','

  • grouping() == grpng

template <typename... IntArgs>
constexpr numpunct(int grp0, IntArgs... grps) noexcept;
Preconditions

Same as of the constructor of digits_grouping ( see here ).

Postconditions
  • decimal_point() == U'.'

  • thousands_sep() == U','

  • grouping() == digits_grouping{grp0, grps...};

int thousands_sep_count(int digcount) const;
Return value

grouping().separators_count(digcount))

constexpr digits_distribution distribute(unsiged digcount) const noexcept;
Return value

grouping().distribute(digcount))

bool any_group_separation(int digcount) const;
Return value

grouping().any_separator(digcount)

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 ch.

Postcondition

decimal_point() == ch

Return value

*this or std::move(*this)

numpunct &  thousands_sep(char32_t ch) &  noexcept;
numpunct && thousands_sep(char32_t ch) && noexcept;
Effect

Changes the thousands separtor to ch.

Postcondition

thousands_sep() == ch

Return value

*this or std::move(*this)

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

true

constexpr bool operator!=(const default_numpunct& other) const noexcept;
Return value

false

constexpr digits_grouping grouping() const
Return value

digits_grouping{}

constexpr digits_distribution distribute(unsiged digcount) const
Return value

digits_distribution{{}, 0, digcount}

constexpr bool any_group_separation(int digcount) const noexcept;
Return value

false

int thousands_sep_count(int digcount) const override;
Return value

0

char32_t thousands_sep() const noexcept;
Return value

U','

char32_t decimal_point() const noexcept;
Return value

U'.'

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

decimal_point() == other.decimal_point()

constexpr bool operator!=(const no_grouping& other) const noexcept;
Return value

decimal_point() != other.decimal_point()

constexpr digits_grouping grouping() const
Return value

digits_grouping{}

constexpr digits_distribution distribute(unsiged digcount) const
Return value

digits_distribution{{}, 0, digcount}

constexpr bool any_group_separation(int digcount) const noexcept;
Return value

false

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

U','

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 ch.

Postcondition

decimal_point() == ch

Return value

*this or std::move(*this)

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

empty() returns true

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 that g == -1 || (0 < g && g <= grp_max) is true.

  • The value g of any argument but the last is such that (0 < g && g <= grp_max) is true.

  • The number of groups ( not counting the last argument if it’s -1 ) is not greater than grps_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 in str that is not the last character, 0 < ch && ch <= grp_max is true

  • If ch is the last character str, then ch == '\xFF' || (0 < ch && ch <= grp_max) is true

  • The number of groups ( not counting the last character if it is '\xFF' ) must not be greater than grps_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

separators_count(digcount) != 0

constexpr int separators_count(int digcount) const noexcept;
Return value

The quantity of thousands separators that would appear in digcount digits.

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 not 0, then dist.low_groups.empty() is false.

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.

Example
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

ended() returns false.

constexpr void advance() noexcept;
Effect

Moves to the next (more significant) group.

Precondition

ended() returns false.

Postconditions

If the return value of is_last() is true, then it becames false and return value of ended() becames true.

constexpr bool is_last() const noexcept;
Return value

true is this is the last group. It is equall to is_final() || shall_repaete_current().

constexpr bool shall_repated_current() const noexcept;
Return value

true is this is the last group and it shall be repeated. It is equall to (is_last() && ! is_final()).

constexpr bool is_final() const noexcept;
Return value

true is this is the last group and it shall not be repeated. It is equall to (is_last() && ! shall_repeat_current()).

constexpr bool ended() const noexcept;

Returns true when there is no group left.

Example
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());
Example
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());
Example
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 to low_groups.highest_groups() follow the highest group.

Example
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 reverse_digits_groups is different than in previous classes.

The value returned by reverse_digits_groups::highest_group() is expected to always be the actual number of digits in the group. This why you prior need to pass the total number of digits to digits_distribution::distribute function: so that it can calculate how many digits actually go in each group.

On the other hand, there is no similar need when you create a digits_grouping_iterator object ( digits_distribution::iterator has no parameter ). So the value returned by digits_grouping_iterator::lowers_group() may actually be larger than the amount of remaining digits to print.

constexpr int highest_group() const noexcept;

Return the actual number of digits in the current group.

Postconditions

The return value is zero when empty() returns true. Otherwise, it is non-zero and not greater than grp_max;

constexpr void pop_high() noexcept;
Effects

None when empty() returns true. Otherwise, moves the return value of highest_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 type X

The following must hold:

  • facet_category<X> is a type alias to transcoding_error_notifier_c

  • X is MoveConstructible

x.get()

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 the destination<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 flag transcode_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 flag transcode_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 or wchar_t

  • DstCharT, one of the types: char, char8_t, char16_t, char32_t or wchar_t

  • X, a Transcoder type from SrcCharT to DstCharT

  • x, an expression of type X or const X

  • src, a value of type const SrcCharT*

  • src_end, a value of type const SrcCharT* pointing immediately after the last character of the string that begins at str

  • dst, a value of type DstCharT*

  • dst_end, a value of type DstCharT* pointing immediately after the last element of the array that begins at dst

  • limit is value of type std::ptrdiff_t

  • err_notifier, is a pointer of type transcoding_error_notifier

  • flags, a value of type transcode_flags

The following must hold:

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 is true

Return type

transcode_result

Effect

Converts the content of src from one encoding to another writing the result to dst.

As this function iterates from src to src_end, if it reads a sequence that is invalid ( non-conformant to the source character encoding ) then it calls err_notifier->invalid_sequence(ch_size, name, seq, count), if err_notifer is not null, where:

  • ch_size is equal to sizeof(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 flag stop_on_invalid_sequence, then the function shall stop and return a value with stop_reason equal to transcode_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 flag transcode_flags::lax_surrogate_policy is set in flags.

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), where dst_charset_name is the name of the destination character encoding, and code is such codepoint.

After that, if flags has the flag stop_on_unsupported_codepoint, then the function shall stop and return a value with stop_reason equal to transcode_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+FFFD

transcode_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 and flags has stop_on_invalid_sequence set, then, even if dst_end is equal to dst the returned stop_reason shall not be transcode_stop_reason::insufficient_space; it should instead be shall be transcode_stop_reason::invalid_sequence.

Return value

A value res such that

  • res.stop_reason is transcode_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 is true

Return type

transcode_result

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 in flags, 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 is true

Return type

transcode_size_result

Return value

A value res such that

  • res.src_ptr is equal to tr_res.src_ptr ( see below )

  • res.stop_reason is equal to tr_res.stop_reason

  • res.ssize equals to tr_res.dst_ptr - dst

, where tr_res is the value that x.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
  • The input has no invalid sequence

  • x.unsafe_transcode_() != nullptr is true

Return type

transcode_size_result

Effect

Exactly the same as x.transcode_size(src, src_end, limit, 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 in flags, 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_func()
Return type

transcode_f<SrcCharT, DstCharT>

Return value

A function pointer such that x.transcode_func() (src, src_end, dst, dst_end, derr_notifier, flags) has the same effect as x.transcode(src, src_end, dst, dst_end, err_notifier, flags).

x.unsafe_transcode_func()
Return type

transcode_f<SrcCharT, DstCharT>

Return value

A function pointer such that x.unsafe_transcode_func() (src, src_end, dst, dst_end, err_notifier, flags) has the same effect as x.unsafe_transcode(src, src_end, dst, dst_end, err_notifier, flags).

x.transcode_size_func()
Return type

transcode_size_f<SrcCharT>

Return value

A function pointer such that x.transcode_size_func() (src, src_end, limit, flags) has the same effect as x.transcode_size(src, src_end, limit, flags).

x.unsafe_transcode_size_func()
Return type

transcode_size_f<SrcCharT>

Return value

A function pointer such that x.unsafe_transcode_size_func() (src, src_end, limit, flags) has the same effect as x.unsafe_transcode_size(src, src_end, limit, flags).


Definition

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 or wchar_t

  • OtherCharT, one of the folowing types : char, char8_t, char16_t or wchar_t

  • X, a Charset type for type CharT

  • x, an expression of type X or const X

  • ptr, a value of type CharT*

  • src, a value of type const CharT*

  • src_end, a value of type const SrcCharT* pointing immediately after the last character of the string that begins at str

  • dest, an lvalue reference of type transcode_dest<CharT>

  • src_size, a value of type std::ptrdiff_t equal to the size of the array pointed by src

  • count, a value of type std::ptrdiff_t

  • max_count, a value of type std::ptrdiff_t

  • ch32, a value of type char32_t

  • ch, a value of type CharT

  • cs_id, value of type charset_id

The following must hold:

X::code_unit

Type alias to CharT

x.id()
Return type

charset_id

Return value

The charset_id that corresponds to this encoding.

x.name()
Return type

const char*

Return value

The name of this encoding. Examples: "UTF-8", "ASCII", "ISO-8859-1", "windows-1252".

x.replacement_char()
Return type

char32_t

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 '?' otherwise.

x.write_replacement_char(dest)
Effect

Writes into dest the codepoint returned by x.replacement_char() encoded in this charset.

Return type

void

x.replacement_char_size()
Return type

int

Return value

The number of characters that x.write_replacement_char(dest) writes into dest.

x.encoded_char_size(ch32)
Return type

int

Return value

The size of the string containing the UTF-32 character ch32, if ch32 is supported in this encoding. Otherwise, x.replacement_char_size().

Postcondition

The return value must be greater than zero.

Note

This function does not check whether ch32 is a legal code point, only if it is possible to write it in this encoding. For example, if this is encoding is UTF-32, this function considers as valid any value for ch32 ( even if is is greater than 0x10FFFF ). Surrogates characters are also not sanitized.

x.validate(ch32)
Return type

int

Return value

The size of the string encoding ch32, if ch32 is a valid codepoint and supported in this encoding. Otherwise, -1.

x.encode_char(ptr, ch32)
Effect

Encodes into ptr the UTF-32 character ch32, without sanitizing. If this encoding is not able to encode ch32, then encodes instead the return of x.replacement_char().

Return type

CharT*

Postcondition

x.encode_char(ptr, ch32) - ptr == x.encoded_char_size(ch32) is true.

Return value

The position just after the last writen character.

Note

This function does not check whether ch32 is a legal code point, only if it is possible to write it in this encoding. For example, if this is encoding is UTF-32, this function considers as valid any value for ch32 ( even if is is greater than 0x10FFFF ). Surrogates characters are also not sanitized.

x.encode_fill(dest, count, ch32)
Effect

Writes count times into dest the UTF-32 character ch32 encoded into this encoding, if it is supported. Otherwise writes x.replacement_char() instead.

Return type

void

Note

encode_fill does not check whether ch32 is a legal code point, only if it is possible to write it in this encoding. For example, if this is encoding is UTF-32, encode_fill considers as valid any value for ch32 ( even if is is greater than 0x10FFFF ). Surrogates characters are also not sanitized.

x.count_codepoints_fast(src, src_end, max_count)
Return type

count_codepoints_result<CharT>

Return value

{c, ptr}, where:

  • c is the number of Unicode code points in src, if such value is less than max_count. Otherwise, c is equal to max_count.

  • ptr is the greatest pointer not greater than src_end such that x.count_codepoints_fast(src, ptr, std::numeric_limits<std::ptrdiff_t>::max()).count is equal to c.

Posconditions
  • c <= max_count is true

  • ptr <= src_end is true

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 max_count.

Return type

count_codepoints_result<CharT>

Return value

{c, ptr}, where:

  • c is equal to std::min(max_count, u32len), where u32len is the length of the UTF-32 string that would be generated by converting src from this encoding to UTF-32.

  • ptr is the greatest pointer not greater than src_end such that x.count_codepoints(src, ptr, std::numeric_limits<std::ptrdiff_t>::max()).count is equal to c.

Posconditions
  • c <= max_count is true

  • ptr <= src_end is true

x.decode_unit(ch)
Effect

Decodes ch from this encoding to UTF-32. If ch is an invalid character that is not a surrogate, returns U'\uFFFD' ( surrogates codepoints as not sanitized ).

Return type

char32_t

x.encode_char_func()
Return type

encode_char_f<CharT>

Return value

A function pointer such that x.encode_char_func() (ch32) has the same effect as x.encode_char(ch32).

x.encode_fill_func()
Return type

encode_fill_f<CharT>

Return value

A function pointer such that x.encode_fill_func() (dest, count, ch32) has the same effect as x.encode_fill(dest, count, ch32).

x.write_replacement_char_func()
Return type

write_replacement_char_f<CharT>

Return value

A function pointer such that x.write_replacement_char_func() (dest) has the same effect as x.write_replacement_char(dest)

x.validate_func()
Return type

validate_f

Return value

A function pointer such that x.validate_func() (ch32) returns the same value as x.validate(ch32)

x.from_u32()
Return type

A Transcoder type T, such that T::src_code_unit is char32_t and T::dst_code_unit is CharT

Return value

A transcoder that converts UTF-32 to this encoding.

x.to_u32()
Return type

A Transcoder type T, such that T::src_code_unit is CharT and T::dst_code_unit is char32_t

Return value

A transcoder that converts this encoding to UTF-32.

x.sanitizer()
Return type

A Transcoder from CharT to CharT

Return value

A transcoder that converts this encoding to this encoding, i.e. a sanitizer of this encoding.

( Optional )
x.find_transcoder_to(tag<OtherCharT>, cs_id)
Return type

dynamic_transcoder<CharT, OtherCharT>

Return value

A transcoder that converts this encoding to the encoding corresponding to cs_id, or an null transcoder.

( Optional )
x.find_transcoder_from(tag<OtherCharT>, cs_id)
Return type

dynamic_transcoder<OtherCharT, CharT>

Return value

A transcoder that converts the encoding corresponding to cs_id to this encoding, or an null transcoder.

x.to_dynamic()
Return type

dynamic_transcoder<CharT>

Return value

A dynamic_charset<CharT> object equivalent to this one.

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
  • transcode_func() == nullptr

  • transcode_size_func() == nullptr

constexpr dynamic_transcoder
    ( const dynamic_transcoder& other) noexcept;

Trivial copy constructor

Postconditions
  • transcode_func() == other.transcode_func()

  • transcode_size_func() == other.transcode_size_func()

template <charset_id Src, charset_id Dest>
constexpr explicit dynamic_transcoder
    ( static_transcoder<Src, Dest> other );
Postconditions
  • transcode_func() == other.transcode_func()

  • transcode_size_func() == other.transcode_size_func()

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_func()(src, src_end, dst, dst_end, err_notifier, flags)

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 unsafe_transcode_func()(src, src_end, dst, dst_end, err_notifier, flags)

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_func()(src, src_end, limit, flags)

transcode_size_result<SrcCharT> unsafe_transcode_size
    ( const SrcCharT* src
    , const SrcCharT* src_end
    , std::ptrdiff_t limit
    , transcode_flags flags ) const;
Effect

Calls unsafe_transcode_size_func()(src, src_end, limit, flags)

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

this->data = other.data

dynamic_charset(const dynamic_charset_data<CharT>& d);
Effect

this->data = d

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

this->data = other.data

bool operator==(const dynamic_charset& other) const noexcept;
Return value

this->data == other.data

bool operator!=(const dynamic_charset& other) const noexcept;
Return value

this->data != other.data

void swap(dynamic_charset& other) noexcept;
Effect

Equivalent to std::swap(this->data, other.data)

dynamic_charset to_dynamic() const noexcept;
Return value

*this

const char* name() const noexcept;
Return value

this->data->name

constexpr charset_id id() const noexcept;
Return value

this->data->id

constexpr char32_t replacement_char() const noexcept;
Return value

this->data->replacement_char

constexpr int replacement_char_size() const noexcept;
Return value

this->data->replacement_char_size

constexpr int validate(char32_t ch) const; // noexcept
Effect

Calls and returns this->data->validate_func(ch).

constexpr int encoded_char_size(char32_t ch) const; // noexcept
Effect

Calls and returns this->data->encoded_char_size_func(ch).

code_unit* encode_char(code_unit* dest, char32_t ch) const; // noexcept
Effect

Calls and returns this->data->encoded_char_func(ch).

void encode_fill
    ( transcode_dest<CharT>& dest, std::ptrdiff_t count, char32_t ch ) const;
Effect

Calls and returns this->data->encode_fill_func(dest, count, ch).

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 this->data->count_codepoints_fast_func(src, src_end, max_count).

std::ptrdiff_t count_codepoints
    ( const code_unit* src, const code_unit* src_end
    , std::ptrdiff_t max_count ) const;
Effect

Calls and returns this->data->count_codepoints_func(src, src_end, max_count).

void write_replacement_char(transcode_dest<CharT>& dest) const;
Effect

Calls this->data->write_replacement_char_func(dest).

char32_t decode_unit(code_unit ch) const;
Effect

Calls and returns this->data->decode_unit_func(ch).

encode_char_f<CharT> encode_char_func() const noexcept;
encode_fill_f<CharT> encode_fill_func() const noexcept;
Return value

this->data->encode_fill_func.

write_replacement_char_f<CharT> write_replacement_char_func() const noexcept;
Return value

this->data->write_replacement_char_func.

dynamic_transcoder<char32_t, CharT> from_u32() const;
Return value

this->data->from_u32.

dynamic_transcoder<CharT, char32_t> to_u32() const;
Return value

this->data->to_u32.

dynamic_transcoder<CharT, CharT> sanitizer() const;
Return value

this->data->sanitizer.

dynamic_transcoder<CharT, char> find_transcoder_to
    ( tag<char>, charset_id id ) const;
Return value

this->data->transcoder_finder_to_char(id) if such function pointer is not null. Otherwise returns dynamic_transcoder<CharT, char>{}

dynamic_transcoder<char, CharT> find_transcoder_from
    ( tag<char>, charset_id id ) const;
Return value

this->data->transcoder_finder_from_char(id) if such function pointer is not null. Otherwise returns dynamic_transcoder<char, CharT>{}

dynamic_transcoder<CharT, char8_t> find_transcoder_to
    ( tag<char8_t>, charset_id id ) const;
Return value

this->data->transcoder_finder_to_char8(id) if such function pointer is not null. Otherwise returns dynamic_transcoder<CharT, char8_t>{}

dynamic_transcoder<char8_t, CharT> find_transcoder_from
    ( tag<char8_t>, charset_id id ) const;
Return value

this->data->transcoder_finder_from_char8(id) if such function pointer is not null. Otherwise returns dynamic_transcoder<char8_t, CharT>{}

dynamic_transcoder<CharT, char16_t> find_transcoder_to
    ( tag<char16_t>, charset_id id ) const;
Return value

this->data->transcoder_finder_to_char16(id) if such function pointer is not null. Otherwise returns dynamic_transcoder<CharT, char16_t>{}

dynamic_transcoder<char16_t, CharT> find_transcoder_from
    ( tag<char16_t>, charset_id id ) const;
Return value

this->data->transcoder_finder_from_char16(id) if such function pointer is not null. Otherwise returns dynamic_transcoder<char16_t, CharT>{}

dynamic_transcoder<CharT, wchar_t> find_transcoder_to
    ( tag<wchar_t>, charset_id id ) const;
Return value

this->data->transcoder_finder_to_wchar(id) if such function pointer is not null. Otherwise returns dynamic_transcoder<CharT, wchar_t>{}

dynamic_transcoder<wchar_t, CharT> find_transcoder_from
    ( tag<wchar_t>, charset_id id ) const;
Return value

this->data->transcoder_finder_from_wchar(id) if such function pointer is not null. Otherwise returns dynamic_transcoder<wchar_t, CharT>{}

4.18. Function template find_transcoder

template <class SrcCharset, class DstCharset>
auto find_transcoder(SrcCharset src, DstCharset dest);
Requirements

SrcCharset and DstCharset are Charset types.

Return type

A type that is Transcoder

Return value
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:

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
Effect

decode_encode has the same effects as calling T::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 value res, such that

  • res.stop_reason ( see transcode_stop_reason)

  • res.stale_src_ptr is not the pointer past the last read element in the input range [src, src_end). Instead, it points res.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 and DstCharset satisfy Charset

  • SrcCharset::code_unit is the same type as SrcCharT

  • DstCharset::code_unit is the same type as DstCharT

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 of static_charset

  • DstCharsetTmpl<DstCharT> is an instance of static_charset

  • SrcCharsetTmpl<SrcCharT>::code_unit is SrcCharT

  • DstCharsetTmpl<DstCharT>::code_unit is DstCharT

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
Return value

A decode_encode_result value res, such that

  • res.ssize is equal to res2.ssize

  • res.stop_reason is equal to res2.stop_reason

  • res.stale_src_ptr is not the pointer past the last read element in the input range [src, src_end). Instead, it points res.u32dist codepoints before that.

, where res2 is the value that would be returned by T::transcode_size(src, src_end, limit, flags), it T 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 and DstCharset satisfy Charset

  • SrcCharset::code_unit is the same type as SrcCharT

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 of static_charset

  • SrcCharset::code_unit is the same type as SrcCharT

  • 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
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 value res, such that

  • res.stop_reason is equal to res2.ssize

  • res.dst_ptr is equal to res2.dst_ptr

  • res.stale_src_ptr is not the pointer past the last read element in the input range [src, src_end). Instead, it points res.u32dist codepoints before that.

, where res2 is the value that would be returned by 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.

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 and DstCharset satisfy Charset

  • SrcCharset::code_unit is the same type as SrcCharT

  • DstCharset::code_unit is the same type as DstCharT

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 of static_charset

  • DstCharsetTmpl<DstCharT> is an instance of static_charset

  • SrcCharsetTmpl<SrcCharT>::code_unit is SrcCharT

  • DstCharsetTmpl<DstCharT>::code_unit is DstCharT

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
Return value

A decode_encode_result value res, such that

  • res.ssize is equal to res2.ssize

  • res.stop_reason is equal to res2.stop_reason

  • res.stale_ptr is not the pointer past the last read element in the input range [src, src_end). Instead, it points res.u32dist codepoints before that.

, where res2 is the value that would be returned by T::unsafe_transcode_size(src, src_end, limit, flags), if T 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 and DstCharset satisfy Charset

  • SrcCharset::code_unit is the same type as SrcCharT

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 of static_charset

  • SrcCharset::code_unit is the same type as SrcCharT

  • DstCharset satisfy Charset

4.25. Function template transcode

There is two main sets of overloads:

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 and DstCharset satisfy Charset

  • SrcCharset::code_unit is the same type as SrcCharT

  • DstCharset::code_unit is the same type as DstCharT

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 of static_charset

  • DstCharsetTmpl<DstCharT> is an instance of static_charset

  • SrcCharsetTmpl<SrcCharT>::code_unit is SrcCharT

  • DstCharsetTmpl<DstCharT>::code_unit is DstCharT

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 to dst

Return value

A transcode_size_result value res, such that:

  • res.stop_reason ( see transcode_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 to dst

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 and DstCharset satisfy Charset

  • SrcCharset::code_unit is the same type as SrcCharT

  • DstCharset::code_unit is the same type as DstCharT

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 of static_charset

  • DstCharsetTmpl<DstCharT> is an instance of static_charset

  • SrcCharsetTmpl<SrcCharT>::code_unit is SrcCharT

  • DstCharsetTmpl<DstCharT>::code_unit is DstCharT

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 and DstCharset satisfy Charset

  • SrcCharset::code_unit is the same type as SrcCharT

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 of static_charset

  • DstCharset is an instance of static_charset

  • SrcCharsetTmpl<SrcCharT>::code_unit is SrcCharT

4.27. Function template unsafe_transcode

There is two main sets of overloads:

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 and DstCharset satisfy Charset

  • SrcCharset::code_unit is the same type as SrcCharT

  • DstCharset::code_unit is the same type as DstCharT

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 of static_charset

  • DstCharsetTmpl<DstCharT> is an instance of static_charset

  • SrcCharsetTmpl<SrcCharT>::code_unit is SrcCharT

  • DstCharsetTmpl<DstCharT>::code_unit is DstCharT

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 and DstCharset satisfy Charset

  • SrcCharset::code_unit is the same type as SrcCharT

  • DstCharset::code_unit is the same type as DstCharT

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 of static_charset

  • DstCharsetTmpl<DstCharT> is an instance of static_charset

  • SrcCharsetTmpl<SrcCharT>::code_unit is SrcCharT

  • DstCharsetTmpl<DstCharT>::code_unit is DstCharT

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 and DstCharset satisfy Charset

  • SrcCharset::code_unit is the same type as SrcCharT

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 of static_charset

  • DstCharset is an instance of static_charset

  • SrcCharsetTmpl<SrcCharT>::code_unit is SrcCharT

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 or wchar_t

  • CharsetT, a Charset type for type CharT

  • charset, a value of type CharsetT

  • ch a value of type CharT

  • limit, a value of type width_t

  • str, a value of type const CharT* pointing to a string encoded according to charset.

  • str_end, a value of type const CharT* pointing immediately after the last character of the string that begin at str

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

width_t

Return value

The width of ch when encoded according to charset.

x.str_width(charset, limit, str, str_end)
Return type

width_t

Return value

The width of the string str if it is less than limit. Otherwise, it can be any value that is greater than or equal to limit.

x.str_width_and_pos(charset, limit, str, str_end)
Effect

Calculates the size and width of the longest substring of [str, str_end) whose width is not greater than limit.

Return type

width_and_ptr<CharT>

Return value

A value ret of type width_and_ptr<CharT>, such that

  • ret.ptr is the greatest pointer not greater than str_end such that the width of [str, ret.ptr) is not greater than limit.

  • ret.width is the width of the substring [str, ret.ptr).

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 {};
template <typename Charset>
constexpr width_t char_width
    ( Charset
    , typename Charset::code_unit ) const noexcept;
Return value

1

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;
Return value
  • 0, if limit is not positive

  • otherwise the length of [str, str_end) , if such length is not greater than limit

  • otherwise, limit

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 ret is such that

  • If limit is not positive, then ret.width is 0 and ret.ptr is str

  • otherwise, if limit.floor() is less than the length of [str, str_end), then ret.width is equal to limit.floor() and ret.ptr is equal to str + limit.floor()

  • otherwise, ret.width is equal to the length of [str, str_end), and ret.ptr is equal to str_end

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 {};
template <typename Charset>
constexpr width_t char_width
    ( Charset
    , typename Charset::code_unit ) const noexcept;
Return value

1

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;
Return value
  • 0, if limit is not positive

  • otherwise, cs.count_codepoints_fast(str, str_end, limit.ceil()).count, if such value is not greater than width_t::max,

  • otherwise, width_t::max

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 ret is such that

  • If limit is not positive, then ret.width is 0 and ret.ptr is str;

  • otherwise, ret.width is equal to ret2.count and ret.ptr is equal to ret2.ptr, where ret2 is the return of cs.count_codepoints_fast(str, str_end, lim.floor())

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 = {};
template <typename Charset>
constexpr width_t char_width
    ( Charset
    , typename Charset::code_unit ) const noexcept;
Return value

1

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;
Return value
  • 0, if limit is not positive

  • otherwise, cs.count_codepoints(str, str_end, limit.ceil()).count, if such value is not greater than width_t::max,

  • otherwise, width_t::max

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 ret is such that

  • If limit is not positive, then ret.width is 0 and ret.ptr is str;

  • otherwise, ret.width is equal to ret2.count and ret.ptr is equal to ret2.ptr, where ret2 is the return of cs.count_codepoints(str, str_end, lim.floor())

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

template <typename Charset>
static width_t char_width
    ( Charset cs
    , typename Charset::code_unit ch) const;
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)

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;
Return value

std::min(limit, w), where w is the sum of the grapheme clusters widths in the UTF-32 string obtained by converting str to UTF-32 via cs, i.e. by calling

cs.to_u32().transcode(str, str_end, /* …​ */, nullptr )

The width of each grapheme cluster is assumed to be equal to the width of its first codepoints ch32, which is assumed to equal to char_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 by str_width(cs, limit, str, str_end )

  • r.ptr is greatest pointer not greater than str_end such that the expression below evaluates to true:

    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.

Example
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:

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>>, if T is a reference type or has any cv-qualifier

  • otherwise, it is PrintableDef, when T is value_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

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 ).

( Optional )
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.

( Optional )
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 type facets_pack</*... */>

  • pre, a value of type premeasurements</*... */>

  • dst, an non-const lvalue reference of type destination<CharT>

  • v, a value of type T::forwarded_type or value_and_format<T, F...>, where F... is such that T::format_specifiers is an alias to tag<F...>.

At least one of the function templates below must be defined:

( Optional )
T::print(dst, fpack, v);
Return Type

void

Effect

Prints v into dst taking into account the facets in fpack

( Optional )
auto c = T::make_printer(tag<CharT>{}, pre, fpack, v);

The make_printer function has two purposes:

  1. to return a callable object c such that c(dst) prints v into dst taking into account the facets in fpack

  2. To measure the size and/or width (or none, depeding on the type pre ) of the content that c 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 is width_presence::yes, otherwise this constructor does not participate in overload resolution.

Effect

Initializes width_accumulator base with width_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 is true, 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 is false

None

When Active is true

The internally stored size value ( that is returned by accumulated_ssize() ) is incremented by the value (s >= 0 ? s : 0).

constexpr std::size_t accumulated_usize() const noexcept;
When Active is false

0

When Active is true

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 is true, 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 is false, otherwise does

if (w > 0 && width_ < limit_) {
    width_ = ( w >= limit_ - width_
             ? limit_
             : width_ + w );
}
constexpr void add_width(width_t w) noexcept;
Effect

None if Active is false, otherwise does width_ += 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
Effects
  • When SizePresence is size_presence::yes, do the equivalent to the following fold expression:

    (..., make_printer<CharT>(pre, facets, args) );
  • When WidthPresence is width_presence::yes but SizePresence is size_presence::no, do make_printer<CharT>(pre, facets, a) for each argument a in args pre->has_remaining_width() returns false. This implies that not necessarily all arguments in args... are used.

  • Does nothing if SizePresence is size_presence::no and WidthPresence is width_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> && ...) is true, 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> && ...) is true, 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> && ...) is true, 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 is true

  • sizeof...(U) == sizeof...(FPE) is true

  • ( std::is_constructible_v<FPE, U> && ... ) is true

  • if sizeof...(U) == 1 is true, then std::remove_cvref_t<U…​> is not facets_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 with std::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) returns true then returns do_get_facet<FCat, Tag>(fp), otherwise return FCat::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 of facets_pack, then returns wheter there is any elemente elm in fpe such that has_facet<FCat, Tag>(elm) is true.

  • If FPE is an instance of constrained_fpe<FPE, Filter>, then returns Filter<Tag>::value && has_facet<FCat, Tag>(fpe.get()).

  • If FPE is a Facet type, returns std::is_same_v<FCat, facet_category<FPE>>

Compile-time requirements

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

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

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 of other.

Compile-time requirements

std::is_copy_constructible<FPE>::value is true, 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 of other.

Compile-time requirements

std::is_move_constructible<FPE>::value is true, 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 is true, 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 is true, 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>, where U is std::remove_cv_t<std::remove_reference_t<T>>.

Return value

constrained_fpe<Filter, U>{ std::forward<T>(arg) }

Compile-time requirements

T is such that U satisfies FacetsPackElement.

7.8. Type requirement FacetsPackElement

A given type F satisfies FacetsPackElement if, and only if, one of the following conditions is true:

7.9. Type requirement ConstrainableFacetsPackElement

A given a type F is a ConstrainableFacetsPackElement if, and only if, one of the following conditions is true:

7.10. Type requirement Facet

A given a type F satisfies Facet if all of the following conditions are met:

7.11. Type requirement FacetCagory

A given a type FCat satisfies FacetCategory if:

  • FCat has a static member function named get_default that takes no argument and whose return type is either F or const F&, where F is a type that satisfies the requirements associated to FCat.

  • FCat has a member named constrainable that is a static constexpr value convertible to bool. ( If this value is false then the facets associated FCat 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:

syntax

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>, where DestCreator is an implementation-defined type that satifies DestinationCreator.

Return value

An object whose DestCreator object _dest_creator is such that _dest_creator.create() returns

basic_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 to(dest, dest + count);

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 to(dest, dest + N);

namespace strf {
template <typename CharT>
/* see below */ to_range(CharT* begin, CharT* end);

} // namespace strf
Return type

printing_syntax<DestCreator>, where DestCreator is an implementation-defined type that satifies DestinationCreator.

Return value

An object whose DestCreator object _dest_creator is such that _dest_creator.create() returns

basic_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 to_range(dest, dest + N);

namespace strf {
template <typename CharT>
/* see below */ to_range(CharT* dest, std::size_t count);

} // namespace strf
Return type and value

Same as of to_range(dest, dest + count);

8.1. Class template printing_syntax

namespace strf {

template < typename DestCreator
         , typename ReservePolicy = no_reserve
         , typename... FPE>
class printing_syntax;

}
Compile-time requirements

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 with dest_creator

Compile time requirements

Only participates in overload resolution if DestCreator is copy-constructible and all types in FPE... are default-constructible and ReservePolicy is not reserve_given_space.

constexpr printing_syntax(DestCreator&& dest_creator)
Effects

Initializes the inther DestCreator object with dest_creator

Compile time requirements

Only participates in overload resolution if DestCreator is move-constructible and all types in FPE... are default-constructible and ReservePolicy is not reserve_given_space.

constexpr printing_syntax(const DestCreator& dest_creator, ReservePolicy poli, U&&... fpes)
Effects
  • Initializes the internal DestCreator object with dest_creator,

  • Initializes the internal ReservePolicy object with poli,

  • 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 in U...

constexpr printing_syntax(DestCreator&& dest_creator, ReservePolicy poli, U&&... fpes
Effects
  • Initializes the internal DestCreator object with dest_creator,

  • Initializes the internal ReservePolicy object with poli,

  • 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 in U...

Member functions for printing

return_type operator()(Args&&... args) const;
Effect

Executes the following steps:

  1. 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 called fargs... and the second pargs...

  2. Create a facets_pack object from the the internal FPE... objects and fargs.... Let it be here called fpack, an let its type be FPack ( which is facets_pack<FPE..., std::remove_cvref_t<decltype(fargs)>...>

When ReservePolicy is strf::reserve_given_space
  1. Let dest_creator be the internal DestCreator object, and poli be the internal reserve_given_space object. Do:

    using dest_type = typename DestCreator::sized_destination_type;
    dest_type dest{dest_creator.create(poli.space)};
  2. Print all arguments pargs... into dest

  3. Returns dest.finish() if such expression is valid

When ReservePolicy is strf::reserve_calc
  1. Do:

    using pre_type = premeasurements<size_presence::yes, width_presence::no>;
    pre_type pre;
  2. For each parg in pargs..., do:

    auto printer = make_printer<char_type>(&pre, fpack, arg);
  3. Let dest_creator be the internal DestCreator object. Do:

    using dest_type = typename DestCreator::sized_destination_type;
    dest_type dest{dest_creator.create(pre.accumulated_ssize())};
  4. For each printer, do printer(dest)

  5. Return dest.finish() if such expression is valid.

When ReservePolicy is strf::no_reserve
  1. Let dest_creator be the internal DestCreator object. Do:

    typename DestCreator::destination_type dest{dest_creator.create()};
  2. Print all arguments `pargs... into dest

  3. Return dest.finish() if such expression is valid.

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 in Args... are FacetsPackElements.

  • PArgs... are the remaining types in Args..., and they are expected to be Printable.

  • facets... are the arguments in args... that correspond to Facets...

  • pargs... are the remaining arguments in args... .

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
constexpr       printing_syntax &  reserve(std::integral auto space) &;
constexpr       printing_syntax && reserve(std::integral auto space) &&;

Changes the space stored in the internal strf::reserve_given_space object, and returns *this or std::move(*this).

constexpr printing_syntax reserve(std::integral auto space) const &;
constexpr printing_syntax reserve(std::integral auto space) const &&;

Returns a new printing_syntax whose internal DestCreator and FPE... objects are copy-constructed or move-constructed ( depedending on the overload used ) from the internal DestCreator and FPE... objects of this object.

When ReservePolicy is not strf::reserve_calc
constexpr printing_syntax<DestCreator, strf::reserve_calc, FPE...>
reserve(std::integral auto space) const &;

constexpr printing_syntax<DestCreator, strf::reserve_calc, FPE...>
reserve(std::integral auto space) &&;

Returns a new printing_syntax whose internal DestCreator and FPE... objects are copy-constructed or move-constructed ( depedending on the overload used ) from the internal DestCreator and FPE... objects of this object, and the the internal strf::reserve_calc object is initialized with space

constexpr /* ... */  reserve_calc() /* ... */;
When ReservePolicy is strf::reserve_calc
constexpr       printing_syntax &  reserve_calc() &;
constexpr const printing_syntax &  reserve_calc() const &;
constexpr       printing_syntax && reserve_calc() &&;
constexpr const printing_syntax && reserve_calc() const &&;

Just returns *this or std::move(*this)

When ReservePolicy is not strf::reserve_calc
constexpr printing_syntax<DestCreator, strf::reserve_calc, FPE...>
reserve_calc() const &;

constexpr printing_syntax<DestCreator, strf::reserve_calc, FPE...>
reserve_calc() &&;

Returns a new printing_syntax whose internal DestCreator and FPE... objects are copy-constructed or move-constructed ( depedending on the overload used ) from the internal DestCreator and FPE... objects of this object.

constexpr /* ... */  no_reserve() /* ... */;
When ReservePolicy is strf::no_reserve
constexpr       printing_syntax &  no_reserve() &;
constexpr const printing_syntax &  no_reserve() const &;
constexpr       printing_syntax && no_reserve() &&;
constexpr const printing_syntax && no_reserve() const &&;

Just returns *this or std::move(*this).

When ReservePolicy is not strf::no_reserve
constexpr printing_syntax<DestCreator, strf::no_reserve, FPE...> no_reserve() const &;
constexpr printing_syntax<DestCreator, strf::no_reserve, FPE...> no_reserve() &&;

Returns a new printing_syntax whose internal DestCreator and FPE... objects are copy-constructed or move-constructed ( depedending on the overload used ) from the internal DestCreator and FPE... objects of this object.

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 in FPE... are copy-constructible.

  • ( In the && overload ) DestCreator and all types in FPE... are move-constructible.

Return type

printing_syntax<DestCreator, ReservePolicy, FPE..., std::remove_cvref_t<U>...>

Effect

Returns a new printing_syntax whose internal DestCreator and FPE... objects are copy-constructed or move-constructed ( depedending on the overload used ) from the internal DestCreator and FPE... objects of this object. and each the internal std::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 for char_type

  • x, an expression of type X or const X

The following must hold:

  • X is CopyConstructible

  • X has a member type alias X::char_type defined as char_type

  • X has the X::destination_type that is a type alias to a concrete type that is derives from destination<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 the std::size_t

  • X, an SizedDestinationCreator type for char_type

  • x, an expression of type X or const X

The following must hold:

  • X is CopyConstructible

  • X has a member type alias T::char_type defined as char_type

  • X has the X::sized_destination_type that is a type alias to a concrete type that derives from destination<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.

is_int_number

matches short, int, long, long long and the corresponding unsigned types

is_char

matches char, char8_t, wchar_t, char16_t, and char32_t

is_string

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