Boost logo

Boost :

Subject: Re: [boost] [iostreams][io_state_savers] Request for interest in some ios_base basic utilities
From: Vicente J. Botet Escriba (vicente.botet_at_[hidden])
Date: 2011-11-10 18:09:58


Le 10/11/11 23:18, Artyom Beilis a écrit :
>> 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
>
Your last example is exactly the context to which I was referring to.
The user needs to install some specific facets that depend on the
locale, as the standard locale doesn't do it for you.

So the question is. How can you associate a specific facet when you
change the locale of a stream. I know that we can register callbacks for
a specific ios_base, but what I think is needed is to register a
callback for any ios_base object.

Another way to see this problem is as follows. As you said , when there
is no specific facet associated to the locale of a ios_base, no need to
instal one, just take a default behavior. It would be great if the
default behavior could be configured either depending on the locale name
or as a global default facet that could be set by the user.

I don't know if my concerns are more clear now.

Thanks again,
Vicente


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk