|
Boost : |
Subject: Re: [boost] [iostreams][io_state_savers] Request for interest in some ios_base basic utilities
From: Artyom Beilis (artyomtnk_at_[hidden])
Date: 2011-11-10 17:18:01
> From: Vicente J. Botet Escriba <vicente.botet_at_[hidden]>
>>
>> try {
>> foo const&f =use_facet<foo>(f);
>> // do required
>> }
>> catch(std::bad_cast const&) {
>> // do default
>> }
> I'm missing surely something. Recall, I'm a beginner. How do you ensure
> that any stream has associated a locale that contains your facet?
You don't. For example
std::ostream &operator<<(std::ostream &out,my_time const &tm)
{
std::locale l = out.getloc();
if(std::has_facet<my_time_facet>(loc)) {
my_time_facet const &f=std::use_facet<my_time_facet>(loc);
f.print_time(tm,out);
}
else { // user had not installed anything interesting so fallback for something.
my_time::print_iso_time(tm,out);
}
return out;
}
It is not YOUR job to install facets.
Ideally. std::locale should include "Classic" version of my_time_facet. But
without it you can do what I had shown above.
>> No actually, it is not. facets are not generated frequently.
>> locale is cheap to copy because facets are reference counted
>> so you create facet once and use it for long time. For example
>> messages facet can load dictionaries convert their encoding,
>> it is by no means cheap. But you create it once and then
>> reuse it.
>>
>>
> How do you reach to reuse them.
>
> For example if we use a string stream we will need to add the facet.
No, you don't.
You don't add facet unless you need to bring some locale specific data.
> I guess that this operation will not take too much time, and in any case I
> expect it to load a dictionary that has already been loaded.
> So I
> suspect that the facet should only contain a key identifying the
> dictionary or a reference to it.
>
> Vicente
>
The process works this way (with Boost.Locale and even with std::locale.
Boost Locale.
------------
std::locale l=generator(""); // load dictionaries creates facets etc
std::cout.imbue(l);
l << as::time << time(0);
With std::locale
------------------
std::locale l(""); // load dictionaries create facets etc.
std::cout.imbue(l);
std::use_facet<std::time_put>(std::cout.getloc()).put(std::cout,std::cout,' ',localtime(time),'c',0);
All the data created when you create locale object. You don't alter it afterwards.
Now as C++ standard provided by default all facets even if l is C locale it will have facet you need.
But from user point of view you can fallback to something if custom locale facet is not installed.
I hope it is clear or we talk about different things
Artyom
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk