Skip to content

Commit fb53806

Browse files
committed
Turn printable_overrider_c into a struct template.
This way the user doesn't need to remember to constrain the facet
1 parent 234dfa2 commit fb53806

10 files changed

+66
-107
lines changed

docs/howto_add_printable_types.adoc

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ http://www.boost.org/LICENSE_1_0.txt)
1919
:format_specifiers: <<strf_hpp#PrintableDef_format_specifiers,format_specifiers>>
2020
:FormatSpecifier: <<strf_hpp#FormatSpecifier,FormatSpecifier>>
2121
:printable_overrider_c: <<strf_hpp#printable_overrider_c,printable_overrider_c>>
22-
:dont_override: <<strf_hpp#dont_override,dont_override>>
2322
:premeasurements: <<strf_hpp#premeasurements,premeasurements>>
2423
:measure: <<strf_hpp#measure,measure>>
2524
:value_and_format: <<strf_hpp#value_and_format,value_and_format>>

docs/howto_override_printable_types.adoc

Lines changed: 13 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ http://www.boost.org/LICENSE_1_0.txt)
66
////
77

88
:printable_overrider_c: <<strf_hpp#printable_overrider_c,printable_overrider_c>>
9+
:printable_overrider_c_of: <<strf_hpp#printable_overrider_c_of,printable_overrider_c_of>>
910
:make_printer: <<strf_hpp#make_printer,make_printer>>
1011
:get_facet: <<strf_hpp#get_facet,get_facet>>
1112
:pack: <<strf_hpp#pack,pack>>
@@ -32,25 +33,20 @@ http://www.boost.org/LICENSE_1_0.txt)
3233
Strf allows you not only to <<howto_add_printable_types#,add printable types>>,
3334
but also to override existing ones. The procedure is similar; the
3435
main difference is that instead of defining a _{PrintableDef}_ type,
35-
you create a facet of the `{printable_overrider_c}` category,
36+
you create a facet of the `{printable_overrider_c}<...>` category,
3637
which is almost the same thing.
37-
So this document presumes you already know how to do that.
38+
So this document presumes you already know how to do add printables types.
3839
If you don't,
3940
<<howto_add_printable_types#CreatePrintableDef,click here>>
4041
to get some explanation.
4142

42-
43-
The facet shall contain the
44-
`make_printer` member function templates that will
45-
replace those defined in the _{PrintableDef}_ class of the
46-
overrided type.
4743
For example, one could define a facet to override the `bool` like this:
4844

4945
[source,cpp,subs=normal]
5046
----
5147
struct italian_bool_facet
5248
{
53-
using category = strf::{printable_overrider_c};
49+
using category = strf::{printable_overrider_c_of}<bool>;
5450
5551
template <typename CharT, typename Pre, typename FPack>
5652
constexpr static auto make_printer
@@ -85,21 +81,15 @@ so instead of hardcoded strings like `"vero"`, and `"falso"`
8581
, we could use member variables, which would probably make more sense ).
8682

8783
Just as it is usual in __PrintableDef__ classes,
88-
you can see that we have two `make_printer` fuctions
89-
( though the first one is unnecessary ).
84+
you can see that we have two `make_printer` fuctions.
9085
The second one handles `bool` values with formatting.
91-
Even if we don't define it, an expression like
92-
`strf::right(true, 10, '.')`
93-
is still well-formed, because the format functions
94-
that are applicable to a printable type keep being the same
95-
when we override it. We can't change them.
96-
So it makes sense to overload `make_printer`
97-
with `{value_and_format}` argument even
98-
if you don't want to support formatting, just to
99-
add a `static_assert` to emit a clear error message.
100-
101-
But if do you want support formatting then
102-
check in the <<strf_hpp#printable_types_list,documentation>> what
86+
87+
The format functions that are applicable to a printable
88+
type keep being the same when we override it. We can't change them.
89+
Defining the `format_specifiers` type alias in the overrider facet
90+
has not effect.
91+
92+
Check in the <<strf_hpp#printable_types_list,documentation>> what
10393
are the format functions ( or the __FormatSpecifiers__ )
10494
applicable to the printable type you are overriding.
10595
If you take a look at the part the covers
@@ -115,35 +105,14 @@ taking the `{value_and_format}` argument and add
115105
a `static_assert` with an explanatory message.
116106
////
117107

