
----- Original Message -----
From: Vicente Botet <vicente.botet@wanadoo.fr>
however the second part the "state saver" is something very important.
In fact today Boost.DateTime uses for example locale facet to provide such information which is wrong by design. If such state saver was around when it created it would be much better.
Yes, Boost.Chrono I/O V1 is using this design also. I'm creating a Boost.Chrono v2 design that stores information like duration style, timezone, time format in the ios state.
On thing - boost.locale already does all this. I mean there is manipulators to handle time zone, time formats and other things. I'd suggest to take a look on them. Because this may be all you need. Also it can be extended with some new styles easily if needed like for example "duration" style. So I'd suggest to use them.
The inconvenient is the thread safety and inter-module interferences. I think that the locale/facet approach doesn't suffer from these thread and inter-module issues. What do you think?
No, it has exactly the same problem... The locale facet approach is not correct for other reason. Locale/facet object should hold general rules and methods of handling data and its facets are shared among multiple instances of std::(i|o)stream objects. For that reason std::use_facet<Foo> returns Foo const & and not mutable reference. Now iostream flags should hold (and hold) user specific data like how to format date/time, number according to rules and they are stream specific not locale specific.
Anyway the IOStream library is not thread safe, so the user can not use them without falling in undefined behavior.
Actually most iostream implementations are thread safe - not in terms that same object can be accessed from two threads but rather things that are expected to be accessed from different threads like xalloc. For example xalloc is thread safe in both MSVC and GCC libraries.
So my +1 and big one.
Now some important (extremely important) notes about this code: ---------------------------------------------------------------
static inline int index() { static const int v_ = std::ios_base::xalloc(); return v_; }
1. This code may be not thread safe and may create two different values for two different threads.
So I'd suggest to provide some global initialization option to at least illeminate somehow this problem or to use Boost.Thread's ones initialization.
I agree, the code is not thread safe.
2. This code can't be used on cross dll boundaries.
Consider you have function (non-linline) boost::foo::bar in libboost_foo.dll that updates manipulator in the exe other inline function boost::foo::baz uses it.
You'll be surprised what will happen: the "static const int v_" in the index() function would have two instances and would allocate two distinct indexes.
I know these issues. The final implementation would need a kind of thread safe and multi DLL singleton, maybe based on the holder included in Boost.Flyweight.
I don't know if chrono is header only library or not. Just you need to make sure that such library can't be header only. As long as it is not header only there will be no such problem.
3. You should never use it with static linked runtime and dlls (of course) because there will be two instances of xalloc()'s counter.
But this is related to gcc 4.4 and below on Windows only.
So library should be very careful and not use such smart pointer in inline instances and this should be written with big red letters in the top of the library docs.
Well I see two alternatives here: either the library state that this can be used in a single threaded program and in a single module, or it is thread and intermodule safe.
Yes, unfortunately it is the limitation.
That is why Boost.Locale's ios_prop.hpp is hidden in sources.
How the fact to hide it makes it more thread or module safe. Could you clarify this?
Because, I can initialize all at once and don't live to user an option to choose when to do it. However once all "static" variables are ready there no more thread issues. For example all locale ids and all xalloc ids are initialized once globally.
(Yep... dll platforms sucks... :-) or make our work a way much harder)
Yes, and unfortunately this is something we need to live with :(
Best, Vicente
Regards, Artyom Beilis -------------- CppCMS - C++ Web Framework: http://cppcms.sf.net/ CppDB - C++ SQL Connectivity: http://cppcms.sf.net/sql/cppdb/