$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
Subject: [boost] [io_base-utilities] Request for interest and/or comments.
From: Vicente J. Botet Escriba (vicente.botet_at_[hidden])
Date: 2012-05-28 09:51:36
Hi,
While refactoring the Boost.Chrono IO (version 2) I've created some
utilities that could be of general use.
* Manipulator Mixin
It is is based on
http://www.angelikalanger.com/Articles/Cuj/05.Manipulators/Manipulators.html.
http://svn.boost.org/svn/boost/trunk/boost/chrono/io/utility/manip_base.hpp
defines a class manip that can be used as follows
class mendl: public manip<mendl>
{
public:
explicit mendl(size_t how_many) :
count(how_many) {}
template <typename out_stream>
void operator()(out_stream &out) const
{
for (size_t line = 0; line < count; ++line)
{
out.put(out.widen('\n'));
}
out.flush();
}
private:
size_t count;
};
* std::ios_base Specific Pointers
std::ios_base allows to create specific pointers indexed by xalloc() and
retrieved by pword().
http://svn.boost.org/svn/boost/trunk/boost/chrono/io/utility/ios_base_state_ptr.hpp
defines a class ios_state_ptr class that provides the same interface
that a smart ptr with some minor adaptations to a std::ios_base.
template <typename Tag, typename T>
class ios_state_ptr;
The type T must be CopyConstructible. This class must be used as follows
struct mytag {}
struct myT {
int i;
};
ios_state_ptr<mytag, myT > ptr(ios);
if (! ptr) {
ptr.reset(new myT);
}
ptr->i =0;
This class is not thread_safe and should be protected as other io
functions if the user needs to use them in a multi-threaded environment;
The user can use also ios_state_ptr for classes T that are
DefaultConstructible, so that the type is created implicitly if not
already created.
ios_state_not_null_ptr<mytag, myT > ptr(ios);
ptr->i =0;
This class is not thread_safe.
Boost.Chrono use it as follows
namespace chrono {
namespace detail {
template<typename CharT>
struct ios_base_data_aux
{
std::basic_string<CharT> time_fmt;
std::basic_string<CharT> duration_fmt;
public:
ios_base_data_aux() :
time_fmt(""),
duration_fmt("")
{}
};
template<typename CharT>
struct ios_base_data {};
} // namespace detail
template<typename CharT>
static inline std::basic_string<CharT> get_time_fmt(std::ios_base &
ios)
{
ios_state_not_null_ptr<detail::ios_base_data<CharT>,
detail::ios_base_data_aux<CharT> > ptr(ios);
return ptr->time_fmt;
}
template<typename CharT>
static inline void set_time_fmt(std::ios_base& ios, std::basic_string<
CharT> const& fmt)
{
ios_state_not_null_ptr<detail::ios_base_data<CharT>,
detail::ios_base_data_aux<CharT> > ptr(ios);
ptr->time_fmt = fmt;
}
}
The internal single call to xalloc should be done before main() to be
thread safe. The library provide a initializer class
xalloc_key_initializer that takes as parameter a tag class.
namespace chrono { namespace detail {
namespace /**/ {
xalloc_key_initializer<detail::ios_base_data<char> >
ios_base_data_aux_xalloc_key_initializer;
xalloc_key_initializer<detail::ios_base_data<wchar_t> >
wios_base_data_aux_xalloc_key_initializer;
#if BOOST_CHRONO_HAS_UNICODE_SUPPORT
xalloc_key_initializer<detail::ios_base_data<char16_t> >
u16ios_base_data_aux_xalloc_key_initializer;
xalloc_key_initializer<detail::ios_base_data<char32_t> >
u32ios_base_data_aux_xalloc_key_initializer;
#endif
} // namespace
} }
* ios_flags
ios_base allows also to create specific pointers indexed by xalloc() and
retrieved by iword().
http://svn.boost.org/svn/boost/trunk/boost/chrono/io/utility/ios_base_state_ptr.hpp
defines a class
template <typename Final>
class ios_flags;
providing an interface similar to "27.5.3.2 ios_base state functions
[fmtflags.state]
fmtflags flags() const;
Returns: The format control information for both input and output.
fmtflags flags(fmtflags fmtfl);
Postcondition: fmtfl == flags().
Returns: The previous value of flags().
fmtflags setf(fmtflags fmtfl);
Effects: Sets fmtfl in flags().
Returns: The previous value of flags().
fmtflags setf(fmtflags fmtfl, fmtflags mask);
Effects: Clears mask in flags(), sets fmtfl & mask in flags().
Returns: The previous value of flags().
void unsetf(fmtflags mask);
Effects: Clears mask in flags()
"
and that creates implicitly the index of the ios_base::iword() function
once for a specific ios_flags<Final>.
For example, Boost.Chrono use it as follows to store the use_symbol and
use_local flags.
class fmt_masks : public ios_flags<fmt_masks>
{
typedef ios_flags<fmt_masks> base_type;
public:
fmt_masks(std::ios_base& ios): base_type(ios) {}
enum type
{
uses_symbol = 1 << 0,
uses_local = 1 << 1
};
duration_style get_duration_style()
{
return (flags() & uses_symbol) ? duration_style::symbol :
duration_style::prefix;
}
void set_duration_style(duration_style style)
{
if (style == duration_style::symbol)
setf(uses_symbol);
else
unsetf(uses_symbol);
}
timezone get_timezone()
{
return (flags() & uses_local) ? timezone::local : timezone::utc;
}
void set_timezone(timezone tz)
{
if (tz == timezone::local)
setf(uses_local);
else
unsetf(uses_local);
}
};
The internal single call to xalloc should be done before main() to be
thread safe. The library provide a initializer class
namespace detail
{
namespace /**/ {
xalloc_key_initializer<fmt_masks >
fmt_masks_xalloc_key_initializer;
} // namespace
} // namespace detail
Do you see a design flaw on the design of these classes?
Is there an interest to include them in Boost? Could these classes be
associated iostreams?
Best,
Vicente