118-
119108
Things are more lenient regarding facets:
120109
you can completely ignore the facet categories that
121110
influence the original printable type, as well as consider others
122111
or <<howto_add_printable_types#creating_facet,new>> ones.
123112
You can see that although `bool` type is influenced
124113
by `{lettercase}` facet, our override just ignores it.
125114

126-
Now we are almost ready to use our implementation.
127-
There is just a detail you *must*
128-
remember before using a facet object
129-
of the `printable_overrider_c` category &#x2014; you must __{constrain}__
130-
it to the types it aims to override:
131-
132-
[source,cpp]
133-
----
134-
template <typename T>
135-
struct is_bool: std::is_same<T, strf::representative_of_printable<bool>> {}; // <1>
136-
137-
constexpr auto italian_bool = strf::constrain<is_bool>(italian_bool_facet{});
138-
----
139-
140-
<1> `strf::{representative_of_printable}<__X__>`
141-
commonly aliases to `__X__`, and it does so for `bool`.
142-
However, is a good practice to use it (instead `__X__`), because it is
143-
what the library uses (__i.e.__ parameterizes `<<strf_hpp#get_facet,get_facet>>`
144-
with ) when "deciding" whether to apply a facet or not.
145-
146-
Now we are ready:
115+
Anyway, let's see the result:
147116

148117
[source,cpp,subs=normal]
149118
----
@@ -158,20 +127,6 @@ str = strf::to_string
158127
assert(str == "\...vero\.../..falso\...");
159128
----
160129

161-
162-
[WARNING]
163-
====
164-
When a `printable_overrider_c` facet is not constrained, it affects all
165-
overridable printable types, which is certainly not what we want:
166-
167-
[source,cpp,subs=normal]
168-
----
169-
auto str = strf::to_string.with(italian_bool_facet{})
170-
(true, '/', false, '/', 1.0, '/', 0.0, '/', (void*)0);
171-
assert(str == "vero/falso/vero/falso/falso");
172-
----
173-
====
174-
175130
[NOTE]
176131
====
177132
Some printable types are not overridable.

docs/quick_reference.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -712,7 +712,7 @@ When the argument associated with a `"{"` does not exist, the library does two t
712712
|Yes | Notifies nonconformities to the character encoding.
713713
|`<<tr_string_error,tr_error_notifier_c>>` |No | Notifies errors on the tr-string
714714
|`<<width_calculator,width_calculator_c>>` |Yes |Defines how the width is calculated
715-
|`<<howto_override_printable_types#,printable_overrider_c>>` |Yes | Overrides printable types
715+
|`<<howto_override_printable_types#,printable_overrider_c<_R_>>>` |Yes | Overrides printable types
716716
|===
717717

718718
[[numpunct]]

docs/ref_printable_types_requirements.adoc

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -231,40 +231,50 @@ using forwarded_printable_type = typename {printable_def_of}<T>::<<PrintableDef_
231231
} // namespace strf
232232
----
233233

234-
=== Facet category `printable_overrider_c` [[printable_overrider_c]]
235-
236-
////
237-
to-do
238-
////
239-
240-
A facet of this category should **aways** be <<constrain,constrained>> to the
241-
printable type intended to be overriden.
234+
=== Template facet category `printable_overrider_c` [[printable_overrider_c]]
242235

