early-access version 3088

This commit is contained in:
pineappleEA
2022-11-05 15:35:56 +01:00
parent 4e4fc25ce3
commit b601909c6d
35519 changed files with 5996896 additions and 860 deletions

View File

@@ -0,0 +1,591 @@
// (C) Copyright Howard Hinnant
// (C) Copyright 2011 Vicente J. Botet Escriba
// Use, modification and distribution are subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt).
//
#ifndef BOOST_CHRONO_IO_DURATION_GET_HPP
#define BOOST_CHRONO_IO_DURATION_GET_HPP
#include <boost/chrono/config.hpp>
#include <string>
#include <boost/type_traits/is_scalar.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_signed.hpp>
#include <boost/mpl/if.hpp>
#include <boost/integer/common_factor_rt.hpp>
#include <boost/chrono/detail/scan_keyword.hpp>
#include <boost/chrono/detail/no_warning/signed_unsigned_cmp.hpp>
#include <boost/chrono/process_cpu_clocks.hpp>
#include <boost/assert.hpp>
#include <locale>
/**
* Duration formatting facet for input.
*/
namespace boost
{
namespace chrono
{
namespace detail
{
template <class Rep, bool = is_scalar<Rep>::value>
struct duration_io_intermediate
{
typedef Rep type;
};
template <class Rep>
struct duration_io_intermediate<Rep, true>
{
typedef typename mpl::if_c<is_floating_point<Rep>::value, long double, typename mpl::if_c<
is_signed<Rep>::value, long long, unsigned long long>::type>::type type;
};
template <class Rep>
struct duration_io_intermediate<process_times<Rep>, false>
{
typedef process_times<typename duration_io_intermediate<Rep>::type> type;
};
template <typename intermediate_type>
typename enable_if<is_integral<intermediate_type> , bool>::type reduce(intermediate_type& r,
unsigned long long& den, std::ios_base::iostate& err)
{
typedef typename common_type<intermediate_type, unsigned long long>::type common_type_t;
// Reduce r * num / den
common_type_t t = integer::gcd<common_type_t>(common_type_t(r), common_type_t(den));
r /= t;
den /= t;
if (den != 1)
{
// Conversion to Period is integral and not exact
err |= std::ios_base::failbit;
return false;
}
return true;
}
template <typename intermediate_type>
typename disable_if<is_integral<intermediate_type> , bool>::type reduce(intermediate_type&, unsigned long long&,
std::ios_base::iostate&)
{
return true;
}
}
/**
* @c duration_get is used to parse a character sequence, extracting
* components of a duration into a class duration.
* Each get member parses a format as produced by a corresponding format specifier to time_put<>::put.
* If the sequence being parsed matches the correct format, the
* corresponding member of the class duration argument are set to the
* value used to produce the sequence;
* otherwise either an error is reported or unspecified values are assigned.
* In other words, user confirmation is required for reliable parsing of
* user-entered durations, but machine-generated formats can be parsed
* reliably. This allows parsers to be aggressive about interpreting user
* variations on standard formats.
*
* If the end iterator is reached during parsing of the get() member
* function, the member sets std::ios_base::eofbit in err.
*/
template <class CharT, class InputIterator = std::istreambuf_iterator<CharT> >
class duration_get: public std::locale::facet
{
public:
/**
* Type of character the facet is instantiated on.
*/
typedef CharT char_type;
/**
* Type of character string passed to member functions.
*/
typedef std::basic_string<CharT> string_type;
/**
* Type of iterator used to scan the character buffer.
*/
typedef InputIterator iter_type;
/**
* Construct a @c duration_get facet.
* @param refs
* @Effects Construct a @c duration_get facet.
* If the @c refs argument is @c 0 then destruction of the object is
* delegated to the @c locale, or locales, containing it. This allows
* the user to ignore lifetime management issues. On the other had,
* if @c refs is @c 1 then the object must be explicitly deleted;
* the @c locale will not do so. In this case, the object can be
* maintained across the lifetime of multiple locales.
*/
explicit duration_get(size_t refs = 0) :
std::locale::facet(refs)
{
}
/**
* @param s start input stream iterator
* @param end end input stream iterator
* @param ios a reference to a ios_base
* @param err the ios_base state
* @param d the duration
* @param pattern begin of the formatting pattern
* @param pat_end end of the formatting pattern
*
* Requires: [pattern,pat_end) shall be a valid range.
*
* Effects: The function starts by evaluating err = std::ios_base::goodbit.
* It then enters a loop, reading zero or more characters from s at
* each iteration. Unless otherwise specified below, the loop
* terminates when the first of the following conditions holds:
* - The expression pattern == pat_end evaluates to true.
* - The expression err == std::ios_base::goodbit evaluates to false.
* - The expression s == end evaluates to true, in which case the
* function evaluates err = std::ios_base::eofbit | std::ios_base::failbit.
* - The next element of pattern is equal to '%', followed by a conversion
* specifier character, format.
* If the number of elements in the range [pattern,pat_end) is not
* sufficient to unambiguously determine whether the conversion
* specification is complete and valid, the function evaluates
* err = std::ios_base::failbit. Otherwise, the function evaluates
* s = get_value(s, end, ios, err, r) when the conversion specification is 'v' and
* s = get_value(s, end, ios, err, rt) when the conversion specification is 'u'.
* If err == std::ios_base::goodbit holds after
* the evaluation of the expression, the function increments pattern to
* point just past the end of the conversion specification and continues
* looping.
* - The expression isspace(*pattern, ios.getloc()) evaluates to true, in
* which case the function first increments pattern until
* pattern == pat_end || !isspace(*pattern, ios.getloc()) evaluates to true,
* then advances s until s == end || !isspace(*s, ios.getloc()) is true,
* and finally resumes looping.
* - The next character read from s matches the element pointed to by
* pattern in a case-insensitive comparison, in which case the function
* evaluates ++pattern, ++s and continues looping. Otherwise, the function
* evaluates err = std::ios_base::failbit.
*
* Once r and rt are retrieved,
* Returns: s
*/
template <typename Rep, typename Period>
iter_type get(iter_type s, iter_type end, std::ios_base& ios, std::ios_base::iostate& err,
duration<Rep, Period> &d, const char_type *pattern, const char_type *pat_end) const
{
if (std::has_facet<duration_units<CharT> >(ios.getloc()))
{
duration_units<CharT> const&facet = std::use_facet<duration_units<CharT> >(ios.getloc());
return get(facet, s, end, ios, err, d, pattern, pat_end);
}
else
{
duration_units_default<CharT> facet;
return get(facet, s, end, ios, err, d, pattern, pat_end);
}
}
template <typename Rep, typename Period>
iter_type get(duration_units<CharT> const&facet, iter_type s, iter_type end, std::ios_base& ios,
std::ios_base::iostate& err, duration<Rep, Period> &d, const char_type *pattern, const char_type *pat_end) const
{
typedef typename detail::duration_io_intermediate<Rep>::type intermediate_type;
intermediate_type r;
rt_ratio rt;
bool value_found = false, unit_found = false;
const std::ctype<char_type>& ct = std::use_facet<std::ctype<char_type> >(ios.getloc());
while (pattern != pat_end && err == std::ios_base::goodbit)
{
if (s == end)
{
err |= std::ios_base::eofbit;
break;
}
if (ct.narrow(*pattern, 0) == '%')
{
if (++pattern == pat_end)
{
err |= std::ios_base::failbit;
return s;
}
char cmd = ct.narrow(*pattern, 0);
switch (cmd)
{
case 'v':
{
if (value_found)
{
err |= std::ios_base::failbit;
return s;
}
value_found = true;
s = get_value(s, end, ios, err, r);
if (err & (std::ios_base::badbit | std::ios_base::failbit))
{
return s;
}
break;
}
case 'u':
{
if (unit_found)
{
err |= std::ios_base::failbit;
return s;
}
unit_found = true;
s = get_unit(facet, s, end, ios, err, rt);
if (err & (std::ios_base::badbit | std::ios_base::failbit))
{
return s;
}
break;
}
default:
BOOST_ASSERT(false && "Boost::Chrono internal error.");
break;
}
++pattern;
}
else if (ct.is(std::ctype_base::space, *pattern))
{
for (++pattern; pattern != pat_end && ct.is(std::ctype_base::space, *pattern); ++pattern)
;
for (; s != end && ct.is(std::ctype_base::space, *s); ++s)
;
}
else if (ct.toupper(*s) == ct.toupper(*pattern))
{
++s;
++pattern;
}
else
{
err |= std::ios_base::failbit;
return s;
}
}
unsigned long long num = rt.num;
unsigned long long den = rt.den;
// r should be multiplied by (num/den) / Period
// Reduce (num/den) / Period to lowest terms
unsigned long long gcd_n1_n2 = integer::gcd<unsigned long long>(num, Period::num);
unsigned long long gcd_d1_d2 = integer::gcd<unsigned long long>(den, Period::den);
num /= gcd_n1_n2;
den /= gcd_d1_d2;
unsigned long long n2 = Period::num / gcd_n1_n2;
unsigned long long d2 = Period::den / gcd_d1_d2;
if (num > (std::numeric_limits<unsigned long long>::max)() / d2 || den
> (std::numeric_limits<unsigned long long>::max)() / n2)
{
// (num/den) / Period overflows
err |= std::ios_base::failbit;
return s;
}
num *= d2;
den *= n2;
typedef typename common_type<intermediate_type, unsigned long long>::type common_type_t;
// num / den is now factor to multiply by r
if (!detail::reduce(r, den, err)) return s;
if (chrono::detail::gt(r, ( (duration_values<common_type_t>::max)() / num)))
{
// Conversion to Period overflowed
err |= std::ios_base::failbit;
return s;
}
common_type_t t = r * num;
t /= den;
if (t > duration_values<common_type_t>::zero())
{
if ( (duration_values<Rep>::max)() < Rep(t))
{
// Conversion to Period overflowed
err |= std::ios_base::failbit;
return s;
}
}
// Success! Store it.
d = duration<Rep, Period> (Rep(t));
return s;
}
/**
*
* @param s start input stream iterator
* @param end end input stream iterator
* @param ios a reference to a ios_base
* @param err the ios_base state
* @param d the duration
* Stores the duration pattern from the @c duration_unit facet in let say @c str. Last as if
* @code
* return get(s, end, ios, err, ios, d, str.data(), str.data() + str.size());
* @codeend
* @Returns An iterator pointing just beyond the last character that can be determined to be part of a valid name
*/
template <typename Rep, typename Period>
iter_type get(iter_type s, iter_type end, std::ios_base& ios, std::ios_base::iostate& err,
duration<Rep, Period> & d) const
{
if (std::has_facet<duration_units<CharT> >(ios.getloc()))
{
duration_units<CharT> const&facet = std::use_facet<duration_units<CharT> >(ios.getloc());
std::basic_string<CharT> str = facet.get_pattern();
return get(facet, s, end, ios, err, d, str.data(), str.data() + str.size());
}
else
{
duration_units_default<CharT> facet;
std::basic_string<CharT> str = facet.get_pattern();
return get(facet, s, end, ios, err, d, str.data(), str.data() + str.size());
}
}
/**
*
* @param s start input stream iterator
* @param end end input stream iterator
* @param ios a reference to a ios_base
* @param err the ios_base state
* @param r a reference to the duration representation.
* @Effects As if
* @code
* return std::use_facet<std::num_get<cahr_type, iter_type> >(ios.getloc()).get(s, end, ios, err, r);
* @endcode
*
* @Returns An iterator pointing just beyond the last character that can be determined to be part of a valid name
*/
template <typename Rep>
iter_type get_value(iter_type s, iter_type end, std::ios_base& ios, std::ios_base::iostate& err, Rep& r) const
{
return std::use_facet<std::num_get<CharT, iter_type> >(ios.getloc()).get(s, end, ios, err, r);
}
template <typename Rep>
iter_type get_value(iter_type s, iter_type end, std::ios_base& ios, std::ios_base::iostate& err, process_times<Rep>& r) const
{
if (s == end) {
err |= std::ios_base::eofbit;
return s;
} else if (*s != '{') { // mandatory '{'
err |= std::ios_base::failbit;
return s;
}
++s;
s = std::use_facet<std::num_get<CharT, iter_type> >(ios.getloc()).get(s, end, ios, err, r.real);
if (s == end) {
err |= std::ios_base::eofbit;
return s;
} else if (*s != ';') { // mandatory ';'
err |= std::ios_base::failbit;
return s;
}
++s;
s = std::use_facet<std::num_get<CharT, iter_type> >(ios.getloc()).get(s, end, ios, err, r.user);
if (s == end) {
err |= std::ios_base::eofbit;
return s;
} else if (*s != ';') { // mandatory ';'
err |= std::ios_base::failbit;
return s;
}
++s;
s = std::use_facet<std::num_get<CharT, iter_type> >(ios.getloc()).get(s, end, ios, err, r.system);
if (s == end) {
err |= std::ios_base::eofbit;
return s;
} else if (*s != '}') { // mandatory '}'
err |= std::ios_base::failbit;
return s;
}
return s;
}
/**
*
* @param s start input stream iterator
* @param e end input stream iterator
* @param ios a reference to a ios_base
* @param err the ios_base state
* @param rt a reference to the duration run-time ratio.
* @Returns An iterator pointing just beyond the last character that can be determined to be part of a valid name
*/
iter_type get_unit(iter_type i, iter_type e, std::ios_base& is, std::ios_base::iostate& err, rt_ratio &rt) const
{
if (std::has_facet<duration_units<CharT> >(is.getloc()))
{
return get_unit(std::use_facet<duration_units<CharT> >(is.getloc()), i, e, is, err, rt);
}
else
{
duration_units_default<CharT> facet;
return get_unit(facet, i, e, is, err, rt);
}
}
iter_type get_unit(duration_units<CharT> const &facet, iter_type i, iter_type e, std::ios_base& is,
std::ios_base::iostate& err, rt_ratio &rt) const
{
if (*i == '[')
{
// parse [N/D]s or [N/D]second or [N/D]seconds format
++i;
i = std::use_facet<std::num_get<CharT, iter_type> >(is.getloc()).get(i, e, is, err, rt.num);
if ( (err & std::ios_base::failbit) != 0)
{
return i;
}
if (i == e)
{
err |= std::ios_base::failbit;
return i;
}
CharT x = *i++;
if (x != '/')
{
err |= std::ios_base::failbit;
return i;
}
i = std::use_facet<std::num_get<CharT, iter_type> >(is.getloc()).get(i, e, is, err, rt.den);
if ( (err & std::ios_base::failbit) != 0)
{
return i;
}
if (i == e)
{
err |= std::ios_base::failbit;
return i;
}
if (*i != ']')
{
err |= std::ios_base::failbit;
return i;
}
++i;
if (i == e)
{
err |= std::ios_base::failbit;
return i;
}
// parse s or second or seconds
return do_get_n_d_valid_unit(facet, i, e, is, err);
}
else
{
return do_get_valid_unit(facet, i, e, is, err, rt);
}
}
/**
* Unique identifier for this type of facet.
*/
static std::locale::id id;
/**
* @Effects Destroy the facet
*/
~duration_get()
{
}
protected:
/**
* Extracts the run-time ratio associated to the duration when it is given in prefix form.
*
* This is an extension point of this facet so that we can take in account other periods that can have a useful
* translation in other contexts, as e.g. days and weeks.
*
* @param facet the duration_units facet
* @param i start input stream iterator.
* @param e end input stream iterator.
* @param ios a reference to a ios_base.
* @param err the ios_base state.
* @return @c s
*/
iter_type do_get_n_d_valid_unit(duration_units<CharT> const &facet, iter_type i, iter_type e,
std::ios_base&, std::ios_base::iostate& err) const
{
// parse SI name, short or long
const string_type* units = facet.get_n_d_valid_units_start();
const string_type* units_end = facet.get_n_d_valid_units_end();
const string_type* k = chrono_detail::scan_keyword(i, e, units, units_end,
//~ std::use_facet<std::ctype<CharT> >(loc),
err);
if (err & (std::ios_base::badbit | std::ios_base::failbit))
{
return i;
}
if (!facet.match_n_d_valid_unit(k))
{
err |= std::ios_base::failbit;
}
return i;
}
/**
* Extracts the run-time ratio associated to the duration when it is given in prefix form.
*
* This is an extension point of this facet so that we can take in account other periods that can have a useful
* translation in other contexts, as e.g. days and weeks.
*
* @param facet the duration_units facet
* @param i start input stream iterator.
* @param e end input stream iterator.
* @param ios a reference to a ios_base.
* @param err the ios_base state.
* @param rt a reference to the duration run-time ratio.
* @Effects
* @Returns An iterator pointing just beyond the last character that can be determined to be part of a valid name.
*/
iter_type do_get_valid_unit(duration_units<CharT> const &facet, iter_type i, iter_type e,
std::ios_base&, std::ios_base::iostate& err, rt_ratio &rt) const
{
// parse SI name, short or long
const string_type* units = facet.get_valid_units_start();
const string_type* units_end = facet.get_valid_units_end();
err = std::ios_base::goodbit;
const string_type* k = chrono_detail::scan_keyword(i, e, units, units_end,
//~ std::use_facet<std::ctype<CharT> >(loc),
err);
if (err & (std::ios_base::badbit | std::ios_base::failbit))
{
return i;
}
if (!facet.match_valid_unit(k, rt))
{
err |= std::ios_base::failbit;
}
return i;
}
};
/**
* Unique identifier for this type of facet.
*/
template <class CharT, class InputIterator>
std::locale::id duration_get<CharT, InputIterator>::id;
} // chrono
}
// boost
#endif // header

View File

@@ -0,0 +1,295 @@
// (C) Copyright Howard Hinnant
// (C) Copyright 2011 Vicente J. Botet Escriba
// Use, modification and distribution are subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt).
//
// This code was adapted by Vicente from Howard Hinnant's experimental work
// on chrono i/o to Boost
#ifndef BOOST_CHRONO_IO_DURATION_IO_HPP
#define BOOST_CHRONO_IO_DURATION_IO_HPP
#include <boost/chrono/duration.hpp>
#include <boost/ratio/ratio_io.hpp>
#include <boost/chrono/io/duration_style.hpp>
#include <boost/chrono/io/ios_base_state.hpp>
#include <boost/chrono/io/duration_put.hpp>
#include <boost/chrono/io/duration_get.hpp>
#include <boost/chrono/io/utility/manip_base.hpp>
#include <boost/core/no_exceptions_support.hpp>
#include <boost/type_traits/is_integral.hpp>
#include <boost/type_traits/is_floating_point.hpp>
#include <locale>
#include <iosfwd>
#include <sstream>
namespace boost
{
namespace chrono
{
/**
* duration parameterized manipulator.
*/
class duration_fmt: public manip<duration_fmt>
{
duration_style style_;
public:
/**
* explicit manipulator constructor from a @c duration_style
*/
explicit duration_fmt(duration_style style)BOOST_NOEXCEPT
: style_(style)
{}
/**
* Change the duration_style ios state;
*/
void operator()(std::ios_base &ios) const
{
set_duration_style(ios, style_);
}
};
/**
* duration_style i/o saver.
*
* See Boost.IO i/o state savers for a motivating compression.
*/
struct duration_style_io_saver
{
//! the type of the state to restore
typedef std::ios_base state_type;
//! the type of aspect to save
typedef duration_style aspect_type;
/**
* Explicit construction from an i/o stream.
*
* Store a reference to the i/o stream and the value of the associated @c duration_style.
*/
explicit duration_style_io_saver(state_type &s) :
s_save_(s), a_save_(get_duration_style(s))
{
}
/**
* Construction from an i/o stream and a @c duration_style to restore.
*
* Stores a reference to the i/o stream and the value @c new_value @c duration_style to set.
*/
duration_style_io_saver(state_type &s, aspect_type new_value) :
s_save_(s), a_save_(get_duration_style(s))
{
set_duration_style(s, new_value);
}
/**
* Destructor.
*
* Restores the i/o stream with the duration_style to be restored.
*/
~duration_style_io_saver()
{
this->restore();
}
/**
* Restores the i/o stream with the duration_style to be restored.
*/
void restore()
{
set_duration_style(s_save_, a_save_);
}
private:
duration_style_io_saver& operator=(duration_style_io_saver const& rhs) ;
state_type& s_save_;
aspect_type a_save_;
};
template <class Rep>
struct duration_put_enabled
: integral_constant<bool,
is_integral<Rep>::value || is_floating_point<Rep>::value
>
{};
/**
* duration stream inserter
* @param os the output stream
* @param d to value to insert
* @return @c os
*/
template <class CharT, class Traits, class Rep, class Period>
typename boost::enable_if_c< ! duration_put_enabled<Rep>::value, std::basic_ostream<CharT, Traits>& >::type
operator<<(std::basic_ostream<CharT, Traits>& os, const duration<Rep, Period>& d)
{
std::basic_ostringstream<CharT, Traits> ostr;
ostr << d.count();
duration<int, Period> dd(0);
bool failed = false;
BOOST_TRY
{
std::ios_base::iostate err = std::ios_base::goodbit;
BOOST_TRY
{
typename std::basic_ostream<CharT, Traits>::sentry opfx(os);
if (bool(opfx))
{
if (!std::has_facet<duration_put<CharT> >(os.getloc()))
{
if (duration_put<CharT> ().put(os, os, os.fill(), dd, ostr.str().c_str()) .failed())
{
err = std::ios_base::badbit;
}
}
else if (std::use_facet<duration_put<CharT> >(os.getloc()) .put(os, os, os.fill(), dd, ostr.str().c_str()) .failed())
{
err = std::ios_base::badbit;
}
os.width(0);
}
}
BOOST_CATCH(...)
{
bool flag = false;
BOOST_TRY
{
os.setstate(std::ios_base::failbit);
}
BOOST_CATCH (std::ios_base::failure )
{
flag = true;
}
BOOST_CATCH_END
if (flag) throw;
}
BOOST_CATCH_END
if (err) os.setstate(err);
return os;
}
BOOST_CATCH(...)
{
failed = true;
}
BOOST_CATCH_END
if (failed) os.setstate(std::ios_base::failbit | std::ios_base::badbit);
return os;
}
template <class CharT, class Traits, class Rep, class Period>
typename boost::enable_if_c< duration_put_enabled<Rep>::value, std::basic_ostream<CharT, Traits>& >::type
operator<<(std::basic_ostream<CharT, Traits>& os, const duration<Rep, Period>& d)
{
bool failed = false;
BOOST_TRY
{
std::ios_base::iostate err = std::ios_base::goodbit;
BOOST_TRY
{
typename std::basic_ostream<CharT, Traits>::sentry opfx(os);
if (bool(opfx))
{
if (!std::has_facet<duration_put<CharT> >(os.getloc()))
{
if (duration_put<CharT> ().put(os, os, os.fill(), d) .failed())
{
err = std::ios_base::badbit;
}
}
else if (std::use_facet<duration_put<CharT> >(os.getloc()) .put(os, os, os.fill(), d) .failed())
{
err = std::ios_base::badbit;
}
os.width(0);
}
}
BOOST_CATCH(...)
{
bool flag = false;
BOOST_TRY
{
os.setstate(std::ios_base::failbit);
}
BOOST_CATCH (std::ios_base::failure )
{
flag = true;
}
BOOST_CATCH_END
if (flag) throw;
}
BOOST_CATCH_END
if (err) os.setstate(err);
return os;
}
BOOST_CATCH(...)
{
failed = true;
}
BOOST_CATCH_END
if (failed) os.setstate(std::ios_base::failbit | std::ios_base::badbit);
return os;
}
/**
*
* @param is the input stream
* @param d the duration
* @return @c is
*/
template <class CharT, class Traits, class Rep, class Period>
std::basic_istream<CharT, Traits>&
operator>>(std::basic_istream<CharT, Traits>& is, duration<Rep, Period>& d)
{
std::ios_base::iostate err = std::ios_base::goodbit;
BOOST_TRY
{
typename std::basic_istream<CharT, Traits>::sentry ipfx(is);
if (bool(ipfx))
{
if (!std::has_facet<duration_get<CharT> >(is.getloc()))
{
duration_get<CharT> ().get(is, std::istreambuf_iterator<CharT, Traits>(), is, err, d);
}
else
{
std::use_facet<duration_get<CharT> >(is.getloc()) .get(is, std::istreambuf_iterator<CharT, Traits>(), is,
err, d);
}
}
}
BOOST_CATCH (...)
{
bool flag = false;
BOOST_TRY
{
is.setstate(std::ios_base::failbit);
}
BOOST_CATCH (std::ios_base::failure )
{
flag = true;
}
BOOST_CATCH_END
if (flag) { BOOST_RETHROW }
}
BOOST_CATCH_END
if (err) is.setstate(err);
return is;
}
} // chrono
}
#endif // header

View File

@@ -0,0 +1,317 @@
// (C) Copyright Howard Hinnant
// (C) Copyright 2011 Vicente J. Botet Escriba
// Use, modification and distribution are subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt).
//
/**
* Duration formatting facet for output.
*/
#ifndef BOOST_CHRONO_IO_DURATION_PUT_HPP
#define BOOST_CHRONO_IO_DURATION_PUT_HPP
#include <boost/chrono/config.hpp>
#include <boost/chrono/io/duration_units.hpp>
#include <boost/chrono/process_cpu_clocks.hpp>
#include <boost/assert.hpp>
#include <locale>
namespace boost
{
namespace chrono
{
namespace detail
{
template <class T>
struct propagate {
typedef T type;
};
template <>
struct propagate<boost::int_least32_t> {
typedef boost::int_least64_t type;
};
}
/**
* @tparam ChatT a character type
* @tparam OutputIterator a model of @c OutputIterator
*
* The @c duration_put facet provides facilities for formatted output of duration values.
* The member function of @c duration_put take a duration and format it into character string representation.
*
*/
template <class CharT, class OutputIterator = std::ostreambuf_iterator<CharT> >
class duration_put: public std::locale::facet
{
public:
/**
* Type of character the facet is instantiated on.
*/
typedef CharT char_type;
/**
* Type of character string passed to member functions.
*/
typedef std::basic_string<CharT> string_type;
/**
* Type of iterator used to write in the character buffer.
*/
typedef OutputIterator iter_type;
/**
* Construct a duration_put facet.
* @param refs
* @Effects Construct a duration_put facet.
* If the @c refs argument is @c 0 then destruction of the object is
* delegated to the @c locale, or locales, containing it. This allows
* the user to ignore lifetime management issues. On the other had,
* if @c refs is @c 1 then the object must be explicitly deleted;
* the @c locale will not do so. In this case, the object can be
* maintained across the lifetime of multiple locales.
*/
explicit duration_put(size_t refs = 0) :
std::locale::facet(refs)
{
}
/**
*
* @param s an output stream iterator
* @param ios a reference to a ios_base
* @param fill the character used as filler
* @param d the duration
* @param pattern begin of the formatting pattern
* @param pat_end end of the formatting pattern
*
* @Effects Steps through the sequence from @c pattern to @c pat_end,
* identifying characters that are part of a pattern sequence. Each character
* that is not part of a pattern sequence is written to @c s immediately, and
* each pattern sequence, as it is identified, results in a call to
* @c put_value or @c put_unit;
* thus, pattern elements and other characters are interleaved in the output
* in the order in which they appear in the pattern. Pattern sequences are
* identified by converting each character @c c to a @c char value as if by
* @c ct.narrow(c,0), where @c ct is a reference to @c ctype<charT> obtained from
* @c ios.getloc(). The first character of each sequence is equal to @c '%',
* followed by a pattern specifier character @c spec, which can be @c 'v' for
* the duration value or @c 'u' for the duration unit. .
* For each valid pattern sequence identified, calls
* <c>put_value(s, ios, fill, d)</c> or <c>put_unit(s, ios, fill, d)</c>.
*
* @Returns An iterator pointing immediately after the last character produced.
*/
template <typename Rep, typename Period>
iter_type put(iter_type s, std::ios_base& ios, char_type fill, duration<Rep, Period> const& d, const CharT* pattern,
const CharT* pat_end, const char_type* val = 0) const
{
if (std::has_facet<duration_units<CharT> >(ios.getloc()))
{
duration_units<CharT> const&facet = std::use_facet<duration_units<CharT> >(
ios.getloc());
return put(facet, s, ios, fill, d, pattern, pat_end, val);
}
else
{
duration_units_default<CharT> facet;
return put(facet, s, ios, fill, d, pattern, pat_end, val);
}
}
template <typename Rep, typename Period>
iter_type put(duration_units<CharT> const& units_facet, iter_type s, std::ios_base& ios, char_type fill,
duration<Rep, Period> const& d, const CharT* pattern, const CharT* pat_end, const char_type* val = 0) const
{
const std::ctype<char_type>& ct = std::use_facet<std::ctype<char_type> >(ios.getloc());
for (; pattern != pat_end; ++pattern)
{
if (ct.narrow(*pattern, 0) == '%')
{
if (++pattern == pat_end)
{
*s++ = pattern[-1];
break;
}
char fmt = ct.narrow(*pattern, 0);
switch (fmt)
{
case 'v':
{
s = put_value(s, ios, fill, d, val);
break;
}
case 'u':
{
s = put_unit(units_facet, s, ios, fill, d);
break;
}
default:
BOOST_ASSERT(false && "Boost::Chrono internal error.");
break;
}
}
else
*s++ = *pattern;
}
return s;
}
/**
*
* @param s an output stream iterator
* @param ios a reference to a ios_base
* @param fill the character used as filler
* @param d the duration
* @Effects imbue in @c ios the @c duration_units_default facet if not already present.
* Retrieves Stores the duration pattern from the @c duration_unit facet in let say @c str. Last as if
* @code
* return put(s, ios, d, str.data(), str.data() + str.size());
* @endcode
* @Returns An iterator pointing immediately after the last character produced.
*/
template <typename Rep, typename Period>
iter_type put(iter_type s, std::ios_base& ios, char_type fill, duration<Rep, Period> const& d, const char_type* val = 0) const
{
if (std::has_facet<duration_units<CharT> >(ios.getloc()))
{
duration_units<CharT> const&facet = std::use_facet<duration_units<CharT> >(
ios.getloc());
std::basic_string<CharT> str = facet.get_pattern();
return put(facet, s, ios, fill, d, str.data(), str.data() + str.size(), val);
}
else
{
duration_units_default<CharT> facet;
std::basic_string<CharT> str = facet.get_pattern();
return put(facet, s, ios, fill, d, str.data(), str.data() + str.size(), val);
}
}
/**
*
* @param s an output stream iterator
* @param ios a reference to a ios_base
* @param fill the character used as filler
* @param d the duration
* @Effects As if s=std::use_facet<std::num_put<CharT, iter_type> >(ios.getloc()).put(s, ios, fill, static_cast<long int> (d.count())).
* @Returns s, iterator pointing immediately after the last character produced.
*/
template <typename Rep, typename Period>
iter_type put_value(iter_type s, std::ios_base& ios, char_type fill, duration<Rep, Period> const& d, const char_type* val = 0) const
{
if (val)
{
while (*val) {
*s = *val;
s++; val++;
}
return s;
}
return std::use_facet<std::num_put<CharT, iter_type> >(ios.getloc()).put(s, ios, fill,
static_cast<typename detail::propagate<Rep>::type> (d.count()));
}
template <typename Rep, typename Period>
iter_type put_value(iter_type s, std::ios_base& ios, char_type fill, duration<process_times<Rep>, Period> const& d, const char_type* = 0) const
{
*s++ = CharT('{');
s = put_value(s, ios, fill, process_real_cpu_clock::duration(d.count().real));
*s++ = CharT(';');
s = put_value(s, ios, fill, process_user_cpu_clock::duration(d.count().user));
*s++ = CharT(';');
s = put_value(s, ios, fill, process_system_cpu_clock::duration(d.count().system));
*s++ = CharT('}');
return s;
}
/**
*
* @param s an output stream iterator
* @param ios a reference to a ios_base
* @param fill the character used as filler
* @param d the duration
* @Effects Let facet be the duration_units<CharT> facet associated to ios. If the associated unit is named,
* as if
* @code
string_type str = facet.get_unit(get_duration_style(ios), d);
s=std::copy(str.begin(), str.end(), s);
* @endcode
* Otherwise, format the unit as "[Period::num/Period::den]" followed by the unit associated to [N/D] obtained using facet.get_n_d_unit(get_duration_style(ios), d)
* @Returns s, iterator pointing immediately after the last character produced.
*/
template <typename Rep, typename Period>
iter_type put_unit(iter_type s, std::ios_base& ios, char_type fill, duration<Rep, Period> const& d) const
{
if (std::has_facet<duration_units<CharT> >(ios.getloc()))
{
duration_units<CharT> const&facet = std::use_facet<duration_units<CharT> >(
ios.getloc());
return put_unit(facet, s, ios, fill, d);
}
else
{
duration_units_default<CharT> facet;
return put_unit(facet, s, ios, fill, d);
}
}
template <typename Rep, typename Period>
iter_type put_unit(duration_units<CharT> const& facet, iter_type s, std::ios_base& ios, char_type fill,
duration<Rep, Period> const& d) const
{
if (facet.template is_named_unit<Period>()) {
string_type str = facet.get_unit(get_duration_style(ios), d);
s=std::copy(str.begin(), str.end(), s);
} else {
*s++ = CharT('[');
std::use_facet<std::num_put<CharT, iter_type> >(ios.getloc()).put(s, ios, fill, Period::num);
*s++ = CharT('/');
std::use_facet<std::num_put<CharT, iter_type> >(ios.getloc()).put(s, ios, fill, Period::den);
*s++ = CharT(']');
string_type str = facet.get_n_d_unit(get_duration_style(ios), d);
s=std::copy(str.begin(), str.end(), s);
}
return s;
}
template <typename Rep, typename Period>
iter_type put_unit(duration_units<CharT> const& facet, iter_type s, std::ios_base& ios, char_type fill,
duration<process_times<Rep>, Period> const& d) const
{
duration<Rep,Period> real(d.count().real);
if (facet.template is_named_unit<Period>()) {
string_type str = facet.get_unit(get_duration_style(ios), real);
s=std::copy(str.begin(), str.end(), s);
} else {
*s++ = CharT('[');
std::use_facet<std::num_put<CharT, iter_type> >(ios.getloc()).put(s, ios, fill, Period::num);
*s++ = CharT('/');
std::use_facet<std::num_put<CharT, iter_type> >(ios.getloc()).put(s, ios, fill, Period::den);
*s++ = CharT(']');
string_type str = facet.get_n_d_unit(get_duration_style(ios), real);
s=std::copy(str.begin(), str.end(), s);
}
return s;
}
/**
* Unique identifier for this type of facet.
*/
static std::locale::id id;
/**
* @Effects Destroy the facet
*/
~duration_put()
{
}
};
template <class CharT, class OutputIterator>
std::locale::id duration_put<CharT, OutputIterator>::id;
} // chrono
} // boost
#endif // header

