| This document is still a work in progress. | 
1. facets_pack
1.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);- 
- Effects
- 
Initializes each element in this object with the corresponding element in other
- Compile-time requirements
- 
std::is_copy_constructible_v<FPE> && ..., otherwise this constructor does not participate in overload resolution.
 
constexpr facets_pack(facets_pack&& other);- 
- Effects
- 
Initializes each element from the rvalue reference of the corresponding element in other
- Compile-time requirements
- 
std::is_move_constructible_v<FPE> && ..., otherwise this constructor does not participate in overload resolution.
 
constexpr explicit facets_pack(const FPE& ... fpe)- 
- Effects
- 
Initializes each element with the correspondig value in fpe...
- Compile-time requirements
- 
std::is_copy_constructible_v<FPE> && ..., otherwise this constructor does not participate in overload resolution.
 
template <typename... U>[br]
constexpr explicit facets_pack(U&&... u)- 
- Effects
- 
Initializes each element with the correspondig value in std::forward<U>(u)....
- Compile-time requirements
- 
This constructor does not participate in overload resolution, unless - 
sizeof...(U) == sizeof...(FPE), and
- 
sizeof...(U) != 0, and
- 
std::is_constructible_v<FPE, U&&> && ...
 
- 
 
Assignment operators (deleted)
   facets_pack& operator=(const facets_pack&) = delete
   facets_pack& operator=(facets_pack&&) = delete;- 
Assignments are deleted because they seem unecessary and it’s unclear what would be the best implementation in the case there is any reference type in FPE....
1.2. Function template pack
template <typename ... T>
constexpr /* see below */ pack(const T& ... args)- 
- Return type
- 
facets_pack<std::remove_cv_t<std::remove_reference_t<T>>...>
- Return value
- 
A facets_packobject initialized withstd::forward<T>(args)...
 
1.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)returnstruethen returns <<do_get_facet,do_get_facet<FCat, Tag>(fp), otherwise returnFCat::get_default().
- Compile-time requirements
- 
FCatis a FacetCategory type.
 
1.4. Hypothetical function template fas_facet
| This function template does not exists in this library.
       It is only documented to help to explain the get_facetfunction template. | 
template <typename FCat, typename Tag, typename FPE>
constexpr bool has_facet(const FPE& fpe)- 
- Effects
- 
- 
If FPEis an instance offacets_pack, then returns wheter there is any elementeelminfpesuch thathas_facet<FCat, Tag>(elm)istrue.
- 
If FPEis an instance ofconstrained_fpe<FPE, Filter>, then returnsFilter<Tag>::value && has_facet<FCat, Tag>(fpe.get()).
- 
If FPEis a Facet type, returnsstd::is_same_v<FCat, facet_category<FPE>>
 
- 
- Compile-time requirements
- 
- 
FCatis a FacetCategory type.
- 
FPEsatisfies FacetsPackElement.
 
- 
 
1.5. Hypothetical function template do_get_facet
| This function template is not part of the library.
      It only is documented to help to explaine the get_facetfunction template | 
template <typename FCat, typename Tag, typename FPE>
constexpr decltype(auto) do_get_facet(const FPE& fpe);- 
- Compile-time requirements
- 
- 
FCatsatisfies FacetCategory.
- 
FPEsatisfies FacetsPackElement.
- 
has_facet<FCat, Tag>(fpe)istrue.
 
- 
 
1.6. Class template constrained_fpe
template <template <class> class Filter, typename FPE>
class constrained_fpe;- 
The class template constrained_fpeis designed to be used infacets_pack.constrained_fpe<Filter, FPE>holds a value ofFPEthat will only be returned byget_facet<Category, Tag>ifFilter<Tag>::valueistrue.- Compile-time requirements
- 
- 
For any type T,Filter<T>has a member variablevaluethat is a static constexpr value whose type is implicitly convertible tobool
- 
FPEsatisfies ConstrainableFacetsPackElement.
 
- 
 
Synopsis
namespace strf {
template <template <class> class Filter, typename FPE>
class constrained_fpe
{
public:
    // constructors
    constexpr constrained_fpe(const constrained_fpe&) = default;
    constexpr constrained_fpe(constrained_fpe&& other) = default;
    constexpr constrained_fpe(const FPE& f);
    // element access
    constexpr const FPE& get() const;
private:
    FPE element; // exposition only;
};
} // namespace strfMember functions
Constructors
constexpr explicit constrained_fpe(const FPE& fpe);- 
- Effect
- 
Initializes the element of the constrained_fpewithfpe.
 
constexpr constrained_fpe(const constrained_fpe& other);- 
- Effect
- 
Initializes the element of the constrained_fpefrom the const reference of the element ofother.
- Compile-time requirements
- 
std::is_copy_constructible<FPE>::valueistrue.
 
constexpr constrained_fpe(constrained_fpe&& other);- 
- Effect
- 
Initializes the element of the constrained_fpefrom the rvalue reference of element ofother.
- Compile-time requirements
- 
std::is_move_constructible<FPE>::valueistrue.
 
Element access
constexpr const FPE& get() const;- 
- Effect
- 
Return the stored element; 
 
1.7. Function template constrain
template <template <class> class Filter, typename T>
constexpr constrained_fpe<Filter, U> constrain(const T& arg);- 
constrainis just a syntatic sugar to create aconstrained_fpeobject.- Return type
- 
constrained_fpe<Filter, U>, whereUisstd::remove_cv_t<std::remove_reference_t<T>>.
- Return value
- 
constrained_fpe<Filter, U>{ std::forward<T>(arg) }
- Compile-time requirements
- 
Tis such thatUsatisfies FacetsPackElement.
 
1.8. Type requirement FacetsPackElement
A given type F satisfies FacetsPackElement if, and only if, one of the following conditions is true:
- 
Fis a Facet type.
- 
Fis an instance offacets_pack.
- 
Fis an instance ofconstrained_fpe.
1.9. Type requirement ConstrainableFacetsPackElement
A given a type F is a ConstrainableFacetsPackElement if, and only if,
one of the following conditions is true:
- 
Fis a Facet type andfacet_category<F>::constrainableistrue.
- 
Fisfacets_pack<F2...>and all types inF2...are ConstrainableFacetsPackElement.
- 
Fis an instance ofconstrained_fpe.
1.10. Type requirement Facet
A given a type F satisfies Facet if all of the following conditions are met:
- 
Fis MoveConstructible
- 
facet_category<F>satisfies the FacetCategory requirements.
1.11. Type requirement FacetCagory
A given a type FCat satisfies FacetCategory if:
- 
FCathas a static member function namedget_defaultthat takes no argument and whose return type is eitherForconst F&, whereFis a type that satisfies the requirements associated toFCat.
- 
FCathas a member namedconstrainablethat is a static constexpr value convertible tobool. ( If this value isfalsethen the facets associatedFCatcan not be constrained ).
1.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;
};1.13. Type alias facet_category
facet_category is just a syntatic sugar:
template <typename Facet>
using facet_category = facet_traits<Facet>::typename category;2. Requirements of printable types
This section provides what one needs to be known to add a new printable type or override an existing one.
2.1. Type requirement Printable
A type T is Printable if:
- 
print_traits_of<T>is defined and is a PrintTraits type
- 
print_traits_of<T>::forwarded_typeis implicitly convertible fromT
2.2. Type alias template print_traits_of
namespace strf {
struct print_traits_tag;
template <typename T> print_traits;
template <typename T> using print_traits_of = /* see below... */;
} // namespace strfprint_traits_of<T> is:
- 
print_traits_of<std::remove_cvref<T>>, ifTis a reference type or has any cv-qualifier
- 
otherwise, it is Traits, whenTisvalue_with_formatters<Traits, /*... */>
- 
otherwise, it is print_traits<T>if such template specialization is defined
- 
otherwise, it is decltype(tag_invoke(print_traits_tag{}, std::declval<T>()))
2.3. Type alias template forwarded_printable_type
namespace strf {
template <typename T>
using forwarded_printable_type = /* see below... */;
} // namespace strf- 
forwarded_printable_type<T>isT, whenTavalue_with_formatters</*... */>
- 
otherwise, it is typename print_traits_of<T>::forwarded_type
2.4. Type requirement PrintTraits
Given
- 
T, a PrintTraits type.
- 
P, a Printable type such thatprint_traits_of<P>isT.
Member types
T::forwarded_typeforwarded_type must be implicitly convertible from P,
and must be copy-constructible. And its copy-constructor should be fast.
( forwarded_type is usually P or const P& )
forwarded_type is used intead of P as the storage type in some
situations ( for example, the objects created by fmt and join ).
T::facet_tagThe type that is used as the tag type in get_facet.
It shall not be a reference type, and shall not contain cv-qualifiers.
Usually is it std::remove_cv_t<std::remove_reference<forwarded_type>>
T::fmt_type;A type alias to a value_with_formatters<T, /*...*/> type.
It is the return type of fmt(std::declval<P>())
Member static function templates
Given
- 
T, a PrintTraits type.
- 
CharT, a character type
- 
fpack, a value of typefacets_pack</*... */>
- 
preview, an lvalue of typeprint_preview</*... */>
- 
v, a value of typeT::forwarded_typeorT::fmt_type
T::template make_printer_input<CharT>(preview, fpack, v)| Return type | A PrinterInput type. | 
| Return value | A value  | 
2.5. Type requirements PrinterInput
Given
- 
CharT, a character type
- 
Preview, an instance of theprint_previewclass template
- 
X, a PrinterInput type for typesCharTandPreview
- 
x, a value of typeX
T::char_typeA type alias to CharT.
T::preview_typeA type alias to Preview.
T::printer_typeA type that is constructible from X and convertible to const printer<CharT>&,
such that the sequence:
statisfies the following postconditions when Preview::size_required is true:
- 
if predicted_size <= dest_sizeistruethendest.recycle()is not called.
x.previewA lvalue reference of type Preview.
2.6. Function template make_default_printer_input
namespace strf {
template <typename CharT, typename Preview, typename FPack, typename Arg>
constexpr auto make_default_printer_input
    ( Preview& preview, const FPack& fp, const Arg& arg)
    noexcept(/* see below... */)
    -> /* see below... */
} // namespace strfThe expression make_default_printer_input<CharT>(preview, fp, arg) is equivalent to
print_traits_of<Arg>::template make_printer_input<CharT>(preview, fp, arg);2.7. Facet category print_override_c
This facet category affects the return type and value of make_printer_input.
This way, it enables the user change how a printable type is printed,
by making the library an the alternative PrinterInput object.
A facet of this category should aways be constrained to the
printable type intended to be overriden.
namespace strf {
struct print_override_c {
    static constexpr bool constrainable = true;
    constexpr static no_print_override get_default() noexcept {
        return {};
    }
};
} // namespace strfStruct no_print_override
no_print_override is the default facet of print_override_c category.
namespace strf {
struct no_print_override {
    using category = print_override_c;
    template <typename CharT, typename Preview, typename FPack, typename Arg>
    constexpr static auto make_printer_input(Preview& preview, const FPack& fp, Arg&& arg)
        noexcept(noexcept(make_default_printer_input<CharT>(preview, fp, arg)))
    {
        return make_default_printer_input<CharT>(preview, fp, arg);
    }
};
} // namespace strf2.8. Function template make_printer_input
namespace strf {
template <typename CharT, typename Preview, typename FPack, typename Arg>
constexpr auto make_printer_input(Preview& preview, const FPack& fp, const Arg& arg)
{
    auto tag = typename print_traits_of<Arg>::facet_tag;
    auto f = get_facet<print_override_c, tag>(fp);
    return f.template make_printer_input<CharT>(preview, fp, arg);
}
} // namespace strf2.9. Type alias template printer_type
namespace strf {
template <typename CharT, typename Preview, typename FPack, typename Arg>
using printer_input_type = decltype
    ( make_printer_input<CharT>( std::declval<Preview&>()
                               , std::declval<const FPack&>()
                               , std::declval<Arg>() ) );
template <typename CharT, typename Preview, typename FPack, typename Arg>
using printer_type = typename printer_input_type<CharT, Preview, FPack, Arg>::printer_type;
} // namespace strf2.10. Class template printer
namespace strf {
template <typename CharT>
class printer {
public:
    using char_type = CharOut;
    virtual ~printer() {}
    virtual void print_to(basic_outbuff<CharT>&) const = 0;
};
} // namespace strf2.11. Class template print_preview
namespace strf {
enum class preview_width: bool { no = false, yes = true };
enum class preview_size : bool { no = false, yes = true };
template <preview_size SizeRequired, preview_width WidthRequired>
class print_preview
    : public size_preview<static_cast<bool>(SizeRequired)>
    , public width_preview<static_cast<bool>(WidthRequired)>
{
public:
    static constexpr bool size_required = static_cast<bool>(SizeRequired);
    static constexpr bool width_required = static_cast<bool>(WidthRequired);
    static constexpr bool nothing_required = ! size_required && ! width_required;
    constexpr print_preview() noexcept = default;
    constexpr explicit print_preview(width_t initial_width) noexcept;
};
} // namespace strfConstructors
constexpr print_preview() noexcept;| Effect | Default-construct each of the base classes. | 
constexpr explicit print_preview(width_t initial_width) noexcept;- Compile-time requirement
- 
WidthRequiredispreview_width::yes, otherwise this constructor does not participate in overload resolution.
- Effect
- 
Initializes width_previewbase withinitial_width.
2.12. Class template size_preview
namespace strf {
template <bool Active>
class size_preview
{
public:
    explicit constexpr size_preview() noexcept;
    explicit constexpr size_preview(std::size_t initial_size) noexcept;
    constexpr void add_size(std::size_t) noexcept;
    constexpr std::size_t get_size() const noexcept;
};
} // namespace strfMember functions
explicit constexpr size_preview() noexcept;- Postcondition
- 
get_size() == 0
explicit constexpr size_preview(std::size_t initial_size) noexcept;- Compile-time requirement
- 
Activeistrue, otherwise this constructor does not participate in overload resolution.
- Postcondition
- 
get_size() == initial_size
constexpr void add_size(std::size_t s) noexcept;- Postcondition
- 
- When Activeisfalse
- 
None 
- When Activeistrue
- 
(get_size() - previous_size == s), whereprevious_sizeis the return value ofget_size()before this call.
 
- When 
constexpr void get_size() const noexcept;- Return value
- 
- When Activeisfalse
- 
0(always)
- When Activeistrue
- 
The internally stored size value. 
 
- When 
2.13. Class template width_preview
namespace strf {
template <bool Active>
class width_preview
{
public:
    constexpr width_preview() noexcept;
    explicit constexpr width_preview(width_t initial_width) noexcept;
    constexpr void subtract_width(width_t) noexcept;
    constexpr void checked_subtract_width(std::ptrdiff_t w) noexcept;
    constexpr void clear_remaining_width() noexcept;
    constexpr width_t remaining_width() const noexcept;
}
} // namespace strfMember functions
constexpr width_preview() noexcept;- Postcondition
- 
remaining_width() == 0
constexpr width_preview(width_t initial_width) noexcept;- Compile-time requirement
- 
Activeistrue, otherwise this constructor does not participate in overload resolution.
- Postcondition
- 
remaining_width() == initial_width
void subtract_width(width_t w) noexcept;- Postcondition
- 
- When Activeisfalse
- 
None 
- When Activeistrue
- 
remaining_width() == previous_w - wwhere previous_wis the return value ofremaining_width()before this call.
 
- When 
void checked_subtract_width(width_t w) noexcept;- Postcondition
- 
- When Activeisfalse
- 
None 
- When Activeistrue
- 
remaining_width() == (w < previous_w ? previous_w - w : 0)where previous_wis the return value ofremaining_width()before this call.
 
- When 
void checked_subtract_width(std::ptrdiff_t w)- Postcondition
- 
- When Activeisfalse
- 
None 
- When Activeistrue
- 
remaining_width() == (w < previous_w.ceil() ? previous_w - (std::int16_t)w : 0)where previous_wis the return value ofremaining_width()before this call.
 
- When 
3. Format functions
3.1. Global format functions
namespace strf {
inline namespace format_functions {
constexpr /*…*/ hex {};
constexpr /*…*/ dec {};
constexpr /*…*/ oct {};
constexpr /*…*/ bin {};
constexpr /*…*/ fixed {};
constexpr /*…*/ sci {};
constexpr /*…*/ gen {};
constexpr /*…*/ multi {};
constexpr /*…*/ conv {};
constexpr /*…*/ sani {};
constexpr /*…*/ right {};
constexpr /*…*/ left {};
constexpr /*…*/ center {};
constexpr /*…*/ split {};
} // inline namespace format_functions
} // namespace strfThe format_functions inline namespace contains callable objects
that work as alias to format functions
| Expression | Equivalent Expression | 
|---|---|
| 
 | 
 | 
| 
 | 
 | 
| 
 | 
 | 
| 
 | 
 | 
| 
 | 
 | 
| 
 | 
 | 
| 
 | 
 | 
| 
 | 
 | 
| 
 | 
 | 
| 
 | 
 | 
| 
 | 
 | 
| 
 | 
 | 
| 
 | 
 | 
| 
 | 
 | 
| 
 | 
 | 
| 
 | 
 | 
| 
 | 
 | 
| 
 | 
 | 
| 
 | 
 | 
| 
 | 
 | 
| 
 | 
 | 
| 
 | 
 | 
| 
 | 
 | 
3.2. Callable object fmt
namespace strf {
template <typename T>
using fmt_value_type = typename fmt_type<T>::value_type;
constexpr struct /*…*/ {
    template <typename T>
    constexpr fmt_type<T> operator()(T&& value) const
        noexcept(noexcept(fmt_type<T>fmt_value_type<T>{(T&&)value}}))
    {
        return fmt_type<T>{fmt_value_type<T>{(T&&)value}};
    }
} fmt;
} // namespace strf3.3. Type alias template fmt_type
namespace strf {
template <typename T>
using fmt_type = /*…*/;
} // namespace strffmt_type<T> is:
- 
T, whenTisvalue_with_formatters</* … */>
- 
print_traits_of<T>::fmt_type, otherwise
fmt_type<T> is always expected to be an instance of value_with_formatters class template.
3.4. Class template value_with_formatters
namespace strf {
template <typename ValueType, class... Fmts>
class value_with_formatters;
} // namespace strf- 
- Compile-time requirements
- 
- 
All types in Fmt...satisfy Formatter.
- 
All types in Fmt...are different.
 
- 
 
The purpose of the value_with_formatters class template is to aid
the creation classes that contain format functions.
The types of expressions like fmt("Hello"),
fmt(55), *hex(55) > 20, etc, are all value_with_formatters
instances. The ValueType template parameter holds the input
type, and the types in Fmts... defines the format functions.
Synopsis
namespace strf {
template <typename ValueType, class... Fmts>
class value_with_formatters
    : public Fmts::template fn<value_with_formatters<ValueType, Fmts...>>...
{
public:
    constexpr value_with_formatters(const value_with_formatters&) = default;
    constexpr value_with_formatters(value_with_formatters&&) = default;
    constexpr value_with_formatters(const ValueType&);
    template <typename OtherValueType>
    constexpr value_with_formatters
        ( const ValueType&
        , const value_with_formatters<OtherValueType, Fmts...>& );
    template <typename OtherValueType>
    constexpr value_with_formatters
        ( const ValueType&
        , value_with_formatters<OtherValueType, Fmts...>&& );
    template <typename... OtherFmts>
    constexpr value_with_formatters(const value_with_formatters<ValueType, OtherFmts...>&);
    template <typename... OtherFmts>
    constexpr value_with_formatters(value_with_formatters<ValueType, OtherFmts...>&&);
    constexpr const ValueType& value() const;
};
} // namespace strfTo-do
3.5. Type requirement Formatter
A type Fmt is a Formatter 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 ifTisvalue_with_formatters<ValueType, Fmts...>. In this case, note thatFmtis inFmts...andTderives fromFmt::template fn<T>.
- 
Fmt::template fn<T>is default constructible, assuming it is well formed.
- 
Fmt::template fn<T>can be constructed fromconst Fmt::template fn<U>&, if both are well formed.
3.6. Formatter alignment_formatter
namespace strf {
template <bool HasAlignment>
struct alignment_formatter_q
{
    template <class T>
    using fn = alignment_formatter_fn<T, HasAlignment>;
};
using alignment_formatter       = alignment_formatter_q<true>;
using empty_alignment_formatter = alignment_formatter_q<false>;
} // namespace strfalignment_formatter_fn
namespace strf {
template <class T, bool HasAlignment>
class alignment_formatter_fn;
{
public:
    // constructors
    constexpr alignment_formatter_fn() noexcept;
    template <typename U, bool B>
    constexpr explitic alignment_formatter_fn(const alignment_formatter_fn<U, B>& u) noexcept;
    // format functions
    constexpr T&& operator<(width_t width) && noexcept; // left
    constexpr T&& operator>(width_t width) && noexcept; // right
    constexpr T&& operator^(width_t width) && noexcept; // center
    constexpr T&& operator%(width_t width) && noexcept; // split, aka internal
    constexpr T&& fill(char32_t ch) && noexcept;
    // observers
    constexpr width_t width() const noexcept;
    constexpr text_alignment alignment() const noexcept;
    constexpr char32_t fill() const noexcept;
    constexpr alignment_format get_alignmet_format() const noexcept;
};
// alignment_formatter_fn<T, false> is an empty class
template <class T>
class alignment_formatter_fn<T, false>
{
    using converted_fmt = boost::mp_replace< T , alignment_formatter_q<false>
                                               , alignment_formatter_q<true> >;
public:
    // constructors
    constexpr alignment_formatter_fn() noexcept;
    template <typename U>
    constexpr explicit alignment_formatter_fn(const alignment_formatter_fn<U, false>&) noexcept;
    // observers
    constexpr width_t width() const noexcept;
    constexpr text_alignment alignment() const noexcept;
    constexpr char32_t fill() const noexcept;
    constexpr alignment_format get_alignmet_format() const noexcept;
    // format functions
    constexpr converted_fmt operator<(width_t width) const noexcept;
    constexpr converted_fmt operator>(width_t width) const noexcept;
    constexpr converted_fmt operator^(width_t width) const noexcept;
    constexpr converted_fmt operator%(width_t width) const noexcept;
    constexpr converted_fmt fill(char32_t ch) const noexcept;
};
} // namespace strfConstructors
constexpr alignment_formatter_fn() noexcept;- 
- Postconditions
- 
get_alignmet_format() == alignment_format{}
 
template <typename U, bool B>
constexpr explitic alignment_formatter_fn(const alignment_formatter_fn<U, B>& u) noexcept;- 
- Postconditions
- 
get_alignmet_format() == u.get_alignmet_format()
- Note
- 
This function only participates in overload resolution if 'HasAlignment' is trueorBisfalse
 
Observers
constexpr alignment_format get_alignmet_format() const noexcept;- 
- Return value
- 
- 
alignment_format{}, whenHasAlignmentisfalse.
- 
The value corresponding to the state of this object, when HasAlignmentistrue.
 
- 
 
constexpr {width_t} width() const noexcept;- 
- Return value
- 
get_alignmet_format().width
 
constexpr text_alignment alignment() const noexcept;- 
- Return value
- 
get_alignmet_format().alignment
 
constexpr char32_t fill() const noexcept;- 
- Return value
- 
get_alignmet_format().fill
 
Format functions
constexpr /*return type */ operator<({width_t} width) /* qualifier */ noexcept;- 
- Posconditions
- 
The return value rsatisfies:- 
r.width() == width
- 
r.alignment == text_alignment::left
 
- 
- Return value
- 
- 
when HasAlignmentisfalse:converted_fmt{static_cast<const T&>(*this)} < width.
- 
when HasAlignmentistrue:std::move(static_cast<T&>(*this)).
 
- 
 
constexpr /*return type */ operator>({width_t} width) /* qualifier */ noexcept;- 
- Posconditions
- 
The return value rsatisfies:- 
r.width() == width
- 
r.alignment() == text_alignment::right
 
- 
- Return value
- 
- 
when HasAlignmentisfalse:converted_fmt{static_cast<const T&>(*this)} > width.
- 
when HasAlignmentistrue:std::move(static_cast<T&>(*this)).
 
- 
 
constexpr /*return type */ operator^({width_t} width) /* qualifier */ noexcept;- 
- Posconditions
- 
The return value rsatisfies:- 
r.width() == width
- 
r.alignment() == text_alignment::center
 
- 
- Return value
- 
- 
when HasAlignmentisfalse:converted_fmt{static_cast<const T&>(*this)} ^ width.
- 
when HasAlignmentistrue:std::move(static_cast<T&>(*this)).
 
- 
 
constexpr /*return type */ operator%({width_t} width) /* qualifier */ noexcept;- 
- Posconditions
- 
The return value rsatisfies:- 
r.width() == width
- 
r.alignment() == text_alignment::split
 
- 
- Return value
- 
- 
when HasAlignmentisfalse:converted_fmt{static_cast<const T&>(*this)} % width.
- 
when HasAlignmentistrue:std::move(static_cast<T&>(*this)).
 
- 
 
constexpr /*return type */ fill(char32_t ch) /* qualifier */ noexcept;- 
- Posconditions
- 
The return value rsatisfies:- 
r.fill() == ch
 
- 
- Return value
- 
- 
when HasAlignmentisfalse:converted_fmt{static_cast<const T&>(*this)}.fill(ch).
- 
when HasAlignmentistrue:std::move(static_cast<T&>(*this)).
 
- 
 
alignment_format
namespace strf {
enum class text_alignment {left, right, split, center};
struct alignment_format
{
    char32_t fill = U' ';
    width_t width = 0;
    text_alignment alignment = text_alignment::right;
};
constexpr bool operator==(alignment_format lhs, alignment_format rhs) noexcept;
constexpr bool operator!=(alignment_format lhs, alignment_format rhs) noexcept;
} // namespace strf3.7. Formatter int_formatter
namespace strf {
template <class T, int Base>
class int_formatter_fn;
template <int Base>
struct int_formatter
{
    template <typename T>
    using fn = strf::int_formatter_fn<T, Base>;
};
} // namespace strfint_formatter_fn
namespace strf {
struct int_format
{
    unsigned precision = 0;
    bool showbase = false;
    bool showpos = false;
};
constexpr bool operator==(int_format lhs, int_format rhs) noexcept;
constexpr bool operator!=(int_format lhs, int_format rhs) noexcept;
template <class T, int Base>
class int_formatter_fn
{
public:
    constexpr int_formatter_fn() noexcept;
    template <typename U, int OtherBase>
    constexpr int_formatter_fn(const int_formatter_fn<U, OtherBase> & u) noexcept;
    // observers
    constexpr int_format get_int_format() const noexcept;
    constexpr unsigned precision() const noexcept;
    constexpr bool showbase() const noexcept;
    constexpr bool showpos() const noexcept;
    constexpr static int base() noexcept;
    // format functions
    constexpr T&& p(unsigned precision) && noexcept; // set precision
    constexpr T&& operator+() && noexcept;           // show positive sign
    constexpr T&& operator*() && noexcept;           // show base
     constexpr T&& operator~() && noexcept;           // show base
    constexpr /* see below */ hex() && noexcept; // hexadecimal base
    constexpr /* see below */ dec() && noexcept; // decimal base
    constexpr /* see below */ oct() && noexcept; // octal base
    constexpr /* see below */ bin() && noexcept; // binary base
};
} // namespace strfObservers
constexpr int_format get_int_format() const noexcept;- 
- Return value
- 
The value corresponding to the state of this object. 
 
constexpr unsigned precision() const noexcept;- 
- Return value
- 
get_int_format().precision
 
constexpr showpos() const noexcept;- 
- Return value
- 
get_int_format().showpos
 
constexpr showbase() const noexcept;- 
- Return value
- 
get_int_format().showbase
 
constexpr static base() noexcept;- 
- Return value
- 
Base
 
Format functions
constexpr T&& p(unsigned precision) && noexcept;- 
- Postconditions
- 
precision() == precision
- Return value
- 
std::move(static_cast<T&>(*this))
 
constexpr T&& operator+() && noexcept;- 
- Postconditions
- 
showpos() == true
- Return value
- 
std::move(static_cast<T&>(*this))
 
constexpr T&& operator*() && noexcept;- 
- Postconditions
- 
showbase() == true
- Return value
- 
std::move(static_cast<T&>(*this))
 
constexpr /* see below */ hex() &&;     // hexadecimal base
constexpr /* see below */ dec() &&;     // decimal base
constexpr /* see below */ oct() &&;     // octal base
constexpr /* see below */ bin() &&;     // binary base- 
- Return type
- 
std::conditional_t< Base == NewBase , T&& , boost::mp_replace<T, int_formatter<Base>, int_formatter<NewBase> >, where NewBaseis equal to10indec(),16inhex(),8inoct()and2inbin().
- Return value
- 
- 
static_cast<ReturnType>(static_cast<T&>(*this)), whereReturnTypeis the return type;
 
- 
 
3.8. Formatter float_formatter
namespace strf {
template <class T, float Base>
class float_formatter_fn;
template <float Base>
struct float_formatter
{
    template <typename T>
    using fn = float_formatter_fn<T, Base>;
};
} // namespace strffloat_formatter_fn
namespace strf {
template <typename T>
class float_formatter_fn
{
public:
    constexpr float_formatter_fn() noexcept;
    template <typename U>
    constexpr explicit float_formatter_fn(const float_format_fn<U>& other) noexcept;
    // observers
    constexpr float_format get_float_format() const noexcept;
    // format functions
    constexpr T&& operator+() && noexcept;
    constexpr T&& operator*() && noexcept;
    constexpr T&& p(unsigned precision) && noexcept;
    constexpr T&& gen() && noexcept;
    constexpr T&& sci() && noexcept;
    constexpr T&& fixed() && noexcept;
};
} // namespace strfConstructors
constexpr float_formatter_fn() noexcept;- 
- Postconditions
- 
get_float_format() == float_format{}
 
template <typename U>
constexpr explicit float_formatter_fn(const float_formatter_fn<U>& other) noexcept;- 
- Postconditions
- 
get_float_format() == other.get_float_format()
 
Format functions
constexpr T&& operator+() && noexcept;- 
- Postconditions
- 
get_float_format().showpos == true
- Return value
- 
static_cast<T&&>(static_cast<T&>(*this))
 
constexpr T&& operator*() && noexcept;- 
- Postconditions
- 
get_float_format().showpoint == true
- Return value
- 
static_cast<T&&>(static_cast<T&>(*this))
 
constexpr T&& p(unsigned precision) && noexcept;- 
- Postconditions
- 
get_float_format().precision == precision
- Return value
- 
static_cast<T&&>(static_cast<T&>(*this))
 
constexpr T&& gen() && noexcept;- 
- Postconditions
- 
get_float_format().notation = float_notation::general
- Return value
- 
static_cast<T&&>(static_cast<T&>(*this))
 
constexpr T&& sci() && noexcept;- 
- Postconditions
- 
get_float_format().notation = float_notation::scientific
- Return value
- 
static_cast<T&&>(static_cast<T&>(*this))
 
constexpr T&& fixed() && noexcept;- 
- Postconditions
- 
get_float_format().notation = float_notation::fixed
- Return value
- 
static_cast<T&&>(static_cast<T&>(*this))
 
float_format
namespace strf {
enum class float_notation{fixed, scientific, general};
struct float_format
{
    unsigned precision = (unsigned)-1;
    float_notation notation = float_notation::general;
    bool showpoint = false;
    bool showpos = false;
};
constexpr bool operator==(float_format lhs, float_format rhs) noexcept;
constexpr bool operator!=(float_format lhs, float_format rhs) noexcept;
} // namespace strf- notation
- 
- 
float_notation::fixed: Prints like123.45
- 
float_notation::scientific: Prints like1.2345e+02
- 
float_notation::general: When precision is(unsigned)-1, prints in the scientfic notation if it is shorter than the fixed notation. When precision is different than(unsigned)-1, does like instd::printf: uses the scientfic notation if the exponent is less than -4 or greater than or equal to the precision. Trailing fractional zeros are not printed.
 
- 
- precision
- 
When notation == float_notation::general, the precision is the number of significant digits. Otherwise it is the number of fractional digits.precision == 0has the same effect asprecision == 1.
- showpoint
- 
Prints the decimal point even when there are no fractional digits. 
- showpos
- 
Prints the positive sign '+'when the value is positive.
3.9. Formatter quantity_formatter
namespace strf {
struct quantity_formatter
{
    template <class T>
    using fn = quantity_formatter_fn<T>;
};
} // namespace strfquantity_formatter_fn
namespace strf {
template <class T>
class quantity_formatter_fn
{
public:
    constexpr quantity_formatter_fn(std::size_t count) noexcept;
    constexpr quantity_formatter_fn() noexcept;
    template <typename U>
    constexpr explicit quantity_formatter_fn(const quantity_formatter_fn<U>& u) noexcept
        : _count(u.count())
    {
    }
    constexpr T&& multi(std::size_t count) && noexcept
    constexpr std::size_t count() const noexcept
};
} // namespace strfConstructors
constexpr quantity_formatter_fn() noexcept;- 
- Postconditions
- 
count() == 1
 
template <typename U>
constexpr explicit quantity_formatter_fn(const quantity_formatter_fn<U>& u) noexcept;- 
- Postconditions
- 
count() == u.count()
 
Format functions
constexpr T&& multi(std::size_t count) && noexcept- 
- Postconditions
- 
count() == count
- Return value
- 
static_cast<T&&>(*this)
 
4. List of printable types
4.1. Strings
- Types
- 
const CharT*,std::string_view<CharT, Traits>andstd::basic_string<CharT, Traits, Alloc>
- 
where: 
- 
- 
CharTis the character type. If it is not the same as the output character type ( defined by the destination ), then it is necessary to use theconvorsaniformat function.
- 
Traitscan be any type that satisfies CharTraits
- 
Alloccan be any type that satisfies Allocator
 
- 
- Format functions
- 
( in addition to alignment functions ) - p(width_t limit)
- 
Does not print the whole string if its width is greater than limit, but the greatest possible amount of its leading Unicode code points such that the width is not greater thanlimit.
- template <typename Encoding> sanitize_from_encoding(Encoding enc)
- 
Translates input string from encto the output encoding. If the encodings are the same then sanitizes the input string.
- sanitize_encoding()
- 
Translates input string from the encoding associated to CharTto the output encoding. If these encodings are the same then sanitizes the input string.
- template <typename Encoding> convert_from_encoding(Encoding enc)
- 
Translates input string from encto the output encoding, if these encodings are not the same. Otherwise, copies input string as it is.
- convert_encoding()
- 
Translates input string from the encoding associated to CharTto the output encoding, if these encodings are not the same. Otherwise, copies the input string as it is.
- template <typename Encoding> sani(Encoding enc)
- 
Equivanlent to sanitize_encoding(enc)
- template <typename Encoding> conv(Encoding enc)
- 
Equivanlent to convert_encoding(enc)
- sani()
- 
Equivalent to sanitize_encoding()
- conv()
- 
Equivalent to convert_encoding()Exampleauto str = strf::to_string(strf::center(u" Hello! ", 16, '*').conv()); assert(str == "**** Hello! ****");See also the section about encoding conversion. 
 
- Facet categories
4.2. Single characters
- Type
- 
CharT, that is the output character type defined by the destination.
- Format functions
- 
( in addition to alignment functions ) 
| multi(std::size_t count) | Prints the character  | 
- Facet categories
- 
- 
char_encoding_c<CharType>: Used to encode the fill character.
 
4.3. bool
- Type
- 
bool
- Format functions
- 
Alignment functions only. 
- Facet categories
- 
- 
char_encoding_c<CharType>: Used to encode the fill character.
 
4.4. const void*
- Types
- 
const void*
- Format functions
- 
The alignment functions only. 
- Facet categories
- 
- 
numpunct_c<16>
- 
char_encoding_c<CharType>: Used to encode the fill character and the punctuation characters.
 
4.5. Integers
- Types
- 
short,int,long int,long long int,unsigned short,unsigned int,unsigned long intandunsigned long long int
- Format functions
- 
( in addition to alignment functions ) 
| dec() | Use decimal base ( This is already the default, though ) | 
| hex() | Use hexadecimal base. | 
| oct() | Use octal base. | 
| bin() | Use binary base. | 
| p(unsigned precision) | Ensures that at least  | 
| operator+() | When in decimal base, prints the positive sign
 | 
| operator*() | Prints the base indication
(  | 
| operator~() | Equivalent to  | 
- Facet categories
- 
- 
numpunct_c<Base>
- 
char_encoding_c<CharType>: Used to encode the fill character and the punctuation characters.
 
4.6. Floating Points
- Types
- 
float,double
- Format functions
- 
( In addition to the alignment functions ) 
| operator+() | When in decimal base, prints the positive sign
 | 
| operator*() | Prints the decimal point even when there are no fractional digits. | 
| operator~() | Equivalent to  | 
| sci() | Prints in scientific notation, like this:  | 
| fixed() | Prints in decimal notation, like this:  | 
| gen() | This is the default notation.
When precision is unspecified ( or equal to  | 
| hex() | Prints in hexadecimal notation, like this  | 
| p(unsigned precision) | If  | 
- Facet categories
- 
- 
numpunct_c<10>
- 
char_encoding_c<CharType>: Used to encode the fill character and the punctuation characters.
 
4.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 strfint 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 strfAny format function applicable to the element type of the
range can also be applied to the
expression strf::fmt_range(/*...*/) or
strf::fmt_separated_range(/*...*/).
This way the format functions is applied to all elements:
std::vector<int> vec = { 11, 22, 33 };
auto str1 = strf::to_string("[", +strf::fmt_separated_range(vec, " ;") > 4, "]");
assert(str1 == "[ +11 ; +22 ; +33]");std::vector<int> vec = { 11, 22, 33 };
auto str2 = strf::to_string
    ( "["
    , *strf::fmt_separated_range(vec, " / ").fill('.').hex() > 6,
    " ]");
assert(str2 == "[..0xfa / ..0xfb / ..0xfc]");4.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 split_pos function specifies how many arguments
go before the fill when the operator% is used.
str = strf::to_string
    ( strf::join('a', 'b', 'c', 'd', 'e', 'f').split_pos(2) % 10 );
assert(str == "ab    cdef");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, split, center};
/* ... */ join_align( std::int16_t width
                    , text_alignment align
                    , char32_t fillchar = U' '
                    , std::ptrdiff_t split_pos = 0 );
/* ... */ join_center(int width, char32_t fillchar = U' ');
/* ... */ join_left(int width, char32_t fillchar = U' ');
/* ... */ join_right(int width, char32_t fillchar = U' ');
/* ... */ join_split(int width, int split_pos);
/* ... */ join_split( std::int16_t width
                    , char32_t fillchar
                    , std::ptrdiff_t split_pos );
}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....---");
str = strf::to_string
    ( "---"
    , strf::join_split(15, '.', 1) (strf::left("abc", 5), "def", 123)
    , "---" );
assert(str == "---abc  ....def123---");4.9. Facets
It is possible to override facets to only a subset of the input arguments.
namespace strf {
template < typename FPack >
class inner_pack
{
public:
    template <typename... Args>
    /*...*/  operator()(const Args&... args) const;
    //...
};
template <typename ... Facets>
inner_pack</*...*/> with(const Facets&... facets);auto str = strf::to_string.with(strf::numpunct<10>(1))
    ( 10000
    , "  "
    , strf::hex(0x10000)
    , strf::with( strf::numpunct<10>(3)
                , strf::numpunct<16>(4).thousands_sep('\'') )
        ( "  { "
        , 10000
        , "  "
        , strf::hex(0x10000)
        , " }" ) );
assert(str == "1,0,0,0,0  10000  { 10,000  1'0000 }");auto fp = strf::pack
    ( strf::numpunct<10>(3)
    , strf::numpunct<16>(4).thousands_sep('\'') );
auto str = strf::to_string.with(strf::numpunct<10>(1))
    ( 10000
    , "  "
    , strf::hex(0x10000)
    , strf::with(fp)
        ( "  { "
        , 10000
        , "  "
        , strf::hex(0x10000)
        , strf::with
            (strf::numpunct<10>(2).thousands_sep('.'))
            ("  { ", 10000, " }")
        , " }" ) );
assert(str == "1,0,0,0,0  10000  { 10,000  1'0000  { 1.00.00 } }");5. Destination types
The destination_no_reserve, destination_reserve_calc and
destination_with_given_size class templates provide the
basic usage syntax of the library:
- 
no_reserve()always returns adestination_no_reserveobject
- 
reserve_calc()always returns adestination_reserve_calcobject.
- 
reserve(size)always returns adestination_with_given_sizeobject.
- 
The destination is an object whose type is an instance of one those three class templates. 
5.1. Class template destination_no_reserve
template <typename OutbuffCreator, typename FPack = facets_pack<>>
class destination_no_reserve- Compile-time requirements
- 
- 
FPackis an instance offacets_pack.
- 
OutbuffCreatorsatisfies OutbuffCreator.
 
- 
Synopsis
namespace strf {
template <typename OutbuffCreator, typename FPack>
class destination_no_reserve
{
public:
    using char_type = typename OutbuffCreator::char_type;
    // constructors
    template <typename... Args>
    constexpr destination_no_reserve(Args&&...);
    constexpr destination_no_reserve(const destination_no_reserve&);
    constexpr destination_no_reserve(destination_no_reserve&&);
    // facets
    template <typename... FPE>
    destination_no_reserve<OutbuffCreator, /*...*/> with(FPE&&...) const &;
    template <typename... FPE>
    destination_no_reserve<OutbuffCreator, /*...*/> with(FPE&&...) &&;
    // size reserve
    constexpr destination_calc_size<OutbuffCreator, FPack>
    reserve_calc() const &;
    constexpr destination_calc_size<OutbuffCreator, FPack>
    reserve_calc() &&;
    constexpr destination_with_given_size<OutbuffCreator, FPack>
    reserve(std::size_t) const &;
    constexpr destination_with_given_size<OutbuffCreator, FPack>
    reserve(std::size_t) &&;
    constexpr destination_no_reserve&  no_reserve() &;
    constexpr destination_no_reserve&& no_reserve() &&;
    constexpr const destination_no_reserve&  no_reserve() const &;
    constexpr const destination_no_reserve&& no_reserve() const &&;
    // printing
    template <typename... Args>
    /*...*/ operator()(const Args&...) const;
    template <typename... Args>
    /*...*/ tr(const char_type*, const Args&...) const;
    template <typename... Args>
    /*...*/ tr( const std::basic_string_view<char_type>&
              , const Args&...) const;
    template <typename... Args>
    /*...*/ tr( std::basic_string_view<char_type>
              , const Args&...) const;
private:
    OutbuffCreator _outbuff_creator; // exposition only
    FPack _fpack;                    // exposition only
};
} // namespace strfPublic member functions
Constructors
template <typename... Args>
constexpr destination_no_reserve(Args&&... args);- Compile-time requirements
- 
- 
FPackis DefaultConstructible
- 
std::is_constructible<OutbuffCreator, Args...>istrue, otherwise this constructor does not participate on overload resolution.
 
- 
- Effect
- 
- 
Initializes _outbuff_creatorwithstd::forward<Args>(args)....
 
- 
constexpr destination_no_reserve(const destination_no_reserve&) = default;Copy constructor.
- Compile-time requirements
- 
- 
FPackandOutbuffCreatorare CopyConstructible
 
- 
constexpr destination_no_reserve(destination_no_reserve&&) = default;Move constructor.
Facets
template <typename... FPE>
/* see below */ with(FPE&&...) const &;- Compile-time requirements
- 
- 
All types in FPE...satisfy FacetsPackElement.
- 
OutbuffCreatoris CopyConstructible
 
- 
- Return Type
- 
destination_no_reserve< OutbuffCreator , decltype(pack( std::declval<const FPack&>() , std::forward<FPE>(fpe)...) ) >
- Effect
- 
Creates a destination_no_reserveobject whose_outbuff_creatoris initialized with this_outbuff_creator, and whose_fpackis initialized withpack(this->_fpack, std::forward<FPE>(fpe)...)
template <typename... FPE>
/* see below */ with(FPE&&...) &&;- Compile-time requirements
- 
- 
All types in FPE...satisfy FacetsPackElement.
- 
OutbuffCreatoris MoveConstructible
 
- 
- Return Type
- 
destination_no_reserve< OutbuffCreator , decltype(pack( std::declval<const FPack&>() , std::forward<FPE>(fpe)...) ) >
- Effect
- 
Creates an destination_no_reserveobject whose_outbuff_creatoris initialized withstd::move(_outbuff_creator), and whose_fpackis initialized withpack(std::move(this->_fpack), std::forward<FPE>(fpe)...)
Size reserve
constexpr destination_calc_size<OutbuffCreator, FPack> reserve_calc() const &;- Compile-time requirements
- 
- 
OutbuffCreatoris CopyConstructible and SizedOutbuffCreator.
- 
FPackis CopyConstructible.
 
- 
- Effect
- 
Creates an destination_calc_sizeobject whose_outbuff_creatoris initialized with this_outbuff_creator, and whose_fpackis initialized with this_fpack.
constexpr destination_calc_size<OutbuffCreator, FPack> reserve_calc() &&;- Compile-time requirements
- 
- 
OutbuffCreatoris MoveConstructible and SizedOutbuffCreator.
- 
FPackis CopyConstructible.
 
- 
- Effect
- 
Creates an destination_calc_sizeobject whose_outbuff_creatoris initialized withstd::move(_outbuff_creator)from this object, and whose_fpackobject is initialized withstd::move(_fpack)from this object.
constexpr destination_with_given_size<OutbuffCreator, FPack>
reserve(std::size_t size) const &;- Compile-time requirements
- 
- 
OutbuffCreatoris CopyConstructible and SizedOutbuffCreator.
- 
FPackis CopyConstructible.
 
- 
- Effect
- 
Creates an destination_with_given_sizewhose_sizeis initialized withsize, whose_outbuff_creatoris initialized with this_outbuff_creator, and whose_fpackis initialized with this_fpack.
constexpr destination_with_given_size<OutbuffCreator, FPack>
reserve(std::size_t size) &&;- Compile-time requirements
- 
OutbuffCreatoris MoveConstructible and SizedOutbuffCreator.- 
FPackis CopyConstructible.
 
- 
- Effect
- 
Creates an destination_with_given_sizeobject whose_sizeis initialized withsize, whose_outbuff_creatoris initialized withstd::move(_outbuff_creator) from this object, and whose `_fpackis initialized withstd::move(_fpack)from this object.
constexpr destination_no_reserve&  no_reserve() &;
constexpr destination_no_reserve&& no_reserve() &&;
constexpr const destination_no_reserve&  no_reserve() const &;
constexpr const destination_no_reserve&& no_reserve() const &&;| Effect | None. | 
| Return | This object. | 
Printing
template <typename... Args>
/*...*/ operator()(const Args&... args) const;- Compile-time requirements
- 
- 
All types in Args...are Printable.
 
- 
- Effect
- 
- 
Creates the outbuff object doing typename OutbuffCreator::outbuff_type ob{_outbuff_creator.create()};
- 
For each arginargs..., doesusing preview_type = print_preview<preview_size::no, preview_width::no>; preview_type preview; using printer_type = printer_type<char_type, preview_type, FPack, Arg>; printer_type p{ make_printer_input<char_type>(preview, _fpack, arg) }; static_cast<const printer<char_type>&>(p).print_to(ob);where Argis the type inArgs...corresponding toarg
- 
Returns ob.finish()if such expression is valid, which is optional. Otherwise the return type isvoid.
 
- 
template <typename … Args>
/*...*/ tr( const char_type* tr_string
          , const Args&... args) const;
template <typename … Args>
/*...*/ tr( const std::basic_string_view<char_type>& tr_string
          , const Args&... args) const;
template <typename … Args>
/*...*/ tr( std::basic_string_view<char_type> tr_string
          , const Args&... args) const;- Compile-time requirements
- 
- 
All types in Args...are Printable.
 
- 
- Effect
- 
to-do 
5.2. Class template destination_calc_size
template <typename SizedOutbuffCreator, typename FPack = facets_pack<>>
class destination_calc_size;- Compile-time requirements
- 
- 
FPackis an instance offacets_pack.
- 
SizedOutbuffCreatorsatisfies SizedOutbuffCreator.
 
- 
Synopsis
namespace strf {
template <typename SizedOutbuffCreator, typename FPack>
class destination_reserve_calc
{
public:
    using char_type = typename SizedOutbuffCreator::char_type;
    // constructors
    template <typename... Args>
    constexpr destination_reserve_calc(Args&&...);
    constexpr destination_reserve_calc(const destination_reserve_calc&) = default;
    constexpr destination_reserve_calc(destination_reserve_calc&&) = default;
    // facets
    template <typename... FPE>
    destination_reserve_calc<SizedOutbuffCreator, /*...*/> with(FPE&&...) const &;
    template <typename... FPE>
    destination_reserve_calc<SizedOutbuffCreator, /*...*/> with(FPE&&...) &&;
    // size reserve
    constexpr destination_no_reserve<SizedOutbuffCreator, FPack>
    no_reserve() const &;
    constexpr destination_no_reserve<SizedOutbuffCreator, FPack>
    no_reserve() &&;
    constexpr destination_with_given_size<SizedOutbuffCreator, FPack>
    reserve(std::size_t) const &;
    constexpr destination_with_given_size<SizedOutbuffCreator, FPack>
    reserve(std::size_t) &&;
    constexpr destination_reserve_calc&  reserve_calc() &;
    constexpr destination_reserve_calc&& reserve_calc() &&;
    constexpr const destination_reserve_calc&  reserve_calc() const &;
    constexpr const destination_reserve_calc&& reserve_calc() const &&;
    // printing
    template <typename... Args>
    /*...*/ operator()(const Args&...) const;
    template <typename... Args>
    /*...*/ tr(const char_type*, const Args&...) const;
    template <typename... Args>
    /*...*/ tr(const std::basic_string<char_type>&, const Args&...) const;
    template <typename... Args>
    /*...*/ tr(std::basic_string_view<char_type>, const Args&...) const;
private:
    OutbuffCreator _outbuff_creator; // exposition only
    FPack _fpack;                    // exposition only
};
} // namespace strfConstructors
template <typename... Args>
constexpr destination_reserve_calc(Args&&... args);- Compile-time requirements
- 
- 
FPackis DefaultConstructible
- 
std::is_constructible<OutbuffCreator, Args...>::valueistrue, otherwise this constructor does not participate on overload resolution.
 
- 
- Effect
- 
- 
Initializes _outbuff_creatorwithstd::forward<Args>(args)....
 
- 
constexpr destination_reserve_calc(const destination_reserve_calc&) = default;Copy constructor.
- Compile-time requirements
- 
- 
FPackandOutbuffCreatorare CopyConstructible
 
- 
constexpr destination_reserve_calc(destination_reserve_calc&&) = default;Move constructor.
Facets
template <typename... FPE>
/* see below */ with(FPE&&...) const &;- Compile-time requirements
- 
- 
All types in FPE...satisfy FacetsPackElement.
- 
OutbuffCreatoris CopyConstructible
 
- 
- Return Type
- 
destination_reserve_calc< OutbuffCreator , decltype(pack( std::declval<const FPack&>() , std::forward<FPE>(fpe)...) ) >
- Effect
- 
Creates an destination_reserve_calcobject whose_outbuff_creatoris initialized with this_outbuff_creator, and whose_fpackis initialized withpack(this->_fpack, std::forward<FPE>(fpe)...)
template <typename... FPE>
/* see below */ with(FPE&&...) &&;- Compile-time requirements
- 
- 
All types in FPE...satisfy FacetsPackElement.
- 
OutbuffCreatoris MoveConstructible
 
- 
- Return Type
- 
destination_reserve_calc< OutbuffCreator , decltype(pack( std::declval<const FPack&>() , std::forward<FPE>(fpe)...) ) >
- Effect
- 
Creates an destination_reserve_calcobject whose_outbuff_creatoris initialized withstd::move(this->_outbuff_creator), and whose_fpackis initialized withpack(std::move(this->_fpack), std::forward<FPE>(fpe)...)
Size reserve
constexpr destination_no_reserve<OutbuffCreator, FPack> no_reserve() const &;- Compile-time requirements
- 
- 
OutbuffCreatoris CopyConstructible
- 
FPackis CopyConstructible.
 
- 
- Effect
- 
Creates an destination_no_reserveobject whose_outbuff_creatoris initialized with this_outbuff_creator, and whose_fpackis initialized with this_fpack.
constexpr destination_calc_size<OutbuffCreator, FPack> reserve_calc() &&;- Compile-time requirements
- 
- 
OutbuffCreatoris MoveConstructible
- 
FPackis CopyConstructible.
 
- 
- Effect
- 
Creates an destination_no_reserveobject whose_outbuff_creatoris initialized withstd::move(_outbuff_creator)from this object, and whose_fpackobject is initialized withstd::move(_fpack)from this object.
constexpr destination_with_given_size<OutbuffCreator, FPack>
reserve(std::size_t size) const &;- Compile-time requirements
- 
- 
OutbuffCreatoris CopyConstructible and SizedOutbuffCreator.
- 
FPackis CopyConstructible.
 
- 
- Effect
- 
Creates an destination_with_given_sizewhose_sizeis initialized withsize, whose_outbuff_creatoris initialized with this_outbuff_creator, and whose_fpackis initialized with this_fpack.
constexpr destination_with_given_size<OutbuffCreator, FPack>
reserve(std::size_t) &&;- Compile-time requirements
- 
OutbuffCreatoris MoveConstructible and SizedOutbuffCreator.- 
FPackis CopyConstructible.
 
- 
- Effect
- 
Creates an destination_with_given_sizeobject whose_sizeis initialized withsize, whose_outbuff_creatoris initialized withstd::move(_outbuff_creator) from this object, and whose `_fpackis initialized withstd::move(_fpack)from this object.
constexpr destination_reserve_calc&  reserve_calc() &;
constexpr destination_reserve_calc&& reserve_calc() &&;
constexpr const destination_reserve_calc&  reserve_calc() const &;
constexpr const destination_reserve_calc&& reserve_calc() const &&;| Effect | None. | 
| Return | This object. | 
Printing
template <typename... Args>
/*...*/ operator()(const Args&... args) const;- Compile-time requirements
- 
- 
All types in Args...are Printable.
 
- 
- Effect
- 
- 
Creates an object previewof typeprint_preview<preview_size::yes, preview_width::no>.using preview_type = print_preview<preview_size::yes, preview_width::no>; preview_type preview;
- 
For each arginargs..., creates a printer object by doing:using printer_type = printer_type<char_type, preview_type, FPack, Arg>; printer_type p{ make_printer_input<char_type>(preview, _fpack, arg) };
- 
Creates/get the outbuff object doing using ob_type = typename OutbuffCreator::size_outbuf_type; ob_type ob{_outbuff_creator.create(preview.get_size())};
- 
For each pobject does:static_cast<const printer<char_type>&>(p).print_to(ob);
- 
Returns ob.finish()if such expression is valid, which is optional. Otherwise the return type isvoid.
 
- 
template <typename … Args>
/*...*/ tr( const char_type* tr_string
          , const Args&... args) const;
template <typename … Args>
/*...*/ tr( const std::basic_string_view<char_type>& tr_string
          , const Args&... args) const;
template <typename … Args>
/*...*/ tr( std::basic_string_view<char_type> tr_string
          , const Args&... args) const;- Compile-time requirements
- 
- 
All types in Args...are Printable.
 
- 
- Effect
- 
to-do 
5.3. Class template destination_with_given_size
template <typename SizedOutbuffCreator, typename FPack = facets_pack<>>
class destination_with_given_size- Compile-time requirements
- 
- 
FPackis an instance offacets_pack.
- 
SizedOutbuffCreatorsatisfies SizedOutbuffCreator.
 
- 
Synopsis
namespace strf {
template <typename SizedOutbuffCreator, typename FPack>
class destination_with_given_size
{
public:
    using char_type = typename SizedOutbuffCreator::char_type;
    // constructors
    template <typename... Args>
    constexpr destination_with_given_size(std::size_t, Args&&...);
    constexpr destination_with_given_size(const destination_with_given_size&) = default;
    constexpr destination_with_given_size(destination_with_given_size&&) = default;
    // facets
    template <typename... FPE>
    destination_with_given_size<SizedOutbuffCreator, /*...*/> with(FPE&&...) const &;
    template <typename... FPE>
    destination_with_given_size<SizedOutbuffCreator, /*...*/> with(FPE&&...) &&;
    // size reserve
    constexpr destination_calc_size<SizedOutbuffCreator, FPack>
    reserve_calc() const &;
    constexpr destination_calc_size<SizedOutbuffCreator, FPack>
    reserve_calc() &&;
    constexpr destination_no_reserve<SizedOutbuffCreator, FPack>
    no_reserve() const &;
    constexpr destination_no_reserve<SizedOutbuffCreator, FPack>
    no_reserve() &&;
    constexpr destination_with_given_size&  reserve(std::size_t) &;
    constexpr destination_with_given_size&& reserve(std::size_t) &&;
    constexpr destination_with_given_size   reserve(std::size_t) const &;
    constexpr destination_with_given_size   reserve(std::size_t) const &&;
    // printing
    template <typename... Args>
    /*...*/ operator()(const Args&...) const;
    template <typename... Args>
    /*...*/ tr(const char_type*, const Args&...) const;
    template <typename... Args>
    /*...*/ tr(const std::basic_string<char_type>&, const Args&...) const;
    template <typename... Args>
    /*...*/ tr(std::basic_string_view<char_type>, const Args&...) const;
private:
    std::size_t _size              // exposition only
    OutbuffCreator _outbuff_creator; // exposition only
    FPack _fpack;                  // exposition only
};
} // namespace strfConstructors
template <typename... Args>
constexpr destination_with_given_size(std::size_t size, Args&&... args);- Compile-time requirements
- 
- 
FPackis DefaultConstructible
- 
std::is_constructible<OutbuffCreator, Args...>, otherwise this constructor does not participate on overload resolution.
 
- 
- Effect
- 
- 
Initializes _outbuff_creatorwithstd::forward<Args>(args)....
- 
Initializes _sizewithsize
 
- 
constexpr destination_with_given_size(const destination_with_given_size&) = default;Copy constructor.
- Compile-time requirements
- 
- 
FPackandOutbuffCreatorare CopyConstructible
 
- 
constexpr destination_with_given_size(destination_with_given_size&&) = default;Move constructor.
Facets
template <typename... FPE>
/* see below */ with(FPE&&...) const &;- Compile-time requirements
- 
- 
All types in FPE...satisfy FacetsPackElement.
- 
OutbuffCreatoris CopyConstructible
 
- 
- Return Type
- 
destination_with_given_size< OutbuffCreator , decltype(pack( std::declval<const FPack&>() , std::forward<FPE>(fpe)...) ) >
- Effect
- 
Creates an destination_with_given_sizeobject whose_sizeis is initialized with this_size, whose_outbuff_creatoris initialized with this_outbuff_creator, and whose_fpackis initialized withpack(this->_fpack, std::forward<FPE>(fpe)...)
template <typename... FPE>
/* see below */ with(FPE&&...) &&;- Compile-time requirements
- 
- 
All types in FPE...satisfy FacetsPackElement.
- 
OutbuffCreatoris MoveConstructible
 
- 
- Return Type
- 
destination_with_given_size< OutbuffCreator , decltype(pack( std::declval<const FPack&>() , std::forward<FPE>(fpe)...) ) >
- Effect
- 
Creates an destination_with_given_sizeobject whose_sizeis is initialized with this_size, whose_outbuff_creatoris initialized withstd::move(_outbuff_creator)from this object , and whose_fpackis initialized withpack(std::move(this->_fpack), std::forward<FPE>(fpe)...)
Size reserve
constexpr destination_no_reserve<OutbuffCreator, FPack> no_reserve() const &;- Compile-time requirements
- 
- 
OutbuffCreatoris CopyConstructible
- 
FPackis CopyConstructible.
 
- 
- Effect
- 
Creates an destination_no_reserveobject whose_outbuff_creatoris initialized with this_outbuff_creator, and whose_fpackis initialized with this_fpack.
constexpr destination_calc_size<OutbuffCreator, FPack> no_reserve() &&;- Compile-time requirements
- 
- 
OutbuffCreatoris MoveConstructible
- 
FPackis CopyConstructible.
 
- 
- Effect
- 
Creates an destination_no_reserveobject whose_outbuff_creatoris initialized withstd::move(_outbuff_creator)from this object, and whose_fpackobject is initialized withstd::move(_fpack)from this object.
constexpr destination_calc_size<OutbuffCreator, FPack> reserve_calc() const &;- Compile-time requirements
- 
- 
OutbuffCreatoris CopyConstructible and SizedOutbuffCreator.
- 
FPackis CopyConstructible.
 
- 
- Effect
- 
Creates an destination_calc_sizeobject whose_outbuff_creatoris initialized with this_outbuff_creator, and whose_fpackis initialized with this_fpack.
constexpr destination_calc_size<OutbuffCreator, FPack> reserve_calc() &&;- Compile-time requirements
- 
- 
OutbuffCreatoris MoveConstructible and SizedOutbuffCreator.
- 
FPackis CopyConstructible.
 
- 
- Effect
- 
Creates an destination_calc_sizeobject whose_outbuff_creatoris initialized withstd::move(_outbuff_creator)from this object, and whose_fpackobject is initialized withstd::move(_fpack)from this object.
constexpr destination_with_given_size&  reserve(std::size_t size) &;
constexpr destination_with_given_size&& reserve(std::size_t size) &&;| Effect | assign  | 
| Return | This object. | 
constexpr destination_with_given_size reserve(std::size_t size) const &;
constexpr destination_with_given_size reserve(std::size_t size) const &&;| Effect | Creates an  | 
Printing
template <typename... Args>
/*...*/ operator()(const Args&... args) const;- Compile-time requirements
- 
- 
All types in Args...are Printable.
 
- 
- Effect
- 
- 
Creates/get the outbuff object doing decltype(auto) ob = _outbuff_creator.create(_size)
- 
For each arginargs...does:using preview_type = print_preview<preview_size::no, preview_width::no>; preview_type preview; using printer_type = printer_type<char_type, preview_type, FPack, Arg>; printer_type p{ make_printer_input<char_type>(preview, _fpack, arg) }; static_cast<const printer<char_type>&>(p).print_to(ob);, where Argis the type inArgs...corresponding toarg
- 
Returns ob.finish()if such expression is valid, which is optional. Otherwise the return type isvoid.
 
- 
template <typename … Args>
/*...*/ tr( const char_type* tr_string
          , const Args&... args) const;
template <typename … Args>
/*...*/ tr( const std::basic_string_view<char_type>& tr_string
          , const Args&... args) const;
template <typename … Args>
/*...*/ tr( std::basic_string_view<char_type> tr_string
          , const Args&... args) const;- Compile-time requirements
- 
- 
All types in Args...are Printable.
 
- 
- Effect
- 
to-do 
5.4. Type requirement OutbuffCreator
Given
- 
char_type, a character type
- 
X, an OutbuffCreator type forchar_type
- 
x, an expression of typeXorconst X
The following must hold:
- 
Xis CopyConstructible
- 
Xhas a member type aliasX::char_typedefined aschar_type
- 
Xhas theX::outbuff_typethat is a type alias to a concrete type that is derives frombasic_outbuff<X::char_type>
And the following expression must be satisfied:
typename X::outbuff_type{x.create()}5.5. Type requirement SizedOutbuffCreator
Given
- 
char_type, a character type
- 
size, a value of thestd::size_t
- 
X, an OutbuffCreator type forchar_type
- 
x, an expression of typeXorconst X
The following must hold:
- 
Xis CopyConstructible
- 
Xhas a member type aliasT::char_typedefined aschar_type
- 
Xhas theX::size_outbuff_typethat is a type alias to a concrete type that is derives frombasic_outbuff<X::char_type>
And the following expression must be satisfied:
typename X::sized_outbuff_type{x.create(size)}| Return type | A type that derives from  | 
| Postcondition | 
 | 
6. Tr-String
6.1. Syntax
| A '{'followed by | until | means | 
|---|---|---|
| 
 | the next  | a comment | 
| a digit | the next  | a positional argument reference | 
| another  | the second  | an escaped  | 
| any other character | the next  | a non positional argument reference | 
Examples:
auto str = strf::to_string.tr
    ( "You can learn more about python{-the programming language, not the reptile} at {}"
    , "www.python.org" );
assert(str == "You can learn more about python at www.python.org");auto str = strf::to_string.tr("{1 a person} likes {0 a food type}.", "sandwich", "Paul");
assert(str == "Paul likes sandwich.");auto str = strf::to_string.tr("{a person} likes {a food type}.", "Paul", "sandwich");
assert(str == "Paul likes sandwich.");auto str = strf::to_string.tr("} {{x} {{{} {{{}}", "aaa", "bbb");
assert(str == "} {x} {aaa {bbb}");Syntax error handling
When the argument associated with a "{" does not exists, the library does two things:
- 
It prints a replacement character "\uFFFD"(�) ( or"?"when the encoding can’t represent it ) where the missing argument would be printed.
- 
It calls the handlefunction on the facet object correspoding to thetr_error_notifier_ccategory.
6.2. 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 strfStruct 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 CharEncoding>
    void handle
        ( const typename CharEncoding::char_type* str
        , std::size_t str_len
        , std::size_t err_pos
        , CharEncoding enc ) noexcept
    {
    }
};
} // namespace strfType requirement TrErrorHandling
Given:
- 
X, a TrErrorHandling type
- 
x, a value of typeX
- 
Enc, a CharEncoding type.
- 
enc, a value of typeEnc
- 
str, a value of typeconst Enc::char_type*pointing to string encoded according toenc
- 
str_len, astd::size_tvalue equal to the length of the stringstr
- 
err_pos, astd::size_tvalue less than or equal tostr_len
The following must host:
- 
Xis CopyConstructible.
- 
X::categoryis a type alias totr_error_notifier_c
- 
The following expression is supported: 
x.handle(str, str_len, err_pos, enc)| Semantics | 
 | 
7. Character encodings
7.1. Enumeration char_encoding_id
namespace strf {
enum class char_encoding_id : unsigned { };
constexpr char_encoding_id  eid_ascii        = /* ... */;
constexpr char_encoding_id  eid_utf8         = /* ... */;
constexpr char_encoding_id  eid_utf16        = /* ... */;
constexpr char_encoding_id  eid_utf32        = /* ... */;
constexpr char_encoding_id  eid_iso_8859_1   = /* ... */;
constexpr char_encoding_id  eid_iso_8859_3   = /* ... */;
constexpr char_encoding_id  eid_iso_8859_15  = /* ... */;
constexpr char_encoding_id  eid_windows_1252 = /* ... */;
} // namespace strf7.2. Facet category invalid_seq_notifier_c
namespace strf {
struct invalid_seq_notifier_c {
    static constexpr bool constrainable = false;
    static constexpr invalid_seq_notifier get_default() noexcept {
        return {}
    }
};
} // namespace strfClass invalid_seq_notifier
namespace strf {
class invalid_seq_notifier {
public:
    using category = invalid_seq_notifier_c;
    typedef void(*notify_fptr)();
    constexpr invalid_seq_notifier() noexcept = default;
    constexpr invalid_seq_notifier(const invalid_seq_notifier&) noexcept = default;
    constexpr explicit invalid_seq_notifier(notify_fptr) noexcept;
    constexpr invalid_seq_notifier& operator=(notify_fptr) noexcept;
    constexpr invalid_seq_notifier& operator=(const invalid_seq_notifier& other) noexcept;
    constexpr bool operator==(const invalid_seq_notifier& other) noexcept;
    constexpr operator bool() const noexcept;
    constexpr void notify() const noexcept;
private:
    notify_fptr notify_func_ = nullptr; // exposition only
};
} // namespace strfconstexpr invalid_seq_notifier() noexcept;Trivial default constructor
| Poscondition | 
 | 
constexpr invalid_seq_notifier(const invalid_seq_notifier& other) noexcept;Trivial copy constructor
| Poscondition | 
 | 
constexpr explicit invalid_seq_notifier(notify_fptr fptr) noexcept;| Poscondition | 
 | 
constexpr invalid_seq_notifier& operator=(const invalid_seq_notifier& other) noexcept;| Poscondition | 
 | 
constexpr bool operator==(const invalid_seq_notifier& other) noexcept;| Return value | 
 | 
constexpr operator bool() const noexcept;| Return value | 
 | 
constexpr void notify() const noexcept;| Effect | Calls  | 
7.3. Facet category surrogate_policy_c
enum class surrogate_policy : bool { strict = false, lax = true };
struct surrogate_policy_c {
    static constexpr bool constrainable = false;
    static constexpr surrogate_policy get_default() noexcept {
        return surrogate_policy::strict;
    }
};
template <>
class facet_traits<surrogate_policy> {
public:
    using category = surrogate_policy_c;
    static constexpr bool store_by_value = true;
};Semantics
This facet enables you to choose whether a nonconformant presence of a surrogate character shall be treated as invalid.
7.4. Facet category template char_encoding_c
namespace strf {
template <typename CharT>
struct char_encoding_c {
    static constexpr bool constrainable = false;
    static constexpr utf<CharT> get_default() noexcept;
};
template <typename CharT, char_encoding_id CEId>
struct facet_traits<static_char_encoding<CharT, CEId>>
{
    using category = char_encoding_c<CharT>;
};
template <typename CharT>
struct facet_traits<dynamic_char_encoding<CharT>>
{
    using category = char_encoding_c<CharT>;
};
} // namespace strfFor a type to be a facet of char_encoding_c<CharT> it has
to be a CharEncoding type for CharT. The library provides
two class templates that satisfy that: static_char_encoding
and dynamic_char_encoding
7.5. Aliases for pointers to functions
constexpr std::size_t invalid_char_len = (std::size_t)-1;
template <typename SrcCharT, typename DestCharT>
using transcode_f = void (*)
    ( basic_outbuff<DestCharT>& ob
    , const SrcCharT* src
    , std::size_t src_size
    , invalid_seq_notifier inv_seq_notifier
    , surrogate_policy surr_poli );
template <typename SrcCharT>
using transcode_size_f = std::size_t (*)
    ( const SrcCharT* src
    , std::size_t src_size
    , surrogate_policy surr_poli );
template <typename CharT>
using write_replacement_char_f = void(*)( basic_outbuff<CharT>& );
using validate_f = std::size_t (*)(char32_t ch);
using encoded_char_size_f = std::size_t (*) (char32_t ch);
template <typename CharT>
using encode_char_f = CharT*(*) (CharT* dest, char32_t ch);
template <typename CharT>
using encode_fill_f = void (*)
    ( basic_outbuff<CharT>&
    , std::size_t count
    , char32_t ch );
struct codepoints_count_result {
    std::size_t count;
    std::size_t pos;
};
template <typename CharT>
using codepoints_fast_count_f = codepoints_count_result (*)
    ( const CharT* src
    , std::size_t src_size
    , std::size_t max_count );
template <typename CharT>
using codepoints_robust_count_f = codepoints_count_result (*)
    ( const CharT* src
    , std::size_t src_size
    , std::size_t max_count
    , surrogate_policy surr_poli );
template <typename CharT>
using decode_char_f = char32_t (*) ( CharT );
template <typename SrcCharT, typename DestCharT>
using find_transcoder_f = dynamic_transcoder<SrcCharT, DestCharT> (*)
    ( char_encoding_id );7.6. Type requirement Transcoder
Given
- 
SrcCharT, one of the types:char,char8_t,char16_t,char32_torwchar_t
- 
DestCharT, one of the types:char,char8_t,char16_t,char32_torwchar_t
- 
X, a Transcoder type fromSrcCharTtoDestCharT
- 
x, an expression of typeXorconst X
- 
dest, an lvalue reference of typebasic_outbuff<DestCharT>
- 
src, a value of typeconst SrcCharT*
- 
src_size, a value of typestd::size_tequal to the size of the array pointed bysrc
- 
inv_seq_notifier, a value of typeinvalid_seq_notifier
- 
surr_poli, a value of typesurrogate_policy
The following must hold:
- 
Xis CopyConstructible.
- 
Xsupports the following syntax and semantics:
x.transcode_size(src, src_size, surr_poli)| Return type | 
 | 
| Return value | The number of character that
 | 
| Precondition | 
 | 
x.transcode(dest, src, src_size, inv_seq_notifier, surr_poli)| Effect | Converts the content of  | 
| Precondition | 
 | 
| Postconditions | 
 | 
x.transcode_size_func()| Return type | 
 | 
| Return value | A function pointer such that
 | 
x.transcode_func()| Return type | 
 | 
| Return value | A function pointer such that
 | 
A null transcoder is an object of an Transcoder
type where the transcode_func function returns nullptr.
| There are two class templates that satisfy Transcoder: static_transcoderanddynamic_transcoder. | 
7.7. Type requirement CharEncoding
Given
- 
CharT, one of the follwoing types:char,char8_t,char16_t,char32_torwchar_t
- 
X, a CharEncoding type for typeCharT
- 
x, an expression of typeXorconst X
- 
OtherCharT, one of the folowing types :char,char8_t,char16_torwchar_t
- 
ptr, a value of typeCharT*
- 
src, a value of typeconst CharT*
- 
src_size, a value of typestd::size_tequal to the size of the array pointed bysrc
- 
count, a value of typestd::size_t
- 
max_count, a value of typestd::size_t
- 
ch32, a value of typechar32_t
- 
ch, a value of typeCharT
- 
ob, an lvalue reference of typebasic_outbuff<CharT>
- 
enc_id, value of typechar_encoding_id
The following must hold:
- 
Xmust be CopyConstructible
- 
facet_category<X>must bechar_encoding_c<CharT>
- 
Xmust satisfy the following syntax and semantics:
X::char_typeType alias to CharT
x.name()| Return type | 
 | 
| Return value | The name of this encoding. Examples:  | 
x.replacement_char()| Return type | 
 | 
| Return value | The character used to signalize an error. Usually it is the replacement character � if it is supported by this encoding, or the question mark  | 
x.write_replacement_char(ob)| Return type | Writes into  | 
x.replacement_char_size()| Return type | 
 | 
| Return value | The number of characters that  | 
x.encoded_char_size(ch32)| Return type | 
 | 
| Return value | The size of the string containing the UTF-32 character  | 
| Note | This function does not check whether  | 
x.validate(ch32)| Return type | 
 | 
| Return value | The size of the string containing the UTF-32 character  | 
x.encode_char(ptr, ch32)| Effect | Writes into  | 
| Return type | 
 | 
| Return value | The position just after the last writen character. | 
| Note | This function does not check whether  | 
x.encode_fill(ob, count, ch32)| Effect | Writes  | 
| Return type | 
 | 
| Note | 
 | 
x.codepoints_fast_count(src, src_size, max_count)| Return type | |
| Return value | 
 
 | 
| Posconditions | 
 | 
| Note | If the input is non-conformant to the corresponding character encoding, this function may return an incorrect value. For instance, for UTF-8 this function may simply count the bytes that are not continuation bytes. | 
x.codepoints_robust_count(src, src_size, max_count, surr_poli)| Effect | Counts the codepoints until is equal to  | 
| Return type | |
| Return value | 
 
 | 
| Posconditions | 
 | 
x.decode_char(ch)| Effect | Decodes  | 
| Return type | 
 | 
x.encode_char_func()| Return type | 
 | 
| Return value | A function pointer such that  | 
x.encode_fill_func()| Return type | 
 | 
| Return value | A function pointer such that  | 
x.write_replacement_char_func()| Return type | 
 | 
| Return value | A function pointer such that  | 
x.from_u32()| Return type | A Transcoder from  | 
| Return value | A transcoder that converts UTF-32 to this encoding. | 
x.to_u32()| Return type | A Transcoder from  | 
| Return value | A transcoder that converts this encoding to UTF-32. | 
x.sanitizer()| Return type | A Transcoder from  | 
| Return value | A transcoder that "converts" this encoding to this encoding, i.e. a sanitizer of this encoding. | 
x.find_transcoder_to(tag<OtherCharT>, enc_id)| Return type | 
 | 
| Return value | A transcoder that converts this encoding to the encoding
corresponding to  | 
x.find_transcoder_from(tag<OtherCharT>, enc_id)| Return type | 
 | 
| Return value | A transcoder that converts the encoding corresponding to
 | 
| You shall not create an CharEncoding for char32_t, sincechar32_tis reserved for UTF-32.
           The library internaly assumes in many occasions that the encoding
           is UTF-32 whenCharTischar32_t. | 
| There are two class templates that satisfy CharEncoding: static_transcoderanddynamic_char_encoding. | 
7.8. Class template static_transcoder
template <char_encoding_id Src, char_encoding_id Dest>
class static_transcoder;
template <> static_transcoder<eid_ascii, eid_ascii>;
template <> static_transcoder<eid_ascii, eid_utf32>;
template <> static_transcoder<eid_utf32, eid_ascii>;
template <> static_transcoder<eid_iso_8859_1, eid_iso_8859_1>;
template <> static_transcoder<eid_iso_8859_1, eid_utf32>;
template <> static_transcoder<eid_utf32, eid_iso_8859_1>;
template <> static_transcoder<eid_iso_8859_3, eid_utf32>;
template <> static_transcoder<eid_utf32, eid_iso_8859_3>;
template <> static_transcoder<eid_iso_8859_3, eid_iso_8859_3>;
template <> static_transcoder<eid_iso_8859_15, eid_iso_8859_15>;
template <> static_transcoder<eid_iso_8859_15, eid_utf32>;
template <> static_transcoder<eid_utf32, eid_iso_8859_15>;
template <> static_transcoder<eid_windows_1252, eid_windows_1252>;
template <> static_transcoder<eid_windows_1252, eid_utf32>;
template <> static_transcoder<eid_utf32, eid_windows_1252>;
template <> static_transcoder<eid_utf8, eid_utf8>;
template <> static_transcoder<eid_utf8, eid_utf16>;
template <> static_transcoder<eid_utf8, eid_utf32>;
template <> static_transcoder<eid_utf16, eid_utf8>;
template <> static_transcoder<eid_utf16, eid_utf16>;
template <> static_transcoder<eid_utf16, eid_utf32>;
template <> static_transcoder<eid_utf32, eid_utf8>;
template <> static_transcoder<eid_utf32, eid_utf16>;
template <> static_transcoder<eid_utf32, eid_utf32>;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.
7.9. Class template static_char_encoding
template <char_encoding_id>
class static_char_encoding;
template <> class static_char_encoding<eid_utf8>;
template <> class static_char_encoding<eid_utf16>;
template <> class static_char_encoding<eid_utf32>;
template <> class static_char_encoding<eid_ascii>;
template <> class static_char_encoding<eid_iso_8859_1>;
template <> class static_char_encoding<eid_iso_8859_3>;
template <> class static_char_encoding<eid_iso_8859_15>;
template <> class static_char_encoding<eid_windows_1252>;static_char_encoding class template has no generic implementation.
Instead, the library provides the template specializations listed above.
All of them are empty classes, and are CharEncoding.
7.10. Class template dynamic_transcoder
namespace strf {
template <typename SrcCharT, typename DestCharT>
class dynamic_transcoder {
public:
    constexpr dynamic_transcoder() noexcept;
    constexpr dynamic_transcoder
        ( const dynamic_transcoder& other) noexcept = default;
    template <char_encoding_id Src, char_encoding_id Dest>
    constexpr explicit dynamic_transcoder
        ( static_transcoder<Src, Dest> st );
    void transcode
        ( basic_outbuff<DestCharT>& ob
        , const SrcCharT* src
        , std::size_t src_size
        , invalid_seq_notifier inv_seq_notifier
        , surrogate_policy surr_poli ) const;
    std::size_t transcode_size
        ( const SrcCharT* src
        , std::size_t src_size
        , surrogate_policy surr_poli ) const;
    constexpr transcode_f<SrcCharT, DestCharT> transcode_func() const noexcept;
    constexpr transcode_size_f<SrcCharT> transcode_size_func() const noexcept;
};
} // namespace strfconstexpr dynamic_transcoder() noexcept;Default constructor
| Postconditions | 
 | 
constexpr dynamic_transcoder
    ( const dynamic_transcoder& other) noexcept;Trivial copy constructor
| Postconditions | 
 | 
template <char_encoding_id Src, char_encoding_id Dest>
constexpr explicit dynamic_transcoder
    ( static_transcoder<Src, Dest> other );| Postconditions | 
 | 
void transcode
    ( basic_outbuff<DestCharT>& ob
    , const SrcCharT* src
    , std::size_t src_size
    , invalid_seq_notifier inv_seq_notifier
    , surrogate_policy surr_poli ) const;Effect: Calls transcode_func()(ob, src, src_size, inv_seq_notifier, surr_poli)
std::size_t transcode_size
    ( const SrcCharT* src
    , std::size_t src_size
    , surrogate_policy surr_poli ) const;Effect: Calls transcode_size_func()(src, src_size, surr_poli)
7.11. Struct template dynamic_char_encoding_data
template <typename CharT>
struct dynamic_char_encoding_data {
    const char* name;
    char_encoding_id id;
    char32_t replacement_char;
    std::size_t 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;
    codepoints_fast_count_f<CharT> codepoints_fast_count_func;
    codepoints_robust_count_f<CharT> codepoints_robust_count_func;
    write_replacement_char_f<CharT> write_replacement_char_func;
    decode_char_f<CharT> decode_char_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
};7.12. Class template dynamic_char_encoding
template <typename CharT>
class dynamic_char_encoding {
public:
    using char_type = CharT;
    dynamic_char_encoding(const dynamic_char_encoding& other) = default;
    dynamic_char_encoding
        ( const dynamic_char_encoding_data<CharT>& d );
    dynamic_char_encoding& operator=(const dynamic_char_encoding& other) noexcept;
    bool operator==(const dynamic_char_encoding& other) const noexcept;
    bool operator!=(const dynamic_char_encoding& other) const noexcept;
    void swap(dynamic_char_encoding& other) noexcept;
    const char* name() const noexcept;
    constexpr char_encoding_id id() const noexcept;
    constexpr char32_t replacement_char() const noexcept;
    constexpr std::size_t replacement_char_size() const noexcept;
    constexpr std::size_t validate(char32_t ch) const; // noexcept
    constexpr std::size_t encoded_char_size(char32_t ch) const; // noexcept
    char_type_* encode_char(char_type_* dest, char32_t ch) const; // noexcept
    void encode_fill
        ( basic_outbuff<CharT>& ob, std::size_t count, char32_t ch ) const;
    std::size_t codepoints_fast_count
        ( const char_type_* src, std::size_t src_size
        , std::size_t max_count ) const;
    std::size_t codepoints_robust_count
        ( const char_type_* src, std::size_t src_size
        , std::size_t max_count, surrogate_policy surr_poli ) const;
    void write_replacement_char(basic_outbuff<CharT>& ob) const;
    char32_t decode_char(char_type_ 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>, char_encoding_id id) const;
    dynamic_transcoder<wchar_t, CharT> find_transcoder_from
        ( tag<wchar_t>, char_encoding_id id) const;
    dynamic_transcoder<CharT, char16_t> find_transcoder_to
        ( tag<char16_t>, char_encoding_id id) const;
    dynamic_transcoder<char16_t, CharT> find_transcoder_from
        ( tag<char16_t>, char_encoding_id id) const;
    dynamic_transcoder<CharT, char> find_transcoder_to
        ( tag<char>, char_encoding_id id) const;
    dynamic_transcoder<char, CharT> find_transcoder_from
        ( tag<char>, char_encoding_id id) const;
#if defined (__cpp_char8_t)
    dynamic_transcoder<CharT, char8_t> find_transcoder_to
        ( tag<char8_t>, char_encoding_id id) const;
    dynamic_transcoder<char8_t, CharT> find_transcoder_from
        ( tag<char8_t>, char_encoding_id id) const;
#endif
private:
    const dynamic_char_encoding_data* data; // exposition only
};dynamic_char_encoding(const dynamic_char_encoding& other);Trivial copy constructor.
| Effect | 
 | 
dynamic_char_encoding
        ( const dynamic_char_encoding_data<CharT>& d );| Effect | 
 | 
dynamic_char_encoding& operator=(const dynamic_char_encoding& other) noexcept| Effect | 
 | 
bool operator==(const dynamic_char_encoding& other) const noexcept;| Return value | 
 | 
bool operator!=(const dynamic_char_encoding& other) const noexcept;| Return value | 
 | 
void swap(dynamic_char_encoding& other) noexcept;| Effect | Same as  | 
const char* name() const noexcept;| Return value | 
 | 
constexpr char_encoding_id id() const noexcept;| Return value | 
 | 
constexpr char32_t replacement_char() const noexcept;| Return value | 
 | 
constexpr std::size_t replacement_char_size() const noexcept;| Return value | 
 | 
constexpr std::size_t validate(char32_t ch) const; // noexcept| Effect | Calls and returns  | 
constexpr std::size_t encoded_char_size(char32_t ch) const; // noexcept| Effect | Calls and returns  | 
char_type_* encode_char(char_type_* dest, char32_t ch) const; // noexcept| Effect | Calls and returns  | 
void encode_fill
    ( basic_outbuff<CharT>& ob, std::size_t count, char32_t ch ) const;| Effect | Calls and returns
 | 
std::size_t codepoints_fast_count
    ( const char_type_* src, std::size_t src_size
    , std::size_t max_count ) const;| Effect | Calls and returns  | 
std::size_t codepoints_robust_count
    ( const char_type_* src, std::size_t src_size
    , std::size_t max_count, surrogate_policy surr_poli ) const;| Effect | Calls and returns
 | 
void write_replacement_char(basic_outbuff<CharT>& ob) const;| Effect | Calls  | 
char32_t decode_char(char_type_ ch) const;| Effect | Calls and returns  | 
encode_char_f<CharT> encode_char_func() const noexcept;encode_fill_f<CharT> encode_fill_func() const noexcept;| Return value | 
 | 
write_replacement_char_f<CharT> write_replacement_char_func() const noexcept;| Return value | 
 | 
dynamic_transcoder<char32_t, CharT> from_u32() const;| Return value | 
 | 
dynamic_transcoder<CharT, char32_t> to_u32() const;| Return value | 
 | 
dynamic_transcoder<CharT, CharT> sanitizer() const;| Return value | 
 | 
dynamic_transcoder<CharT, char> find_transcoder_to
    ( tag<char>, char_encoding_id id) const;| Return value | 
 | 
dynamic_transcoder<char, CharT> find_transcoder_from
    ( tag<char>, char_encoding_id id) const;| Return value | 
 | 
dynamic_transcoder<CharT, char8_t> find_transcoder_to
    ( tag<char8_t>, char_encoding_id id) const;| Return value | 
 | 
dynamic_transcoder<char8_t, CharT> find_transcoder_from
    ( tag<char8_t>, char_encoding_id id) const;| Return value | 
 | 
dynamic_transcoder<CharT, char16_t> find_transcoder_to
    ( tag<char16_t>, char_encoding_id id) const;| Return value | 
 | 
dynamic_transcoder<char16_t, CharT> find_transcoder_from
    ( tag<char16_t>, char_encoding_id id) const;| Return value | 
 | 
dynamic_transcoder<CharT, wchar_t> find_transcoder_to
    ( tag<wchar_t>, char_encoding_id id) const;| Return value | 
 | 
dynamic_transcoder<wchar_t, CharT> find_transcoder_from
    ( tag<wchar_t>, char_encoding_id id) const;| Return value | 
 | 
7.13. Function template find_transcoder
template <typename SrcEncoding, typename DestEncoding>
auto find_transcoder(SrcEncoding src, DestEncoding dest);- Requirements
- 
SrcEncodingandDestEncodingare CharEncoding types.
- Return type
- 
A type that is Transcoder 
- Return value
- 
- 
Returns the default value of static_transcoder<SrcID, DestID>if such template instantiation is defined andSrcEncodingis ( or derives from )static_char_encoding<SrcID>andDestEncodingis ( or derives from )static_char_encoding<DestID>;
- 
otherwise, returns src.sanitizer()ifsrc.id()is equal todest.id()andSrcEncoding::char_typeis the same type asDestEncoding::char_type;
- 
otherwise, returns src.to_u32()ifDestEncoding::char_typeischar32_t;
- 
otherwise, returns dest.from_u32()ifSrcEncoding::char_typeischar32_t;
- 
otherwise, returns src.find_transcoder_to(dest_ch, dest.id())if such expression is well formed and returns a non null transcoder , wheredest_chistag<DestEncoding::char_type>{}
- 
otherwise, returns dest.find_transcoder_from(src_ch, src.id())if such expression is well formed, wheresrc_shistag<SrcEncoding::char_type>{}
- 
otherwise returns dynamic_transcoder<SrcEncoding::char_type, DestEncoding::char_type>{}.
 
- 
| When find_transcoderreturns an null transcoder
, you still can usedecode_encodeanddecode_encode_size. | 
7.14. Function template decode_encode
namespace strf {
template<typename SrcCharT, typename DestCharT>
void decode_encode
    ( basic_outbuff<DestCharT>& ob
    , transcode_f<SrcCharT, char32_t> to_u32
    , transcode_f<char32_t, DestCharT> from_u32
    , const SrcCharT* src
    , std::size_t src_size
    , invalid_seq_notifier inv_seq_notifier
    , surrogate_policy surr_poli );
} // namespace strfConverts the content in src to UTF-32 using to_u32,
then writes the result to ob using from_u32.
| Postcondition | 
 | 