243236
[source,cpp,subs=normal]
244237
----
245238
namespace strf {
246239
240+
template <typename R>
247241
struct printable_overrider_c {
248242
static constexpr bool constrainable = true;
249243
250-
constexpr static <<dont_override,dont_override>> get_default() noexcept {
244+
constexpr static <<dont_override,dont_override>><R> get_default() noexcept {
251245
return {};
252246
}
253247
};
254248
255249
} // namespace strf
256250
----
257251

258-
==== Struct `dont_override` [[dont_override]]
252+
The template parameter `R` shall be the same as the `{representative_of_printable}<P>`,
253+
where `P` the printable type to be overriden.
254+
255+
=== Type alias `printable_overrider_c_of` [[printable_overrider_c_of]]
256+
257+
[source,cpp,subs=normal]
258+
----
259+
namespace strf {
260+
template <typename Printable>
261+
using printable_overrider_c_of =
262+
printable_overrider_c< representative_of_printable<Printable> >;
263+
}
264+
----
265+
266+
=== Struct template `dont_override` [[dont_override]]
267+
259268

260-
`dont_override` is the default facet of `printable_overrider_c` category.
269+
`dont_override<_T_>` is the default facet of `printable_overrider_c<_T>` category.
261270

262271
[source,cpp,subs=normal]
263272
----
264273
namespace strf {
265274
275+
template <typename T>
266276
struct dont_override {
267-
using category = printable_overrider_c;
277+
using category = printable_overrider_c<R>;
268278
};
269279
270280
} // namespace strf
@@ -286,7 +296,10 @@ If `{printable_def_of}<Arg>::<<PrintableDef_is_overridable,is_overridable>>::val
286296
`make_printer` returns
287297
[source,cpp,subs=normal]
288298
----
289-
{get_facet}< {printable_overrider_c}, {representative_of_printable}<Arg> > (facets)
299+
{get_facet}
300+
< {printable_overrider_c}<{representative_of_printable}<Arg>>
301+
, {representative_of_printable}<Arg> >
302+
(facets)
290303
.make_printer({tag}<CharT>{}, pre, facets, arg);
291304
----
292305

docs/why_not_std_locale.adoc

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,8 @@ auto punct = strf::numpunct<10> (3, 2, 1)
9191
( Be aware that `strf::numpunct` does not affect `bool` values,
9292
contrary to `std::numpunct` which
9393
has the `truename()` and `falsename()` functions.
94-
Instead, in Strf there is the `<<howto_override_printable_types#,printable_overrider_c>>`
95-
facet category, which enables you to override how
96-
values of `bool` are printed. )
94+
If you what to change how `bool` values are printed,
95+
see <<howto_override_printable_types#,how to override printable types>>.
9796

9897
// But perhaps the main reason is that the goals
9998
// re different:

examples/override_bool.cpp

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
struct my_bool_overrider
1313
{
14-
using category = strf::printable_overrider_c;
14+
using category = strf::printable_overrider_c_of<bool>;
1515

1616
template <typename CharT, typename PreMeasurements, typename FPack, typename... T>
1717
constexpr auto make_printer
@@ -46,10 +46,7 @@ struct my_bool_overrider
4646

4747
static_assert(strf::is_printable_and_overridable_v<bool>, "bool not overridable");
4848

49-
template <typename T>
50-
struct is_bool: std::is_same<T, strf::representative_of_printable<bool>> {};
51-
52-
constexpr auto italian_bool = strf::constrain<is_bool>(my_bool_overrider{{"falso", "vero"}});
49+
constexpr auto italian_bool = my_bool_overrider{{"falso", "vero"}};
5350

5451
int main()
5552
{
@@ -63,11 +60,6 @@ int main()
6360
, strf::center(false, 10, '.') );
6461
assert(str == "...vero.../..falso...");
6562

66-
// what happens when you don't constrain an overrider facet:
67-
str = strf::to_string.with(my_bool_overrider{{"falso", "vero"}})
68-
(true, '/', false, '/', 1.0, '/', 0.0, '/', static_cast<void*>(nullptr));
69-
assert(str == "vero/falso/vero/falso/falso");
70-
7163
return 0;
7264
}
7365

include/strf/detail/printable_def.hpp

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -346,16 +346,11 @@ constexpr detail_format_functions::fmt_fn fmt {};
346346

347347
} // namespace format_functions
348348

349+
template <typename Representative>
349350
struct printable_overrider_c;
350-
struct dont_override;
351-
352-
using print_override_c
353-
STRF_DEPRECATED_MSG("print_override_c was renamed printable_overrider_c")
354-
= printable_overrider_c;
355351

356-
using no_print_override
357-
STRF_DEPRECATED_MSG("no_print_override was renamed dont_override")
358-
= dont_override;
352+
template <typename Representative>
353+
struct dont_override;
359354