View File

@@ -0,0 +1,35 @@
// (C) Copyright Howard Hinnant
// (C) Copyright 2011 Vicente J. Botet Escriba
// Use, modification and distribution are subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt).
//
// This code was adapted by Vicente from Howard Hinnant's experimental work
// on chrono i/o to Boost
#ifndef BOOST_CHRONO_IO_DURATION_STYLE_HPP
#define BOOST_CHRONO_IO_DURATION_STYLE_HPP
#include <boost/core/scoped_enum.hpp>
namespace boost
{
namespace chrono
{
/**
* Scoped enumeration emulation stating whether the duration I/O style is long or short.
* prefix means duration::rep with whatever stream/locale settings are set for it followed by a long name representing the unit
* symbol means duration::rep with whatever stream/locale settings are set for it followed by a SI unit abbreviation
*/
BOOST_SCOPED_ENUM_DECLARE_BEGIN(duration_style)
{
prefix, symbol
}
BOOST_SCOPED_ENUM_DECLARE_END(duration_style)
} // chrono
}
#endif // header

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,152 @@
// (C) Copyright 2011 Vicente J. Botet Escriba
// Use, modification and distribution are subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt).
//
// This code was adapted by Vicente from Howard Hinnant's experimental work
// on chrono i/o to Boost
#ifndef BOOST_CHRONO_IO_IOS_BASE_STATE_HPP
#define BOOST_CHRONO_IO_IOS_BASE_STATE_HPP
#include <boost/chrono/config.hpp>
#include <locale>
#include <boost/chrono/io/duration_style.hpp>
#include <boost/chrono/io/timezone.hpp>
#include <boost/chrono/io/utility/ios_base_state_ptr.hpp>
namespace boost
{
namespace chrono
{
class fmt_masks : public ios_flags<fmt_masks>
{
typedef ios_flags<fmt_masks> base_type;
fmt_masks& operator=(fmt_masks const& rhs) ;
public:
fmt_masks(std::ios_base& ios): base_type(ios) {}
enum type
{
uses_symbol = 1 << 0,
uses_local = 1 << 1
};
inline duration_style get_duration_style()
{
return (flags() & uses_symbol) ? duration_style::symbol : duration_style::prefix;
}
inline void set_duration_style(duration_style style)
{
if (style == duration_style::symbol)
setf(uses_symbol);
else
unsetf(uses_symbol);
}
inline timezone get_timezone()
{
return (flags() & uses_local) ? timezone::local : timezone::utc;
}
inline void set_timezone(timezone tz)
{
if (tz == timezone::local)
setf(uses_local);
else
unsetf(uses_local);
}
};
namespace detail
{
namespace /**/ {
xalloc_key_initializer<fmt_masks > fmt_masks_xalloc_key_initializer;
} // namespace
} // namespace detail
inline duration_style get_duration_style(std::ios_base & ios)
{
return fmt_masks(ios).get_duration_style();
}
inline void set_duration_style(std::ios_base& ios, duration_style style)
{
fmt_masks(ios).set_duration_style(style);
}
inline std::ios_base& symbol_format(std::ios_base& ios)
{
fmt_masks(ios).setf(fmt_masks::uses_symbol);
return ios;
}
inline std::ios_base& name_format(std::ios_base& ios)
{
fmt_masks(ios).unsetf(fmt_masks::uses_symbol);
return ios;
}
inline timezone get_timezone(std::ios_base & ios)
{
return fmt_masks(ios).get_timezone();
}
inline void set_timezone(std::ios_base& ios, timezone tz)
{
fmt_masks(ios).set_timezone(tz);
}
inline std::ios_base& local_timezone(std::ios_base& ios)
{
fmt_masks(ios).setf(fmt_masks::uses_local);
return ios;
}
inline std::ios_base& utc_timezone(std::ios_base& ios)
{
fmt_masks(ios).unsetf(fmt_masks::uses_local);
return ios;
}
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 /**/ {
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
} // namespace detail
template<typename CharT>
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>
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;
}
} // chrono
} // boost
#endif // header

View File

@@ -0,0 +1,330 @@
// (C) Copyright Howard Hinnant
// (C) Copyright 2011 Vicente J. Botet Escriba
// Use, modification and distribution are subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt).
//
#ifndef BOOST_CHRONO_IO_TIME_POINT_GET_HPP
#define BOOST_CHRONO_IO_TIME_POINT_GET_HPP
#include <boost/chrono/config.hpp>
#include <boost/chrono/detail/scan_keyword.hpp>
#include <boost/chrono/io/time_point_units.hpp>
#include <boost/chrono/io/duration_get.hpp>
#include <boost/assert.hpp>
#include <locale>
#include <string>
/**
* Duration formatting facet for input.
*/
namespace boost
{
namespace chrono
{
template <class CharT, class InputIterator = std::istreambuf_iterator<CharT> >
class time_point_get: public std::locale::facet
{
public:
/**
* Type of character the facet is instantiated on.
*/
typedef CharT char_type;
/**
* Type of iterator used to scan the character buffer.
*/
typedef InputIterator iter_type;
/**
* Construct a @c time_point_get facet.
* @param refs
* @Effects Construct a @c time_point_get facet.
* If the @c refs argument is @c 0 then destruction of the object is
* delegated to the @c locale, or locales, containing it. This allows
* the user to ignore lifetime management issues. On the other had,
* if @c refs is @c 1 then the object must be explicitly deleted;
* the @c locale will not do so. In this case, the object can be
* maintained across the lifetime of multiple locales.
*/
explicit time_point_get(size_t refs = 0) :
std::locale::facet(refs)
{
}
/**
* @param s start input stream iterator
* @param end end input stream iterator
* @param ios a reference to a ios_base
* @param err the ios_base state
* @param d the duration
* @param pattern begin of the formatting pattern
* @param pat_end end of the formatting pattern
*
* Requires: [pattern,pat_end) shall be a valid range.
*
* Effects: The function starts by evaluating err = std::ios_base::goodbit.
* It then enters a loop, reading zero or more characters from s at
* each iteration. Unless otherwise specified below, the loop
* terminates when the first of the following conditions holds:
* - The expression pattern == pat_end evaluates to true.
* - The expression err == std::ios_base::goodbit evaluates to false.
* - The expression s == end evaluates to true, in which case the
* function evaluates err = std::ios_base::eofbit | std::ios_base::failbit.
* - The next element of pattern is equal to '%', followed by a conversion
* specifier character, the functions @c get_duration or @c get_epoch are called depending on
* whether the format is @c 'd' or @c 'e'.
* If the number of elements in the range [pattern,pat_end) is not
* sufficient to unambiguously determine whether the conversion
* specification is complete and valid, the function evaluates
* err = std::ios_base::failbit. Otherwise, the function evaluates
* s = do_get(s, end, ios, err, d). If err == std::ios_base::goodbit holds after
* the evaluation of the expression, the function increments pattern to
* point just past the end of the conversion specification and continues
* looping.
* - The expression isspace(*pattern, ios.getloc()) evaluates to true, in
* which case the function first increments pattern until
* pattern == pat_end || !isspace(*pattern, ios.getloc()) evaluates to true,
* then advances s until s == end || !isspace(*s, ios.getloc()) is true,
* and finally resumes looping.
* - The next character read from s matches the element pointed to by
* pattern in a case-insensitive comparison, in which case the function
* evaluates ++pattern, ++s and continues looping. Otherwise, the function
* evaluates err = std::ios_base::failbit.
*
* Returns: s
*/
template <class Clock, class Duration>
iter_type get(iter_type i, iter_type e, std::ios_base& is, std::ios_base::iostate& err,
time_point<Clock, Duration> &tp, const char_type *pattern, const char_type *pat_end) const
{
if (std::has_facet<time_point_units<CharT> >(is.getloc()))
{
time_point_units<CharT> const &facet = std::use_facet<time_point_units<CharT> >(is.getloc());
return get(facet, i, e, is, err, tp, pattern, pat_end);
}
else
{
time_point_units_default<CharT> facet;
return get(facet, i, e, is, err, tp, pattern, pat_end);
}
}
template <class Clock, class Duration>
iter_type get(time_point_units<CharT> const &facet, iter_type s, iter_type end, std::ios_base& ios,
std::ios_base::iostate& err, time_point<Clock, Duration> &tp, const char_type *pattern,
const char_type *pat_end) const
{
Duration d;
bool duration_found = false, epoch_found = false;
const std::ctype<char_type>& ct = std::use_facet<std::ctype<char_type> >(ios.getloc());
err = std::ios_base::goodbit;
while (pattern != pat_end && err == std::ios_base::goodbit)
{
if (s == end)
{
err |= std::ios_base::eofbit;
break;
}
if (ct.narrow(*pattern, 0) == '%')
{
if (++pattern == pat_end)
{
err |= std::ios_base::failbit;
return s;
}
char cmd = ct.narrow(*pattern, 0);
switch (cmd)
{
case 'd':
{
if (duration_found)
{
err |= std::ios_base::failbit;
return s;
}
duration_found = true;
s = get_duration(s, end, ios, err, d);
if (err & (std::ios_base::badbit | std::ios_base::failbit))
{
return s;
}
break;
}
case 'e':
{
if (epoch_found)
{
err |= std::ios_base::failbit;
return s;
}
epoch_found = true;
s = get_epoch<Clock> (facet, s, end, ios, err);
if (err & (std::ios_base::badbit | std::ios_base::failbit))
{
return s;
}
break;
}
default:
BOOST_ASSERT(false && "Boost::Chrono internal error.");
break;
}
++pattern;
}
else if (ct.is(std::ctype_base::space, *pattern))
{
for (++pattern; pattern != pat_end && ct.is(std::ctype_base::space, *pattern); ++pattern)
;
for (; s != end && ct.is(std::ctype_base::space, *s); ++s)
;
}
else if (ct.toupper(*s) == ct.toupper(*pattern))
{
++s;
++pattern;
}
else
{
err |= std::ios_base::failbit;
}
}
// Success! Store it.
tp = time_point<Clock, Duration> (d);
return s;
}
/**
*
* @param s an input stream iterator
* @param ios a reference to a ios_base
* @param d the duration
* Stores the duration pattern from the @c duration_unit facet in let say @c str. Last as if
* @code
* return get(s, end, ios, err, ios, d, str.data(), str.data() + str.size());
* @codeend
* @Returns An iterator pointing just beyond the last character that can be determined to be part of a valid name
*/
template <class Clock, class Duration>
iter_type get(iter_type i, iter_type e, std::ios_base& is, std::ios_base::iostate& err,
time_point<Clock, Duration> &tp) const
{
if (std::has_facet<time_point_units<CharT> >(is.getloc()))
{
time_point_units<CharT> const &facet = std::use_facet<time_point_units<CharT> >(is.getloc());
std::basic_string<CharT> str = facet.get_pattern();
return get(facet, i, e, is, err, tp, str.data(), str.data() + str.size());
}
else
{
time_point_units_default<CharT> facet;
std::basic_string<CharT> str = facet.get_pattern();
return get(facet, i, e, is, err, tp, str.data(), str.data() + str.size());
}
}
/**
* As if
* @code
* return facet.get(s, end, ios, err, d);
* @endcode
* where @c facet is either the @c duration_get facet associated to the @c ios or an instance of the default @c duration_get facet.
*
* @Returns An iterator pointing just beyond the last character that can be determined to be part of a valid duration.
*/
template <typename Rep, typename Period>
iter_type get_duration(iter_type i, iter_type e, std::ios_base& is, std::ios_base::iostate& err,
duration<Rep, Period>& d) const
{
if (std::has_facet<duration_get<CharT> >(is.getloc()))
{
duration_get<CharT> const &facet = std::use_facet<duration_get<CharT> >(is.getloc());
return get_duration(facet, i, e, is, err, d);
}
else
{
duration_get<CharT> facet;
return get_duration(facet, i, e, is, err, d);
}
}
template <typename Rep, typename Period>
iter_type get_duration(duration_get<CharT> const& facet, iter_type s, iter_type end, std::ios_base& ios,
std::ios_base::iostate& err, duration<Rep, Period>& d) const
{
return facet.get(s, end, ios, err, d);
}
/**
*
* @Effects Let @c facet be the @c time_point_units facet associated to @c is or a new instance of the default @c time_point_units_default facet.
* Let @c epoch be the epoch string associated to the Clock using this facet.
* Scans @c i to match @c epoch or @c e is reached.
*
* If not match before the @c e is reached @c std::ios_base::failbit is set in @c err.
* If @c e is reached @c std::ios_base::failbit is set in @c err.
*
* @Returns An iterator pointing just beyond the last character that can be determined to be part of a valid epoch.
*/
template <class Clock>
iter_type get_epoch(iter_type i, iter_type e, std::ios_base& is, std::ios_base::iostate& err) const
{
if (std::has_facet<time_point_units<CharT> >(is.getloc()))
{
time_point_units<CharT> const &facet = std::use_facet<time_point_units<CharT> >(is.getloc());
return get_epoch<Clock>(facet, i, e, is, err);
}
else
{
time_point_units_default<CharT> facet;
return get_epoch<Clock>(facet, i, e, is, err);
}
}
template <class Clock>
iter_type get_epoch(time_point_units<CharT> const &facet, iter_type i, iter_type e, std::ios_base&,
std::ios_base::iostate& err) const
{
const std::basic_string<CharT> epoch = facet.template get_epoch<Clock> ();
std::ptrdiff_t k = chrono_detail::scan_keyword(i, e, &epoch, &epoch + 1,
//~ std::use_facet<std::ctype<CharT> >(ios.getloc()),
err) - &epoch;
if (k == 1)
{
err |= std::ios_base::failbit;
return i;
}
return i;
}
/**
* Unique identifier for this type of facet.
*/
static std::locale::id id;
/**
* @Effects Destroy the facet
*/
~time_point_get()
{
}
};
/**
* Unique identifier for this type of facet.
*/
template <class CharT, class InputIterator>
std::locale::id time_point_get<CharT, InputIterator>::id;
} // chrono
}
// boost
#endif // header

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,261 @@
// (C) Copyright Howard Hinnant
// (C) Copyright 2011 Vicente J. Botet Escriba
// Use, modification and distribution are subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt).
//
/**
* Duration formatting facet for output.
*/
#ifndef BOOST_CHRONO_IO_TIME_POINT_PUT_HPP
#define BOOST_CHRONO_IO_TIME_POINT_PUT_HPP
#include <boost/chrono/config.hpp>
#include <boost/chrono/io/time_point_units.hpp>
#include <boost/chrono/io/duration_put.hpp>
#include <boost/assert.hpp>
#include <locale>
namespace boost
{
namespace chrono
{
/**
* @tparam ChatT a character type
* @tparam OutputIterator a model of @c OutputIterator
*
* The @c time_point_put facet provides facilities for formatted output of @c time_point values.
* The member function of @c time_point_put take a @c time_point and format it into character string representation.
*
*/
template <class CharT, class OutputIterator = std::ostreambuf_iterator<CharT> >
class time_point_put: public std::locale::facet
{
public:
/**
* Type of character the facet is instantiated on.
*/
typedef CharT char_type;
/**
* Type of character string passed to member functions.
*/
typedef std::basic_string<CharT> string_type;
/**
* Type of iterator used to write in the character buffer.
*/
typedef OutputIterator iter_type;
/**
* Construct a time_point_put facet.
* @param refs
* @Effects Construct a time_point_put facet.
* If the @c refs argument is @c 0 then destruction of the object is
* delegated to the @c locale, or locales, containing it. This allows
* the user to ignore lifetime management issues. On the other had,
* if @c refs is @c 1 then the object must be explicitly deleted;
* the @c locale will not do so. In this case, the object can be
* maintained across the lifetime of multiple locales.
*/
explicit time_point_put(size_t refs = 0) :
std::locale::facet(refs)
{
}
/**
* @param i an output stream iterator
* @param ios a reference to a ios_base
* @param fill the character used as filler
* @param tp the @c time_point
* @param pattern begin of the formatting pattern
* @param pat_end end of the formatting pattern
*
* @Effects Steps through the sequence from @c pattern to @c pat_end,
* identifying characters that are part of a pattern sequence. Each character
* that is not part of a pattern sequence is written to @c s immediately, and
* each pattern sequence, as it is identified, results in a call to
* @c put_duration or @c put_epoch;
* thus, pattern elements and other characters are interleaved in the output
* in the order in which they appear in the pattern. Pattern sequences are
* identified by converting each character @c c to a @c char value as if by
* @c ct.narrow(c,0), where @c ct is a reference to @c ctype<charT> obtained from
* @c ios.getloc(). The first character of each sequence is equal to @c '%',
* followed by a pattern specifier character @c spec, which can be @c 'd' for
* the duration value or @c 'e' for the epoch.
* For each valid pattern sequence identified, calls
* <c>put_duration(s, ios, fill, tp.time_since_epoch())</c> or <c>put_epoch(s, ios)</c>.
*
* @Returns An iterator pointing immediately after the last character produced.
*/
template <class Clock, class Duration>
iter_type put(iter_type i, std::ios_base& ios, char_type fill, time_point<Clock, Duration> const& tp, const CharT* pattern,
const CharT* pat_end) const
{
if (std::has_facet<time_point_units<CharT> >(ios.getloc()))
{
time_point_units<CharT> const &facet =
std::use_facet<time_point_units<CharT> >(ios.getloc());
return put(facet, i, ios, fill, tp, pattern, pat_end);
}
else
{
time_point_units_default<CharT> facet;
return put(facet, i, ios, fill, tp, pattern, pat_end);
}
}
template <class Clock, class Duration>
iter_type put(time_point_units<CharT> const& units_facet, iter_type s, std::ios_base& ios, char_type fill,
time_point<Clock, Duration> const& tp, const CharT* pattern, const CharT* pat_end) const
{
const std::ctype<char_type>& ct = std::use_facet<std::ctype<char_type> >(ios.getloc());
for (; pattern != pat_end; ++pattern)
{
if (ct.narrow(*pattern, 0) == '%')
{
if (++pattern == pat_end)
{
*s++ = pattern[-1];
break;
}
char fmt = ct.narrow(*pattern, 0);
switch (fmt)
{
case 'd':
{
s = put_duration(s, ios, fill, tp.time_since_epoch());
break;
}
case 'e':
{
s = put_epoch<Clock> (units_facet, s, ios);
break;
}
default:
BOOST_ASSERT(false && "Boost::Chrono internal error.");
break;
}
}
else
*s++ = *pattern;
}
return s;
}
/**
* @param i an output stream iterator
* @param ios a reference to a ios_base
* @param fill the character used as filler
* @param tp the @c time_point
* @param pattern begin of the formatting pattern
* @param pat_end end of the formatting pattern
*
* @Effects Stores the time_point pattern from the @c time_point_unit facet in let say @c str. Last as if
* @code
* return put(s, ios, dill, tp, str.data(), str.data() + str.size());
* @endcode
* @Returns An iterator pointing immediately after the last character produced.
*/
template <class Clock, class Duration>
iter_type put(iter_type i, std::ios_base& ios, char_type fill, time_point<Clock, Duration> const& tp) const
{
if (std::has_facet<time_point_units<CharT> >(ios.getloc()))
{
time_point_units<CharT> const &facet =
std::use_facet<time_point_units<CharT> >(ios.getloc());
std::basic_string<CharT> str = facet.get_pattern();
return put(facet, i, ios, fill, tp, str.data(), str.data() + str.size());
}
else
{
time_point_units_default<CharT> facet;
std::basic_string<CharT> str = facet.get_pattern();
return put(facet, i, ios, fill, tp, str.data(), str.data() + str.size());
}
}
/**
* @param i an output stream iterator
* @param ios a reference to a ios_base
* @param fill the character used as filler
* @param d the @c duration
* @Effects As if <c>facet.put(s, ios, fill, d)</c> where facet is the @c duration_put<CharT> facet associated
* to the @c ios or a new instance of @c duration_put<CharT>.
* @Returns An iterator pointing immediately after the last character produced.
*/
template <typename Rep, typename Period>
iter_type put_duration(iter_type i, std::ios_base& ios, char_type fill, duration<Rep, Period> const& d) const
{
if (std::has_facet<duration_put<CharT> >(ios.getloc()))
{
duration_put<CharT> const &facet = std::use_facet<duration_put<CharT> >(ios.getloc());
return facet.put(i, ios, fill, d);
}
else
{
duration_put<CharT> facet;
return facet.put(i, ios, fill, d);
}
}
/**
*
* @param i an output stream iterator
* @param ios a reference to a ios_base
* @Effects As if
* @code
* string_type str = facet.template get_epoch<Clock>();
* s=std::copy(str.begin(), str.end(), s);
* @endcode
* where facet is the @c time_point_units<CharT> facet associated
* to the @c ios or a new instance of @c time_point_units_default<CharT>.
* @Returns s, iterator pointing immediately after the last character produced.
*/
template <typename Clock>
iter_type put_epoch(iter_type i, std::ios_base& os) const
{
if (std::has_facet<time_point_units<CharT> >(os.getloc()))
{
time_point_units<CharT> const &facet = std::use_facet<time_point_units<CharT> >(os.getloc());
return put_epoch<Clock> (facet, i, os);
}
else
{
time_point_units_default<CharT> facet;
return put_epoch<Clock> (facet, i, os);
}
}
template <typename Clock>
iter_type put_epoch(time_point_units<CharT> const& facet, iter_type s, std::ios_base&) const
{
string_type str = facet.template get_epoch<Clock>();
s= std::copy(str.begin(), str.end(), s);
return s;
}
/**
* Unique identifier for this type of facet.
*/
static std::locale::id id;
/**
* @Effects Destroy the facet
*/
~time_point_put()
{
}
};
template <class CharT, class OutputIterator>
std::locale::id time_point_put<CharT, OutputIterator>::id;
} // chrono
} // boost
#endif // header

