stabilize build system: depends, installer, boost/bdb fixes, cross targets groundwork
This commit is contained in:
@@ -0,0 +1,593 @@
|
||||
// (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())
|
||||
{
|
||||
Rep pt = t;
|
||||
if ( (duration_values<Rep>::max)() < pt)
|
||||
{
|
||||
// Conversion to Period overflowed
|
||||
err |= std::ios_base::failbit;
|
||||
return s;
|
||||
}
|
||||
}
|
||||
// Success! Store it.
|
||||
r = Rep(t);
|
||||
d = duration<Rep, Period> (r);
|
||||
|
||||
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
|
||||
@@ -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/detail/no_exceptions_support.hpp>
|
||||
#include <boost/type_traits/is_integral.hpp>
|
||||
#include <boost/type_traits/is_floating_point.hpp>
|
||||
#include <locale>
|
||||
#include <iostream>
|
||||
#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
|
||||
@@ -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
|
||||
@@ -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/detail/scoped_enum_emulation.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
@@ -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
|
||||
@@ -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
@@ -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
|
||||
@@ -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 <iostream>
|
||||
#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
|
||||
@@ -0,0 +1,30 @@
|
||||
// (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/detail/scoped_enum_emulation.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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user