360355
namespace detail {
361356

@@ -407,16 +402,18 @@ constexpr STRF_HD decltype(auto) make_printer
407402
.make_printer(ChTag{}, p, fp, Helper::convert_printable_arg(arg));
408403
}
409404

405+
template <typename Representative>
410406
struct dont_override
411407
{
412-
using category = printable_overrider_c;
408+
using category = printable_overrider_c<Representative>;
413409
};
414410

411+
template <typename Representative>
415412
struct printable_overrider_c
416413
{
417414
static constexpr bool constrainable = true;
418415

419-
constexpr static STRF_HD dont_override get_default() noexcept
416+
constexpr static STRF_HD dont_override<Representative> get_default() noexcept
420417
{
421418
return {};
422419
}
@@ -479,6 +476,10 @@ using extract_representative = typename representative_from_printable_def<Printa
479476
template <typename T>
480477
using representative_of_printable = detail::extract_representative<strf::printable_def_of<T>>;
481478

479+
template <typename Printable>
480+
using printable_overrider_c_of =
481+
printable_overrider_c< representative_of_printable<Printable> >;
482+
482483
template <typename CharT, typename PreMeasurements, typename FPack, typename Arg>
483484
using printer_type = typename
484485
detail::helper_for_printing_with_premeasurements

include/strf/detail/printing_helpers.hpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -111,15 +111,15 @@ using select_printable_arg_converter_for_printing_with_premeasurements = typenam
111111
<PrintableDef, DefOrFacet, CharT, PreMeasurements, FPack, Arg>
112112
::type;
113113

114-
template <typename Overrider, typename OverrideTag>
114+
template <typename Overrider, typename Representative>
115115
struct overrider_getter
116116
{
117117
using printable_def_or_facet_type = Overrider;
118118

119119
template <typename FPack>
120120
static constexpr STRF_HD const Overrider& get_printable_def_or_facet(const FPack& fp)
121121
{
122-
return strf::get_facet<strf::printable_overrider_c, OverrideTag>(fp);
122+
return strf::get_facet<strf::printable_overrider_c<Representative>, Representative>(fp);
123123
}
124124
};
125125

@@ -146,12 +146,12 @@ struct printable_def_or_facet_getter_selector_2
146146
static_assert(Overridable, "");
147147
using representative = detail::extract_representative<PrintableDef>;
148148
using overrider_ = decltype
149-
( strf::get_facet<strf::printable_overrider_c, representative>
149+
( strf::get_facet<strf::printable_overrider_c<representative>, representative>
150150
(std::declval<FPack>()) );
151151

152152
using overrider = strf::detail::remove_cvref_t<overrider_>;
153153
using printable_def_or_facet_getter_type = typename std::conditional
154-
< std::is_same<overrider, strf::dont_override>::value
154+
< std::is_same<overrider, strf::dont_override<representative>>::value
155155
, printable_def_getter<PrintableDef>
156156
, overrider_getter<overrider, representative> >
157157
::type;
@@ -399,9 +399,9 @@ class polymorphic_printer_that_calls_print_from_facet
399399

400400
STRF_HD void print_to(strf::destination<CharT>& dst) const override
401401
{
402+
using representative = detail::extract_representative<PrintableDef>;
402403
strf::get_facet
403-
< strf::printable_overrider_c
404-
, detail::extract_representative<PrintableDef> > (facets_())
404+
< strf::printable_overrider_c<representative>, representative > (facets_())
405405
.print(dst, facets_(), printable_);
406406
}
407407

tests/add_and_override_printable_types.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ STRF_TEST_FUNC void test_printable_def_without_make_printer()
130130

131131
struct mytype_overrider_impl
132132
{
133-
using category = strf::printable_overrider_c;
133+
using category = strf::printable_overrider_c_of<mytype>;
134134

135135
template <typename CharT, typename FPack>
136136
STRF_HD static void print
@@ -494,7 +494,7 @@ STRF_TEST_FUNC void test_make_printer_that_returns_lambda()
494494

495495
struct mytype2_overrider_impl
496496
{
497-
using category = strf::printable_overrider_c;
497+
using category = strf::printable_overrider_c_of<mytype2>;
498498

499499
template <typename CharT, typename Pre, typename FPack>
500500
STRF_HD static auto make_printer

0 commit comments

Comments
 (0)