View File

@@ -0,0 +1,260 @@
// (C) Copyright Howard Hinnant
// (C) Copyright 2011 Vicente J. Botet Escriba
// Copyright (c) Microsoft Corporation 2014
// Use, modification and distribution are subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt).
//
#ifndef BOOST_CHRONO_IO_TIME_POINT_UNITS_HPP
#define BOOST_CHRONO_IO_TIME_POINT_UNITS_HPP
#include <boost/chrono/config.hpp>
#include <boost/chrono/process_cpu_clocks.hpp>
#include <boost/chrono/system_clocks.hpp>
#include <boost/chrono/thread_clock.hpp>
#include <boost/chrono/io/ios_base_state.hpp>
#include <string>
#include <iosfwd>
#include <ios>
#include <locale>
#include <algorithm>
namespace boost
{
namespace chrono
{
/**
* customization point to the epoch associated to the clock @c Clock
* The default calls @c f.do_get_epoch(Clock()). The user can overload this function.
* @return the string epoch associated to the @c Clock
*/
template <typename CharT, typename Clock, typename TPUFacet>
std::basic_string<CharT> get_epoch_custom(Clock, TPUFacet& f)
{
return f.do_get_epoch(Clock());
}
/**
* @c time_point_units facet gives useful information about the time_point pattern,
* the text associated to a time_point's epoch,
*/
template <typename CharT=char>
class time_point_units: public std::locale::facet
{
public:
/**
* Type of character the facet is instantiated on.
*/
typedef CharT char_type;
/**
* Type of character string used by member functions.
*/
typedef std::basic_string<char_type> string_type;
/**
* Unique identifier for this type of facet.
*/
static std::locale::id id;
/**
* Construct a @c time_point_units facet.
* @param refs
* @Effects Construct a @c time_point_units facet.
* If the @c refs argument is @c 0 then destruction of the object is
* delegated to the @c locale, or locales, containing it. This allows
* the user to ignore lifetime management issues. On the other had,
* if @c refs is @c 1 then the object must be explicitly deleted;
* the @c locale will not do so. In this case, the object can be
* maintained across the lifetime of multiple locales.
*/
explicit time_point_units(size_t refs = 0) :
std::locale::facet(refs)
{
}
/**
* @return the pattern to be used by default.
*/
virtual string_type get_pattern() const =0;
/**
* @return the epoch associated to the clock @c Clock calling @c do_get_epoch(Clock())
*/
template <typename Clock>
string_type get_epoch() const
{
return get_epoch_custom<CharT>(Clock(), *this);
}
protected:
/**
* Destroy the facet.
*/
virtual ~time_point_units() {}
public:
/**
*
* @param c a dummy instance of @c system_clock.
* @return The epoch string associated to the @c system_clock.
*/
virtual string_type do_get_epoch(system_clock) const=0;
/**
*
* @param c a dummy instance of @c steady_clock.
* @return The epoch string associated to the @c steady_clock.
*/
virtual string_type do_get_epoch(steady_clock) const=0;
#if defined(BOOST_CHRONO_HAS_PROCESS_CLOCKS)
/**
*
* @param c a dummy instance of @c process_real_cpu_clock.
* @return The epoch string associated to the @c process_real_cpu_clock.
*/
virtual string_type do_get_epoch(process_real_cpu_clock) const=0;
#if ! BOOST_OS_WINDOWS || BOOST_PLAT_WINDOWS_DESKTOP
/**
*
* @param c a dummy instance of @c process_user_cpu_clock.
* @return The epoch string associated to the @c process_user_cpu_clock.
*/
virtual string_type do_get_epoch(process_user_cpu_clock) const=0;
/**
*
* @param c a dummy instance of @c process_system_cpu_clock.
* @return The epoch string associated to the @c process_system_cpu_clock.
*/
virtual string_type do_get_epoch(process_system_cpu_clock) const=0;
/**
*
* @param c a dummy instance of @c process_cpu_clock.
* @return The epoch string associated to the @c process_cpu_clock.
*/
virtual string_type do_get_epoch(process_cpu_clock) const=0;
#endif
#endif
#if defined(BOOST_CHRONO_HAS_THREAD_CLOCK)
/**
*
* @param c a dummy instance of @c thread_clock.
* @return The epoch string associated to the @c thread_clock.
*/
virtual string_type do_get_epoch(thread_clock) const=0;
#endif
};
template <typename CharT>
std::locale::id time_point_units<CharT>::id;
// This class is used to define the strings for the default English
template <typename CharT=char>
class time_point_units_default: public time_point_units<CharT>
{
public:
/**
* Type of character the facet is instantiated on.
*/
typedef CharT char_type;
/**
* Type of character string returned by member functions.
*/
typedef std::basic_string<char_type> string_type;
explicit time_point_units_default(size_t refs = 0) :
time_point_units<CharT> (refs)
{
}
~time_point_units_default() {}
/**
* @return the default pattern "%d%e".
*/
string_type get_pattern() const
{
static const CharT t[] =
{ '%', 'd', '%', 'e' };
static const string_type pattern(t, t + sizeof (t) / sizeof (t[0]));
return pattern;
}
//protected:
/**
* @param c a dummy instance of @c system_clock.
* @return The epoch string returned by @c clock_string<system_clock,CharT>::since().
*/
string_type do_get_epoch(system_clock ) const
{
return clock_string<system_clock,CharT>::since();
}
/**
* @param c a dummy instance of @c steady_clock.
* @return The epoch string returned by @c clock_string<steady_clock,CharT>::since().
*/
string_type do_get_epoch(steady_clock ) const
{
return clock_string<steady_clock,CharT>::since();
}
#if defined(BOOST_CHRONO_HAS_PROCESS_CLOCKS)
/**
* @param c a dummy instance of @c process_real_cpu_clock.
* @return The epoch string returned by @c clock_string<process_real_cpu_clock,CharT>::since().
*/
string_type do_get_epoch(process_real_cpu_clock ) const
{
return clock_string<process_real_cpu_clock,CharT>::since();
}
#if ! BOOST_OS_WINDOWS || BOOST_PLAT_WINDOWS_DESKTOP
/**
* @param c a dummy instance of @c process_user_cpu_clock.
* @return The epoch string returned by @c clock_string<process_user_cpu_clock,CharT>::since().
*/
string_type do_get_epoch(process_user_cpu_clock ) const
{
return clock_string<process_user_cpu_clock,CharT>::since();
}
/**
* @param c a dummy instance of @c process_system_cpu_clock.
* @return The epoch string returned by @c clock_string<process_system_cpu_clock,CharT>::since().
*/
string_type do_get_epoch(process_system_cpu_clock ) const
{
return clock_string<process_system_cpu_clock,CharT>::since();
}
/**
* @param c a dummy instance of @c process_cpu_clock.
* @return The epoch string returned by @c clock_string<process_cpu_clock,CharT>::since().
*/
string_type do_get_epoch(process_cpu_clock ) const
{
return clock_string<process_cpu_clock,CharT>::since();
}
#endif
#endif
#if defined(BOOST_CHRONO_HAS_THREAD_CLOCK)
/**
* @param c a dummy instance of @c thread_clock.
* @return The epoch string returned by @c clock_string<thread_clock,CharT>::since().
*/
string_type do_get_epoch(thread_clock ) const
{
return clock_string<thread_clock,CharT>::since();
}
#endif
};
} // chrono
} // boost
#endif // header

