$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
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