7.15. Function template decode_encode_size
namespace strf {
template<typename SrcCharT>
std::size_t decode_encode_size
    ( transcode_f<SrcCharT, char32_t> to_u32
    , transcode_size_f<char32_t> size_calc_func
    , const SrcCharT* src
    , std::size_t src_size
    , invalid_seq_notifier inv_seq_notifier
    , surrogate_policy surr_poli );
} // namespace strf| Return value | The return of  | 
7.16. Type aliases for encodings
namespace strf {
template <typename CharT>
using ascii = static_char_encoding<CharT, eid_ascii>;
template <typename CharT>
using iso_8859_1 = static_char_encoding<CharT, eid_iso_8859_1>;
template <typename CharT>
using iso_8859_3 = static_char_encoding<CharT, eid_iso_8859_3>;
template <typename CharT>
using iso_8859_15 = static_char_encoding<CharT, eid_iso_8859_15>;
template <typename CharT>
using windows_1252 = static_char_encoding<CharT, eid_windows_1252>;
template <typename CharT>
using utf8 = static_char_encoding<CharT, eid_utf8>;
template <typename CharT>
using utf16 = static_char_encoding<CharT, eid_utf16>;
template <typename CharT>
using utf32 = static_char_encoding<CharT, eid_utf32>;
template <typename CharT>
using utf = /* see below */;
} // namespace strftemplate <typename CharT>
using utf = /* ... */;utf<CharT> is an alias to utf8<CharT>, utf16<CharT> or utf32<CharT>,
depending on the value of sizeof(CharT).
8. Width Calculation
8.1. Facet category width_calculator_c
namespace strf {
struct width_calculator_c
{
    static constexpr bool constrainable = true;
    static constexpr fast_width get_default() noexcept;
};
} // namespace strfFor 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_torwchar_t
- 
Encoding, an CharEncoding type for valueCharSize
- 
encoding, an lvalue reference of typeEncoding
- 
cha value of typeCharT
- 
limit, a value of typewidth_t
- 
str, a value of typeconst CharT*pointing to a string encoded according toencoding.
- 
str_len, a value of typestd::size_tequal to the length of stringstr.
- 
surr_poli, a value of typesurrogate_policy
For a type X to be WidthCalculator, given an object x of type X,
the following syntax and requirements have to be satisfied:
X::categoryA type alias to width_calculator_c.
x.char_width(encoding, ch)| Return type | |
| Return value | The width of  | 
x.str_width(encoding, limit, str, str_len, surr_poli)| Return type | |
| Return value | The width of the string  | 
x.str_width_and_pos(encoding, limit, str, str_len, surr_poli)| Effect | Calculates the width of  | 
| Return type | |
| Return value | A value  
 | 
| The library provides three classes and one class template that
      satisfy _WidthCalculator: fast_width,width_as_fast_u32len,width_as_u32lenand `width_by_func. | 
Struct width_and_pos
struct width_and_pos {
    width_t width;
    std::size_t pos;
};8.2. Class fast_width
Class fast_width is a facet of the category width_calculator_c
that evaluates the width of a string as its size.
class fast_width final
{
public:
    using category = width_calculator_c;
    template <typename CharEncoding>
    width_t char_width
        ( CharEncoding
        , typename CharEncoding::char_type ) const noexcept;
    template <typename CharEncoding>
    width_t str_width
        ( CharEncoding
        , width_t limit
        , const typename CharEncoding::char_type*
        , std::size_t str_len
        , surrogate_policy ) const noexcept;
    template <typename CharEncoding>
    constexpr width_and_pos str_width_and_pos
        ( CharEncoding
        , width_t limit
        , const typename CharEncoding::char_type*
        , std::size_t str_len
        , surrogate_policy ) const noexcept;
};template <typename CharEncoding>
width_t char_width
    ( CharEncoding
    , typename CharEncoding::char_type ) const noexcept;| Return value | 
 | 
template <typename CharEncoding>
constexpr width_t str_width
    ( CharEncoding
    , width_t limit
    , const typename CharEncoding::char_type*
    , std::size_t str_len
    , surrogate_policy ) const noexcept;| Return value | 
 | 
template <typename CharEncoding>
constexpr width_and_pos str_width_and_pos
    ( CharEncoding
    , width_t limit
    , const typename CharEncoding::char_type*
    , std::size_t str_len
    , surrogate_policy ) const noexcept;| Return value | The return value  
 | 
8.3. Class width_as_fast_u32len
Class width_as_fast_u32len 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 and differently from width_as_u32len,
it assumes that the measured string is totally conformant to its encoding.
class width_as_fast_u32len final
{
public:
    using category = width_calculator_c;
    template <typename CharEncoding>
    width_t char_width
        ( CharEncoding encoding
        , typename CharEncoding::char_type ) const noexcept;
    template <typename CharEncoding>
    width_t str_width
        ( CharEncoding encoding
        , width_t limit
        , const typename CharEncoding::char_type* str
        , std::size_t str_len
        , surrogate_policy ) const noexcept;
    template <typename CharEncoding>
    constexpr width_and_pos str_width_and_pos
        ( CharEncoding encoding
        , width_t limit
        , const typename CharEncoding::char_type* str
        , std::size_t str_len
        , surrogate_policy ) const noexcept;
};template <typename CharEncoding>
width_t char_width
    ( CharEncoding
    , typename CharEncoding::char_type ) const noexcept;| Return value | 
 | 
template <typename CharEncoding>
constexpr width_t str_width
    ( CharEncoding encoding
    , width_t limit
    , const typename CharEncoding::char_type* str
    , std::size_t str_len
    , surrogate_policy ) const noexcept;| Return value | 
 | 
template <typename CharEncoding>
constexpr width_and_pos str_width_and_pos
    ( CharEncoding encoding
    , width_t limit
    , const typename CharEncoding::char_type* str
    , std::size_t str_len
    , surrogate_policy ) const noexcept;| Return value | The return value  
 | 
8.4. Class width_as_u32len
Class width_as_fast_u32len 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 the corresponding encoding is replaced
by one codepoint ( following the semantics of {invalid_seq_policy}::replace ).
class width_as_u32len final
{
public:
    using category = width_calculator_c;
    template <typename CharEncoding>
    width_t char_width
        ( CharEncoding encoding
        , typename CharEncoding::char_type ) const noexcept;
    template <typename CharEncoding>
    width_t str_width
        ( CharEncoding encoding
        , width_t limit
        , const typename CharEncoding::char_type* str
        , std::size_t str_len
        , surrogate_policy ) const noexcept;
    template <typename CharEncoding>
    constexpr width_and_pos str_width_and_pos
        ( CharEncoding encoding
        , width_t limit
        , const typename CharEncoding::char_type* str
        , std::size_t str_len
        , surrogate_policy ) const noexcept;
};template <typename CharEncoding>
width_t char_width
    ( CharEncoding
    , typename CharEncoding::char_type ) const noexcept;| Return value | 
 | 
template <typename CharEncoding>
constexpr width_t str_width
    ( CharEncoding encoding
    , width_t limit
    , const typename CharEncoding::char_type* str
    , std::size_t str_len
    , surrogate_policy ) const noexcept;| Return value | 
 | 
template <typename CharEncoding>
constexpr width_and_pos str_width_and_pos
    ( CharEncoding encoding
    , width_t limit
    , const typename CharEncoding::char_type* str
    , std::size_t str_len
    , surrogate_policy ) const noexcept;| Return value | The return value  
 | 
8.5. Class template width_by_func
The instances of the width_by_func class template are facets
of the category width_calculator_c.
It calculates the width of a string by converting it to UTF-32,
following the policy associated to {invalid_seq_policy}::replace,
and then calling the provided function to evaluate the width
of each UTF-32 character.
template <typename CharWidthFunc>
class width_by_func{
public:
    using category = width_calculator_c;
    template <typename CharEncoding>
    width_t char_width
        ( CharEncoding charste
        , typename CharEncoding::char_type ) const;
    template <typename CharEncoding>
    width_t str_width
        ( CharEncoding encoding
        , width_t limit
        , const typename CharEncoding::char_type* str
        , std::size_t str_len
        , surrogate_policy ) const;
    template <typename CharEncoding>
    constexpr width_and_pos str_width_and_pos
        ( CharEncoding encoding
        , width_t limit
        , const typename CharEncoding::char_type* str
        , std::size_t str_len
        , surrogate_policy ) const;
private:
    const CharWidthFunc func_; // exposition only
};Compile-time requirements
Given
- 
ch, a value of typechar32_t
- 
func, a object of typeCharWidthFuncorconst CharWidthFunc
The expression func(ch) must be well formed and the return type
must be width_t.
Member functions
template <typename CharEncoding>
width_t char_width
    ( CharEncoding encoding
    , typename CharEncoding::char_type ch) const;| Return value | 
 | 
template <typename CharEncoding>
constexpr width_t str_width
    ( CharEncoding encoding
    , width_t limit
    , const typename CharEncoding::char_type* str
    , std::size_t str_len
    , surrogate_policy  surr_poli) const;| Return value | The sum of the values of  , if such value is less than or equal to  | 
template <typename CharEncoding>
constexpr width_and_pos str_width_and_pos
    ( CharEncoding encoding
    , width_t limit
    , const typename CharEncoding::char_type* str
    , std::size_t str_len
    , surrogate_policy surr_poli) const;| Return value | The return value  
 | 
8.6. Function template make_width_calculator
template <typename CharWidthFunc>
width_by_func<CharWidthFunc> make_width_calculator(CharWidthFunc f);| Return value | 
 | 
8.7. Class width_t
The width_t class implements signed
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 an en.
namespace strf {
class width_t {
public:
    struct from_underlying_tag{};
    constexpr width_t() noexcept;
    constexpr width_t(std::int16_t) 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 bool is_integral() const noexcept;
    constexpr std::int16_t floor() const noexcept;
    constexpr std::int16_t ceil() const noexcept;
    constexpr std::int16_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;
private:
    std::int32_t _underlying_value; // exposition only
};
constexpr width_t width_max = width_t::from_underlying(INT32_MAX);
constexpr width_t width_min = width_t::from_underlying(INT32_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 checked_add(width_t lhs, width_t rhs) noexcept;
constexpr width_t checked_subtract(width_t lhs, std::int64_t rhs) noexcept;
constexpr width_t checked_subtract(width_t lhs, width_t rhs) noexcept;
constexpr width_t checked_mul(width_t lhs, std::uint32_t rhs) noexcept;
} // namespace strfto-do
8.8. width_t literal _w
namespace strf {
namespace width_literal {
template <char...C>
constexpr width_t operator "" _w()
} // namespace width_literal
} // namespace strfThe suffix _w can be aplied in floating-points literals in fixed notations as well
as integer literals.
using namespace strf::width_literal;
strf::width_t x = 1.5_w;
x += 0.25_w;
x += 1_w;
assert(x == 2.75_w);9. Numeric punctuation
To-do
10. Miscellaneous
10.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 strf10.2. Type traits
The table below list class templates that satisfy
UnaryTypeTrait.
They are created to be used in the constrain function template to filter
printable types.
| 
 | matches  | 
| 
 | matches  | 
| 
 | matches strings. | 
to-do
10.3. Class template tag
namespace strf {
template <typename... >
struct tag
{
    explicit tag() = default;
};
template <typename T>
struct tag<T>
{
    explicit constexpr STRF_HD tag() noexcept { }
    using type = T;
};
} // namespace strf10.4. Outbuff writing functions
namespace strf {
template <std::size_t CharSize>
void write( underlying_outbuff<CharSize>& ob
          , const underlying_char_type<CharSize>* data
          , std::size_t data_size );
template <std::size_t CharSize>
void write( underlying_outbuff<CharSize>& ob
          , const underlying_char_type<CharSize>* data
          , const underlying_char_type<CharSize>* data_end );
template <typename CharT>
void write( basic_outbuff<CharT>& ob
          , const CharT* data
          , std::size_t count );
template <typename CharT>
void write( basic_outbuff<CharT>& ob
          , const CharT* data
          , const CharT* data_end );
void write(basic_outbuff<char>& ob, const char* cstr);
void write(basic_outbuff<wchar_t>& ob, const wchar_t* cstr);
} // namespace strftemplate <std::size_t CharSize>
void write( underlying_outbuff<CharSize>& ob
          , const underlying_char_type<CharSize>* data
          , const underlying_char_type<CharSize>* data_end );| Effect | Writes the the range [  | 
template <std::size_t CharSize>
void write( underlying_outbuff<CharSize>& ob
          , const underlying_char_type<CharSize>* data
          , std::size_t data_size );| Effect | Same as  | 
template <typename CharT>
void write( {basic_outbuff}<CharT>& ob
          , const CharT* data
          , const CharT* data_end );| Effect | Writes the the range [  | 
template <typename CharT>
void write( {basic_outbuff}<CharT>& ob
          , const CharT* data
          , std::size_t data_size );| Effect | Same as  | 
void write( {basic_outbuff}<char>& ob
          , const char* cstr );| Effect | Same as  | 
void write( basic_outbuff<wchar_t>& ob
          , const wchar_t* wcstr );| Effect | Same as  | 
10.5. Destination markers
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 | 
 | 
| Return value | A destination object whose internal OutbuffCreator object  | 
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  | 
namespace strf {
/* see below */ to(char8_t*  dest,  char8_t*  end);
/* see below */ to(char*     dest,  char*     end);
/* see below */ to(char16_t* dest,  char16_t* end);
/* see below */ to(char32_t* dest,  char32_t* end);
/* see below */ to(wchar_t*  dest,  wchar_t*  end);
} // namespace strf| Return type and value | Same as  | 
10.6. Alignment format functions
| operator>(std::int16_t width) | Align to the right ( Or to the left right-to-left (RTL) script ) | 
| operator<(std::int16_t width) | Align to the left ( Or to the right right-to-left (RTL) script ) | 
| operator^(std::int16_t width) | Center alignment | 
| operator%(std::int16_t width) | Split the content, as in  | 
| fill(char32_t ch) | Set the fill character. |