View File

@@ -0,0 +1,31 @@
// (C) Copyright Howard Hinnant
// (C) Copyright 2010-2011 Vicente J. Botet Escriba
// Use, modification and distribution are subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt).
//
// This code was adapted by Vicente from Howard Hinnant's experimental work
// on chrono i/o to Boost
#ifndef BOOST_CHRONO_IO_TIMEZONE_HPP
#define BOOST_CHRONO_IO_TIMEZONE_HPP
#include <boost/core/scoped_enum.hpp>
namespace boost
{
namespace chrono
{
/**
* Scoped enumeration emulation stating whether the time_point for system_clock I/O is UTC or local.
*/
BOOST_SCOPED_ENUM_DECLARE_BEGIN(timezone)
{
utc, local
}
BOOST_SCOPED_ENUM_DECLARE_END(timezone)
} // chrono
} // boost
#endif // header

View File

@@ -0,0 +1,437 @@
// boost/chrono/utility/ios_base_pword_ptr.hpp ------------------------------------------------------------//
// Copyright 2011 Vicente J. Botet Escriba
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/chrono for documentation.
#ifndef BOOST_CHRONO_UTILITY_IOS_BASE_STATE_PTR_HPP
#define BOOST_CHRONO_UTILITY_IOS_BASE_STATE_PTR_HPP
#include <ios>
#include <boost/assert.hpp>
/**
*
*/
namespace boost
{
namespace chrono
{
namespace detail
{
/**
* xalloc key holder.
*/
template <typename T>
struct xalloc_key_holder
{
static int value; //< the xalloc value associated to T.
static bool initialized; //< whether the value has been initialized or not.
};
template <typename T>
int xalloc_key_holder<T>::value = 0;
template <typename T>
bool xalloc_key_holder<T>::initialized = false;
}
/**
* xalloc key initialiazer.
*
* Declare a static variable of this type to ensure that the xalloc_key_holder<T> is initialized correctly.
*/
template <typename T>
struct xalloc_key_initializer
{
xalloc_key_initializer()
{
if (!detail::xalloc_key_holder<T>::initialized)
{
detail::xalloc_key_holder<T>::value = std::ios_base::xalloc();
detail::xalloc_key_holder<T>::initialized = true;
}
}
};
/**
* @c ios_state_ptr is a smart pointer to a ios_base specific state.
*/
template <typename Final, typename T>
class ios_state_ptr
{
ios_state_ptr& operator=(ios_state_ptr const& rhs) ;
public:
/**
* The pointee type
*/
typedef T element_type;
/**
* Explicit constructor.
* @param ios the ios
* @Effects Constructs a @c ios_state_ptr by storing the associated @c ios.
*/
explicit ios_state_ptr(std::ios_base& ios) :
ios_(ios)
{
}
/**
* Nothing to do as xalloc index can not be removed.
*/
~ios_state_ptr()
{
}
/**
* @Effects Allocates the index if not already done.
* Registers the callback responsible of maintaining the state pointer coherency, if not already done.
* Retrieves the associated ios pointer
* @return the retrieved pointer statically casted to const.
*/
T const* get() const BOOST_NOEXCEPT
{
register_once(index(), ios_);
void* &pw = ios_.pword(index());
if (pw == 0)
{
return 0;
}
return static_cast<const T*> (pw);
}
/**
* @Effects Allocates the index if not already done.
* Registers the callback responsible of maintaining the state pointer coherency, if not already done.
* Retrieves the associated ios pointer
* @return the retrieved pointer.
*/
T * get() BOOST_NOEXCEPT
{
register_once(index(), ios_);
void* &pw = ios_.pword(index());
if (pw == 0)
{
return 0;
}
return static_cast<T*> (pw);
}
/**
* @Effects as if @c return get();
* @return the retrieved pointer.
*/
T * operator->()BOOST_NOEXCEPT
{
return get();
}
/**
* @Effects as if @c return get();
* @return the retrieved pointer.
*/
T const * operator->() const BOOST_NOEXCEPT
{
return get();
}
/**
* @Effects as if @c return *get();
* @return a reference to the retrieved state.
* @Remark The behavior is undefined if @c get()==0.
*/
T & operator*() BOOST_NOEXCEPT
{
return *get();
}
/**
* @Effects as if @c return *get();
* @return a reference to the retrieved state.
* @Remark The behavior is undefined if @c get()==0.
*/
T const & operator *() const BOOST_NOEXCEPT
{
return *get();
}
/**
* @Effects reset the current pointer after storing in a temporary variable the pointer to the current state.
* @return the stored state pointer.
*/
T * release() BOOST_NOEXCEPT
{
void*& pw = ios_.pword(index());
T* ptr = static_cast<T*> (pw);
pw = 0;
return ptr;
}
/**
*
* @param new_ptr the new pointer.
* @Effects deletes the current state and replace it with the new one.
*/
void reset(T* new_ptr = 0)BOOST_NOEXCEPT
{
register_once(index(), ios_);
void*& pw = ios_.pword(index());
delete static_cast<T*> (pw);
pw = new_ptr;
}
#if defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
typedef T* (ios_state_ptr::*bool_type)();
operator bool_type() const BOOST_NOEXCEPT
{
return (get()!=0)?&ios_state_ptr::release:0;
}
bool operator!() const BOOST_NOEXCEPT
{
return (get()==0)?&ios_state_ptr::release:0;
}
#else
/**
* Explicit conversion to bool.
*/
explicit operator bool() const BOOST_NOEXCEPT
{
return get()!=0;
}
#endif
std::ios_base& getios()BOOST_NOEXCEPT
{
return ios_;
}
std::ios_base& getios() const BOOST_NOEXCEPT
{
return ios_;
}
/**
* Implicit conversion to the ios_base
*/
operator std::ios_base&() BOOST_NOEXCEPT
{
return ios_;
}
/**
* Implicit conversion to the ios_base const
*/
operator std::ios_base&() const BOOST_NOEXCEPT
{
return ios_;
}
private:
static inline bool is_registerd(std::ios_base& ios)
{
long iw = ios.iword(index());
return (iw == 1);
}
static inline void set_registered(std::ios_base& ios)
{
long& iw = ios.iword(index());
iw = 1;
}
static inline void callback(std::ios_base::event evt, std::ios_base& ios, int index)
{
switch (evt)
{
case std::ios_base::erase_event:
{
void*& pw = ios.pword(index);
if (pw != 0)
{
T* ptr = static_cast<T*> (pw);
delete ptr;
pw = 0;
}
break;
}
case std::ios_base::copyfmt_event:
{
void*& pw = ios.pword(index);
if (pw != 0)
{
pw = new T(*static_cast<T*> (pw));
}
break;
}
default:
break;
}
}
static inline int index()
{
return detail::xalloc_key_holder<Final>::value;
}
static inline void register_once(int indx, std::ios_base& ios)
{
// needs a mask registered
if (!is_registerd(ios))
{
set_registered(ios);
ios.register_callback(callback, indx);
}
}
protected:
std::ios_base& ios_;
//static detail::xalloc_key_initializer<Final> xalloc_key_initializer_;
};
//template <typename Final, typename T>
//detail::xalloc_key_initializer<Final> ios_state_ptr<Final,T>::xalloc_key_initializer_;
/**
* @c ios_state_not_null_ptr is a non null variant of @c ios_state_ptr.
* @tparm T
* @Requires @c T must be @c DefaultConstructible and @c HeapAllocatable
*/
template <typename Final, typename T>
class ios_state_not_null_ptr: public ios_state_ptr<Final, T>
{
typedef ios_state_ptr<Final, T> base_type;
public:
explicit ios_state_not_null_ptr(std::ios_base& ios) :
base_type(ios)
{
if (this->get() == 0)
{
this->base_type::reset(new T());
}
}
~ios_state_not_null_ptr()
{
}
void reset(T* new_value) BOOST_NOEXCEPT
{
BOOST_ASSERT(new_value!=0);
this->base_type::reset(new_value);
}
};
/**
* This class is useful to associate some flags to an std::ios_base.
*/
template <typename Final>
class ios_flags
{
public:
/**
*
* @param ios the associated std::ios_base.
* @Postcondition <c>flags()==0</c>
*/
explicit ios_flags(std::ios_base& ios) :
ios_(ios)
{
}
~ios_flags()
{
}
/**
* @Returns The format control information.
*/
long flags() const BOOST_NOEXCEPT
{
return value();
}
/**
* @param v the new bit mask.
* @Postcondition <c>v == flags()</c>.
* @Returns The previous value of @c flags().
*/
long flags(long v)BOOST_NOEXCEPT
{
long tmp = flags();
ref() = v;
return tmp;
}
/**
* @param v the new value
* @Effects: Sets @c v in @c flags().
* @Returns: The previous value of @c flags().
*/
long setf(long v)
{
long tmp = value();
ref() |= v;
return tmp;
}
/**
* @param mask the bit mask to clear.
* @Effects: Clears @c mask in @c flags().
*/
void unsetf(long mask)
{
ref() &= ~mask;
}
/**
*
* @param v
* @param mask
* @Effects: Clears @c mask in @c flags(), sets <c>v & mask</c> in @c flags().
* @Returns: The previous value of flags().
*/
long setf(long v, long mask)
{
long tmp = value();
unsetf(mask);
ref() |= v & mask;
return tmp;
}
/**
* implicit conversion to the @c ios_base
*/
operator std::ios_base&()BOOST_NOEXCEPT
{
return ios_;
}
/**
* implicit conversion to the @c ios_base const
*/
operator std::ios_base const&() const BOOST_NOEXCEPT
{
return ios_;
}
private:
long value() const BOOST_NOEXCEPT
{
return ios_.iword(index());
}
long& ref()BOOST_NOEXCEPT
{
return ios_.iword(index());
}
static inline int index()
{
return detail::xalloc_key_holder<Final>::value;
}
ios_flags& operator=(ios_flags const& rhs) ;
std::ios_base& ios_;
//static detail::xalloc_key_initializer<Final> xalloc_key_initializer_;
};
//template <typename Final>
//detail::xalloc_key_initializer<Final> ios_flags<Final>::xalloc_key_initializer_;
} // namespace chrono
} // namespace boost
#endif // header

