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_pack
object 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)
returnstrue
then returns <<do_get_facet,do_get_facet<FCat, Tag>(fp)
, otherwise returnFCat::get_default()
. - Compile-time requirements
-
FCat
is 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_facet function template.
|
template <typename FCat, typename Tag, typename FPE>
constexpr bool has_facet(const FPE& fpe)
-
- Effects
-
-
If
FPE
is an instance offacets_pack
, then returns wheter there is any elementeelm
infpe
such thathas_facet<FCat, Tag>(elm)
istrue
. -
If
FPE
is an instance ofconstrained_fpe<FPE, Filter>
, then returnsFilter<Tag>::value && has_facet<FCat, Tag>(fpe.get())
. -
If
FPE
is a Facet type, returnsstd::is_same_v<FCat, facet_category<FPE>>
-
- Compile-time requirements
-
-
FCat
is a FacetCategory type. -
FPE
satisfies FacetsPackElement.
-
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_facet function template
|
template <typename FCat, typename Tag, typename FPE>
constexpr decltype(auto) do_get_facet(const FPE& fpe);
-
- Compile-time requirements
-
-
FCat
satisfies FacetCategory. -
FPE
satisfies FacetsPackElement. -
has_facet<FCat, Tag>(fpe)
istrue
.
-
1.6. Class template constrained_fpe
template <template <class> class Filter, typename FPE>
class constrained_fpe;
-
The class template
constrained_fpe
is designed to be used infacets_pack
.constrained_fpe<Filter, FPE>
holds a value ofFPE
that will only be returned byget_facet<Category, Tag>
ifFilter<Tag>::value
istrue
.- Compile-time requirements
-
-
For any type
T
,Filter<T>
has a member variablevalue
that is a static constexpr value whose type is implicitly convertible tobool
-
FPE
satisfies ConstrainableFacetsPackElement.
-
Synopsis
namespace strf {
template <template <class> class Filter, typename FPE>
class constrained_fpe
{
public:
// constructors
constexpr constrained_fpe(const constrained_fpe&) = default;
constexpr constrained_fpe(constrained_fpe&& other) = default;
constexpr constrained_fpe(const FPE& f);
// element access
constexpr const FPE& get() const;
private:
FPE element; // exposition only;
};
} // namespace strf
Member functions
Constructors
constexpr explicit constrained_fpe(const FPE& fpe);
-
- Effect
-
Initializes the element of the
constrained_fpe
withfpe
.
constexpr constrained_fpe(const constrained_fpe& other);
-
- Effect
-
Initializes the element of the
constrained_fpe
from the const reference of the element ofother
. - Compile-time requirements
-
std::is_copy_constructible<FPE>::value
istrue
.
constexpr constrained_fpe(constrained_fpe&& other);
-
- Effect
-
Initializes the element of the
constrained_fpe
from the rvalue reference of element ofother
. - Compile-time requirements
-
std::is_move_constructible<FPE>::value
istrue
.
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);
-
constrain
is just a syntatic sugar to create aconstrained_fpe
object.- Return type
-
constrained_fpe<Filter, U>
, whereU
isstd::remove_cv_t<std::remove_reference_t<T>>
. - Return value
-
constrained_fpe<Filter, U>{ std::forward<T>(arg) }
- Compile-time requirements
-
T
is such thatU
satisfies FacetsPackElement.
1.8. Type requirement FacetsPackElement
A given type F
satisfies FacetsPackElement if, and only if, one of the following conditions is true:
-
F
is a Facet type. -
F
is an instance offacets_pack
. -
F
is an instance ofconstrained_fpe
.
1.9. Type requirement ConstrainableFacetsPackElement
A given a type F
is a ConstrainableFacetsPackElement if, and only if,
one of the following conditions is true:
-
F
is a Facet type andfacet_category<F>::constrainable
istrue
. -
F
isfacets_pack<F2...>
and all types inF2...
are ConstrainableFacetsPackElement. -
F
is an instance ofconstrained_fpe
.
1.10. Type requirement Facet
A given a type F
satisfies Facet
if all of the following conditions are met:
-
F
is MoveConstructible -
facet_category<F>
satisfies the FacetCategory requirements.
1.11. Type requirement FacetCagory
A given a type FCat
satisfies FacetCategory
if:
-
FCat
has a static member function namedget_default
that takes no argument and whose return type is eitherF
orconst F&
, whereF
is a type that satisfies the requirements associated toFCat
. -
FCat
has a member namedconstrainable
that is a static constexpr value convertible tobool
. ( If this value isfalse
then the facets associatedFCat
can not be constrained ).
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_type
is 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 strf
print_traits_of<T>
is:
-
print_traits_of<std::remove_cvref<T>>
, ifT
is a reference type or has any cv-qualifier -
otherwise, it is
Traits
, whenT
isvalue_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
, whenT
avalue_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_type
forwarded_type
must be implicitly convertible from P
,
and must be copy-constructible. And its copy-constructor should be fast.
( forwarded_type
is usually P
or const P&
)
forwarded_type
is used intead of P
as the storage type in some
situations ( for example, the objects created by fmt
and join
).
T::facet_tag
The 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_type
orT::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_preview
class template -
X
, a PrinterInput type for typesCharT
andPreview
-
x
, a value of typeX
T::char_type
A type alias to CharT
.
T::preview_type
A type alias to Preview
.
T::printer_type
A 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_size
istrue
thendest.recycle()
is not called.
x.preview
A 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 strf
The 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 strf
Struct 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 strf
2.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 strf
2.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 strf
2.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 strf
2.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 strf
Constructors
constexpr print_preview() noexcept;
Effect |
Default-construct each of the base classes. |
constexpr explicit print_preview(width_t initial_width) noexcept;
- Compile-time requirement
-
WidthRequired
ispreview_width::yes
, otherwise this constructor does not participate in overload resolution. - Effect
-
Initializes
width_preview
base 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 strf
Member functions
explicit constexpr size_preview() noexcept;
- Postcondition
-
get_size() == 0
explicit constexpr size_preview(std::size_t initial_size) noexcept;
- Compile-time requirement
-
Active
istrue
, 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
Active
isfalse
-
None
- When
Active
istrue
-
(get_size() - previous_size == s)
, whereprevious_size
is the return value ofget_size()
before this call.
- When
constexpr void get_size() const noexcept;
- Return value
-
- When
Active
isfalse
-
0
(always) - When
Active
istrue
-
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 strf
Member functions
constexpr width_preview() noexcept;
- Postcondition
-
remaining_width() == 0
constexpr width_preview(width_t initial_width) noexcept;
- Compile-time requirement
-
Active
istrue
, otherwise this constructor does not participate in overload resolution. - Postcondition
-
remaining_width() == initial_width
void subtract_width(width_t w) noexcept;
- Postcondition
-
- When
Active
isfalse
-
None
- When
Active
istrue
-
remaining_width() == previous_w - w
where
previous_w
is the return value ofremaining_width()
before this call.
- When
void checked_subtract_width(width_t w) noexcept;
- Postcondition
-
- When
Active
isfalse
-
None
- When
Active
istrue
-
remaining_width() == (w < previous_w ? previous_w - w : 0)
where
previous_w
is the return value ofremaining_width()
before this call.
- When
void checked_subtract_width(std::ptrdiff_t w)
- Postcondition
-
- When
Active
isfalse
-
None
- When
Active
istrue
-
remaining_width() == (w < previous_w.ceil() ? previous_w - (std::int16_t)w : 0)
where
previous_w
is 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 strf
The 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 strf
3.3. Type alias template fmt_type
namespace strf {
template <typename T>
using fmt_type = /*…*/;
} // namespace strf
fmt_type<T>
is:
-
T
, whenT
isvalue_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 strf
To-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 ifT
isvalue_with_formatters<ValueType, Fmts...>
. In this case, note thatFmt
is inFmts...
andT
derives fromFmt::template fn<T>
. -
Fmt::template fn<T>
is default constructible, assuming it is well formed. -
Fmt::template fn<T>
can be constructed fromconst Fmt::template fn<U>&
, if both are well formed.
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 strf
alignment_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 strf
Constructors
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
true
orB
isfalse
Observers
constexpr alignment_format get_alignmet_format() const noexcept;
-
- Return value
-
-
alignment_format{}
, whenHasAlignment
isfalse
. -
The value corresponding to the state of this object, when
HasAlignment
istrue
.
-
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
r
satisfies:-
r.width() == width
-
r.alignment == text_alignment::left
-
- Return value
-
-
when
HasAlignment
isfalse
:converted_fmt{static_cast<const T&>(*this)} < width
. -
when
HasAlignment
istrue
:std::move(static_cast<T&>(*this))
.
-
constexpr /*return type */ operator>({width_t} width) /* qualifier */ noexcept;
-
- Posconditions
-
The return value
r
satisfies:-
r.width() == width
-
r.alignment() == text_alignment::right
-
- Return value
-
-
when
HasAlignment
isfalse
:converted_fmt{static_cast<const T&>(*this)} > width
. -
when
HasAlignment
istrue
:std::move(static_cast<T&>(*this))
.
-
constexpr /*return type */ operator^({width_t} width) /* qualifier */ noexcept;
-
- Posconditions
-
The return value
r
satisfies:-
r.width() == width
-
r.alignment() == text_alignment::center
-
- Return value
-
-
when
HasAlignment
isfalse
:converted_fmt{static_cast<const T&>(*this)} ^ width
. -
when
HasAlignment
istrue
:std::move(static_cast<T&>(*this))
.
-
constexpr /*return type */ operator%({width_t} width) /* qualifier */ noexcept;
-
- Posconditions
-
The return value
r
satisfies:-
r.width() == width
-
r.alignment() == text_alignment::split
-
- Return value
-
-
when
HasAlignment
isfalse
:converted_fmt{static_cast<const T&>(*this)} % width
. -
when
HasAlignment
istrue
:std::move(static_cast<T&>(*this))
.
-
constexpr /*return type */ fill(char32_t ch) /* qualifier */ noexcept;
-
- Posconditions
-
The return value
r
satisfies:-
r.fill() == ch
-
- Return value
-
-
when
HasAlignment
isfalse
:converted_fmt{static_cast<const T&>(*this)}.fill(ch)
. -
when
HasAlignment
istrue
: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 strf
3.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 strf
int_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 strf
Observers
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
NewBase
is equal to10
indec()
,16
inhex()
,8
inoct()
and2
inbin()
. - Return value
-
-
static_cast<ReturnType>(static_cast<T&>(*this))
, whereReturnType
is 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 strf
float_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 strf
Constructors
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 == 0
has 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 strf
quantity_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 strf
Constructors
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:
-
-
CharT
is the character type. If it is not the same as the output character type ( defined by the destination ), then it is necessary to use theconv
orsani
format function. -
Traits
can be any type that satisfies CharTraits -
Alloc
can 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
enc
to the output encoding. If the encodings are the same then sanitizes the input string. sanitize_encoding()
-
Translates input string from the encoding associated to
CharT
to 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
enc
to 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
CharT
to 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 int
andunsigned 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 strf
int arr[3] = { 11, 22, 33 };
auto str = strf::to_string(strf::range(arr));
assert(str == "112233");
str = strf::to_string(strf::separated_range(arr, ", "));
assert(str == "11, 22, 33");
auto op = [](auto x){ return strf::join('(', +strf::fmt(x * 10), ')'); };
str = strf::to_string(strf::separated_range(arr, ", ", op));
assert(str == "(+110), (+220), (+330)");
With formatting
namespace strf {
template <typename Range>
/*...*/ fmt_range(const Range& r);
template <typename T, std::size_t N>
/*...*/ fmt_range(T (&array)[N], const Range& r);
template <typename Iterator>
/*...*/ fmt_range(const Iterator& begin, const Iterator& end);
// With separator
template <typename Range, typename CharT>
/*...*/ fmt_separated_range(const Range& r, const CharT* separator);
template <typename T, std::size_t N, typename CharT>
/*...*/ fmt_separated_range(T (&array)[N], const CharT* separator);
template <typename Iterator, typename CharT>
/*...*/ fmt_separated_range( const Iterator& begin
, const Iterator& end
, const CharT* separator );
} // namespace strf
Any format function applicable to the element type of the
range can also be applied to the
expression strf::fmt_range(/*...*/)
or
strf::fmt_separated_range(/*...*/)
.
This way the format functions is applied to all elements:
std::vector<int> vec = { 11, 22, 33 };
auto str1 = strf::to_string("[", +strf::fmt_separated_range(vec, " ;") > 4, "]");
assert(str1 == "[ +11 ; +22 ; +33]");
std::vector<int> vec = { 11, 22, 33 };
auto str2 = strf::to_string
( "["
, *strf::fmt_separated_range(vec, " / ").fill('.').hex() > 6,
" ]");
assert(str2 == "[..0xfa / ..0xfb / ..0xfc]");
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_reserve
object -
reserve_calc()
always returns adestination_reserve_calc
object. -
reserve(size)
always returns adestination_with_given_size
object. -
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
-
-
FPack
is an instance offacets_pack
. -
OutbuffCreator
satisfies 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 strf
Public member functions
Constructors
template <typename... Args>
constexpr destination_no_reserve(Args&&... args);
- Compile-time requirements
-
-
FPack
is DefaultConstructible -
std::is_constructible<OutbuffCreator, Args...>
istrue
, otherwise this constructor does not participate on overload resolution.
-
- Effect
-
-
Initializes
_outbuff_creator
withstd::forward<Args>(args)...
.
-
constexpr destination_no_reserve(const destination_no_reserve&) = default;
Copy constructor.
- Compile-time requirements
-
-
FPack
andOutbuffCreator
are 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. -
OutbuffCreator
is CopyConstructible
-
- Return Type
-
destination_no_reserve< OutbuffCreator , decltype(pack( std::declval<const FPack&>() , std::forward<FPE>(fpe)...) ) >
- Effect
-
Creates a
destination_no_reserve
object whose_outbuff_creator
is initialized with this_outbuff_creator
, and whose_fpack
is initialized withpack(this->_fpack, std::forward<FPE>(fpe)...)
template <typename... FPE>
/* see below */ with(FPE&&...) &&;
- Compile-time requirements
-
-
All types in
FPE...
satisfy FacetsPackElement. -
OutbuffCreator
is MoveConstructible
-
- Return Type
-
destination_no_reserve< OutbuffCreator , decltype(pack( std::declval<const FPack&>() , std::forward<FPE>(fpe)...) ) >
- Effect
-
Creates an
destination_no_reserve
object whose_outbuff_creator
is initialized withstd::move(_outbuff_creator)
, and whose_fpack
is initialized withpack(std::move(this->_fpack), std::forward<FPE>(fpe)...)
Size reserve
constexpr destination_calc_size<OutbuffCreator, FPack> reserve_calc() const &;
- Compile-time requirements
-
-
OutbuffCreator
is CopyConstructible and SizedOutbuffCreator. -
FPack
is CopyConstructible.
-
- Effect
-
Creates an
destination_calc_size
object whose_outbuff_creator
is initialized with this_outbuff_creator
, and whose_fpack
is initialized with this_fpack
.
constexpr destination_calc_size<OutbuffCreator, FPack> reserve_calc() &&;
- Compile-time requirements
-
-
OutbuffCreator
is MoveConstructible and SizedOutbuffCreator. -
FPack
is CopyConstructible.
-
- Effect
-
Creates an
destination_calc_size
object whose_outbuff_creator
is initialized withstd::move(_outbuff_creator)
from this object, and whose_fpack
object is initialized withstd::move(_fpack)
from this object.
constexpr destination_with_given_size<OutbuffCreator, FPack>
reserve(std::size_t size) const &;
- Compile-time requirements
-
-
OutbuffCreator
is CopyConstructible and SizedOutbuffCreator. -
FPack
is CopyConstructible.
-
- Effect
-
Creates an
destination_with_given_size
whose_size
is initialized withsize
, whose_outbuff_creator
is initialized with this_outbuff_creator
, and whose_fpack
is initialized with this_fpack
.
constexpr destination_with_given_size<OutbuffCreator, FPack>
reserve(std::size_t size) &&;
- Compile-time requirements
-
OutbuffCreator
is MoveConstructible and SizedOutbuffCreator.-
FPack
is CopyConstructible.
-
- Effect
-
Creates an
destination_with_given_size
object whose_size
is initialized withsize
, whose_outbuff_creator
is initialized withstd::move(_outbuff_creator) from this object, and whose `_fpack
is 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
arg
inargs...
, 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
Arg
is 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
-
-
FPack
is an instance offacets_pack
. -
SizedOutbuffCreator
satisfies 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 strf
Constructors
template <typename... Args>
constexpr destination_reserve_calc(Args&&... args);
- Compile-time requirements
-
-
FPack
is DefaultConstructible -
std::is_constructible<OutbuffCreator, Args...>::value
istrue
, otherwise this constructor does not participate on overload resolution.
-
- Effect
-
-
Initializes
_outbuff_creator
withstd::forward<Args>(args)...
.
-
constexpr destination_reserve_calc(const destination_reserve_calc&) = default;
Copy constructor.
- Compile-time requirements
-
-
FPack
andOutbuffCreator
are 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. -
OutbuffCreator
is CopyConstructible
-
- Return Type
-
destination_reserve_calc< OutbuffCreator , decltype(pack( std::declval<const FPack&>() , std::forward<FPE>(fpe)...) ) >
- Effect
-
Creates an
destination_reserve_calc
object whose_outbuff_creator
is initialized with this_outbuff_creator
, and whose_fpack
is initialized withpack(this->_fpack, std::forward<FPE>(fpe)...)
template <typename... FPE>
/* see below */ with(FPE&&...) &&;
- Compile-time requirements
-
-
All types in
FPE...
satisfy FacetsPackElement. -
OutbuffCreator
is MoveConstructible
-
- Return Type
-
destination_reserve_calc< OutbuffCreator , decltype(pack( std::declval<const FPack&>() , std::forward<FPE>(fpe)...) ) >
- Effect
-
Creates an
destination_reserve_calc
object whose_outbuff_creator
is initialized withstd::move(this->_outbuff_creator)
, and whose_fpack
is initialized withpack(std::move(this->_fpack), std::forward<FPE>(fpe)...)
Size reserve
constexpr destination_no_reserve<OutbuffCreator, FPack> no_reserve() const &;
- Compile-time requirements
-
-
OutbuffCreator
is CopyConstructible -
FPack
is CopyConstructible.
-
- Effect
-
Creates an
destination_no_reserve
object whose_outbuff_creator
is initialized with this_outbuff_creator
, and whose_fpack
is initialized with this_fpack
.
constexpr destination_calc_size<OutbuffCreator, FPack> reserve_calc() &&;
- Compile-time requirements
-
-
OutbuffCreator
is MoveConstructible -
FPack
is CopyConstructible.
-
- Effect
-
Creates an
destination_no_reserve
object whose_outbuff_creator
is initialized withstd::move(_outbuff_creator)
from this object, and whose_fpack
object is initialized withstd::move(_fpack)
from this object.
constexpr destination_with_given_size<OutbuffCreator, FPack>
reserve(std::size_t size) const &;
- Compile-time requirements
-
-
OutbuffCreator
is CopyConstructible and SizedOutbuffCreator. -
FPack
is CopyConstructible.
-
- Effect
-
Creates an
destination_with_given_size
whose_size
is initialized withsize
, whose_outbuff_creator
is initialized with this_outbuff_creator
, and whose_fpack
is initialized with this_fpack
.
constexpr destination_with_given_size<OutbuffCreator, FPack>
reserve(std::size_t) &&;
- Compile-time requirements
-
OutbuffCreator
is MoveConstructible and SizedOutbuffCreator.-
FPack
is CopyConstructible.
-
- Effect
-
Creates an
destination_with_given_size
object whose_size
is initialized withsize
, whose_outbuff_creator
is initialized withstd::move(_outbuff_creator) from this object, and whose `_fpack
is 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
preview
of typeprint_preview<preview_size::yes, preview_width::no>
.using preview_type = print_preview<preview_size::yes, preview_width::no>; preview_type preview;
-
For each
arg
inargs...
, 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
p
object 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
-
-
FPack
is an instance offacets_pack
. -
SizedOutbuffCreator
satisfies 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 strf
Constructors
template <typename... Args>
constexpr destination_with_given_size(std::size_t size, Args&&... args);
- Compile-time requirements
-
-
FPack
is DefaultConstructible -
std::is_constructible<OutbuffCreator, Args...>
, otherwise this constructor does not participate on overload resolution.
-
- Effect
-
-
Initializes
_outbuff_creator
withstd::forward<Args>(args)...
. -
Initializes
_size
withsize
-
constexpr destination_with_given_size(const destination_with_given_size&) = default;
Copy constructor.
- Compile-time requirements
-
-
FPack
andOutbuffCreator
are 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. -
OutbuffCreator
is CopyConstructible
-
- Return Type
-
destination_with_given_size< OutbuffCreator , decltype(pack( std::declval<const FPack&>() , std::forward<FPE>(fpe)...) ) >
- Effect
-
Creates an
destination_with_given_size
object whose_size
is is initialized with this_size
, whose_outbuff_creator
is initialized with this_outbuff_creator
, and whose_fpack
is initialized withpack(this->_fpack, std::forward<FPE>(fpe)...)
template <typename... FPE>
/* see below */ with(FPE&&...) &&;
- Compile-time requirements
-
-
All types in
FPE...
satisfy FacetsPackElement. -
OutbuffCreator
is MoveConstructible
-
- Return Type
-
destination_with_given_size< OutbuffCreator , decltype(pack( std::declval<const FPack&>() , std::forward<FPE>(fpe)...) ) >
- Effect
-
Creates an
destination_with_given_size
object whose_size
is is initialized with this_size
, whose_outbuff_creator
is initialized withstd::move(_outbuff_creator)
from this object , and whose_fpack
is initialized withpack(std::move(this->_fpack), std::forward<FPE>(fpe)...)
Size reserve
constexpr destination_no_reserve<OutbuffCreator, FPack> no_reserve() const &;
- Compile-time requirements
-
-
OutbuffCreator
is CopyConstructible -
FPack
is CopyConstructible.
-
- Effect
-
Creates an
destination_no_reserve
object whose_outbuff_creator
is initialized with this_outbuff_creator
, and whose_fpack
is initialized with this_fpack
.
constexpr destination_calc_size<OutbuffCreator, FPack> no_reserve() &&;
- Compile-time requirements
-
-
OutbuffCreator
is MoveConstructible -
FPack
is CopyConstructible.
-
- Effect
-
Creates an
destination_no_reserve
object whose_outbuff_creator
is initialized withstd::move(_outbuff_creator)
from this object, and whose_fpack
object is initialized withstd::move(_fpack)
from this object.
constexpr destination_calc_size<OutbuffCreator, FPack> reserve_calc() const &;
- Compile-time requirements
-
-
OutbuffCreator
is CopyConstructible and SizedOutbuffCreator. -
FPack
is CopyConstructible.
-
- Effect
-
Creates an
destination_calc_size
object whose_outbuff_creator
is initialized with this_outbuff_creator
, and whose_fpack
is initialized with this_fpack
.
constexpr destination_calc_size<OutbuffCreator, FPack> reserve_calc() &&;
- Compile-time requirements
-
-
OutbuffCreator
is MoveConstructible and SizedOutbuffCreator. -
FPack
is CopyConstructible.
-
- Effect
-
Creates an
destination_calc_size
object whose_outbuff_creator
is initialized withstd::move(_outbuff_creator)
from this object, and whose_fpack
object 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
arg
inargs...
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
Arg
is 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 typeX
orconst X
The following must hold:
-
X
is CopyConstructible -
X
has a member type aliasX::char_type
defined aschar_type
-
X
has theX::outbuff_type
that 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 typeX
orconst X
The following must hold:
-
X
is CopyConstructible -
X
has a member type aliasT::char_type
defined aschar_type
-
X
has theX::size_outbuff_type
that 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
handle
function on the facet object correspoding to thetr_error_notifier_c
category.
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 strf
Struct default_tr_error_notifier
default_tr_error_notifier
is the default facet of the tr_error_notifier_c
category.
It’s a dummy error handler.
namespace strf {
struct default_tr_error_notifier {
using category = tr_error_notifier_c;
template <typename CharEncoding>
void handle
( const typename CharEncoding::char_type* str
, std::size_t str_len
, std::size_t err_pos
, CharEncoding enc ) noexcept
{
}
};
} // namespace strf
Type 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_t
value equal to the length of the stringstr
-
err_pos
, astd::size_t
value less than or equal tostr_len
The following must host:
-
X
is CopyConstructible. -
X::category
is a type alias totr_error_notifier_c
-
The following expression is supported:
x.handle(str, str_len, 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 strf
7.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 strf
Class 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 strf
constexpr 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 strf
For 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_t
orwchar_t
-
DestCharT
, one of the types:char
,char8_t
,char16_t
,char32_t
orwchar_t
-
X
, a Transcoder type fromSrcCharT
toDestCharT
-
x
, an expression of typeX
orconst X
-
dest
, an lvalue reference of typebasic_outbuff<DestCharT>
-
src
, a value of typeconst SrcCharT*
-
src_size
, a value of typestd::size_t
equal 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:
-
X
is CopyConstructible. -
X
supports 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_transcoder and dynamic_transcoder .
|
7.7. Type requirement CharEncoding
Given
-
CharT
, one of the follwoing types:char
,char8_t
,char16_t
,char32_t
orwchar_t
-
X
, a CharEncoding type for typeCharT
-
x
, an expression of typeX
orconst X
-
OtherCharT
, one of the folowing types :char
,char8_t
,char16_t
orwchar_t
-
ptr
, a value of typeCharT*
-
src
, a value of typeconst CharT*
-
src_size
, a value of typestd::size_t
equal 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:
-
X
must be CopyConstructible -
facet_category<X>
must bechar_encoding_c<CharT>
-
X
must satisfy the following syntax and semantics:
X::char_type
Type 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 , since char32_t
is reserved for UTF-32.
The library internaly assumes in many occasions that the encoding
is UTF-32 when CharT is char32_t .
|
There are two class templates that satisfy CharEncoding: static_transcoder and dynamic_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 strf
constexpr 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
-
SrcEncoding
andDestEncoding
are 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 andSrcEncoding
is ( or derives from )static_char_encoding<SrcID>
andDestEncoding
is ( or derives from )static_char_encoding<DestID>
; -
otherwise, returns
src.sanitizer()
ifsrc.id()
is equal todest.id()
andSrcEncoding::char_type
is the same type asDestEncoding::char_type
; -
otherwise, returns
src.to_u32()
ifDestEncoding::char_type
ischar32_t
; -
otherwise, returns
dest.from_u32()
ifSrcEncoding::char_type
ischar32_t
; -
otherwise, returns
src.find_transcoder_to(dest_ch, dest.id())
if such expression is well formed and returns a non null transcoder , wheredest_ch
istag<DestEncoding::char_type>{}
-
otherwise, returns
dest.find_transcoder_from(src_ch, src.id())
if such expression is well formed, wheresrc_sh
istag<SrcEncoding::char_type>{}
-
otherwise returns
dynamic_transcoder<SrcEncoding::char_type, DestEncoding::char_type>{}
.
-
When find_transcoder returns an null transcoder
, you still can use decode_encode and decode_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 strf
Converts 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 strf
template <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 strf
For a type to be a facet of the width_calculator_c
category, it has to
satisfy the WidthCalculator requirements.
Type requirement WidthCalculator
Given
-
CharT
, one of the types:char
,char8_t
,char16_t
,char32_t
orwchar_t
-
Encoding
, an CharEncoding type for valueCharSize
-
encoding
, an lvalue reference of typeEncoding
-
ch
a 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_t
equal 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::category
A 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_u32len and `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 typeCharWidthFunc
orconst 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 strf
to-do
8.8. width_t
literal _w
namespace strf {
namespace width_literal {
template <char...C>
constexpr width_t operator "" _w()
} // namespace width_literal
} // namespace strf
The suffix _w
can be aplied in floating-points literals in fixed notations as well
as integer literals.
using namespace strf::width_literal;
strf::width_t x = 1.5_w;
x += 0.25_w;
x += 1_w;
assert(x == 2.75_w);
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 strf
10.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 strf
10.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 strf
template <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. |