View File

@@ -0,0 +1,101 @@
// boost/chrono/utility/manip_base.hpp ------------------------------------------------------------//
// Copyright 2011 Vicente J. Botet Escriba
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/chrono for documentation.
#ifndef BOOST_CHRONO_UTILITY_MANIP_BASE_PTR_HPP
#define BOOST_CHRONO_UTILITY_MANIP_BASE_PTR_HPP
#include <ios>
/**
*
*/
namespace boost
{
namespace chrono
{
/**
* manip is a manipulator mixin class following the CRTP.
* @tparam Final the derived from manip and final type
*
* @Example
* @code
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;
};
* @codeend
*/
template <typename Final>
class manip
{
public:
/**
*
* @param ios the io stream or ios_base.
* @Effects calls to the manipulator final functor.
*/
//template <typename out_stream>
void operator()(std::ios_base &ios) const
{
(*static_cast<const Final *> (this))(ios);
}
};
/**
* @c manip stream inserter
* @param out the io stream or ios_base.
* @param op the manipulator instance.
* @Effects if @c out is good calls to the manipulator functor @op.
* @return @c out
*/
template <typename out_stream, typename manip_type>
out_stream &operator<<(out_stream &out, const manip<manip_type> &op)
{
if (out.good())
op(out);
return out;
}
/**
* @c manip stream extractor
* @param in the io stream or ios_base.
* @param op the manipulator instance.
* @Effects if @c in is good calls to the manipulator functor @op.
* @return @c in
*/
template <typename in_stream, typename manip_type>
in_stream &operator>>(in_stream &in, const manip<manip_type> &op)
{
if (in.good())
op(in);
return in;
}
} // namespace chrono
} // namespace boost
#endif // header

View File

@@ -0,0 +1,50 @@
// boost/chrono/utility/to_string.hpp
//
// Copyright 2011 Vicente J. Botet Escriba
// Use, modification and distribution are subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt).
#ifndef BOOST_CHRONO_UTILITY_TO_STRING_HPP
#define BOOST_CHRONO_UTILITY_TO_STRING_HPP
#include <boost/chrono/config.hpp>
#include <string>
#include <sstream>
namespace boost
{
namespace chrono
{
template <typename CharT, typename T>
std::basic_string<CharT> to_basic_string(T const&v) {
std::basic_stringstream<CharT> sstr;
sstr << v;
return sstr.str();
}
template <typename T>
std::string to_string(T const&v) {
return to_basic_string<char>(v);
}
#ifndef BOOST_NO_STD_WSTRING
template <typename T>
std::wstring to_wstring(T const&v) {
return to_basic_string<wchar_t>(v);
}
#endif
#if BOOST_CHRONO_HAS_UNICODE_SUPPORT
template <typename T>
std::basic_string<char16_t> to_u16string(T const&v) {
return to_basic_string<char16_t>(v);
}
template <typename T>
std::basic_string<char32_t> to_u32string(T const&v) {
return to_basic_string<char32_t>(v);
}
#endif
} // chrono
} // boost
#endif // header