|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r75292 - in trunk/boost/chrono: . io io/utility
From: vicente.botet_at_[hidden]
Date: 2011-11-03 18:39:08
Author: viboes
Date: 2011-11-03 18:39:07 EDT (Thu, 03 Nov 2011)
New Revision: 75292
URL: http://svn.boost.org/trac/boost/changeset/75292
Log:
Chrono: Added duration_units::global() and some refactoring so that the client code is simpler: imbue_if_has_not
Text files modified:
trunk/boost/chrono/config.hpp | 1
trunk/boost/chrono/io/duration_get.hpp | 18 ++-------
trunk/boost/chrono/io/duration_put.hpp | 17 ++------
trunk/boost/chrono/io/duration_units.hpp | 74 ++++++++++++++++++++++++++++++++++++++++
trunk/boost/chrono/io/utility/ios_base_state_ptr.hpp | 60 ++++++++++++++++++++++++--------
5 files changed, 130 insertions(+), 40 deletions(-)
Modified: trunk/boost/chrono/config.hpp
==============================================================================
--- trunk/boost/chrono/config.hpp (original)
+++ trunk/boost/chrono/config.hpp 2011-11-03 18:39:07 EDT (Thu, 03 Nov 2011)
@@ -93,6 +93,7 @@
#define BOOST_CHRONO_IO_USE_XALLOC
#define BOOST_CHRONO_USES_DURATION_PUT
#define BOOST_CHRONO_USES_DURATION_GET
+//#define BOOST_CHRONO_USES_DURATION_UNITS_GLOBAL
//#define BOOST_CHRONO_IS_LOCALIZABLE_VIRTUAL
//#define BOOST_CHRONO_IS_LOCALIZABLE_TRANSLATE
Modified: trunk/boost/chrono/io/duration_get.hpp
==============================================================================
--- trunk/boost/chrono/io/duration_get.hpp (original)
+++ trunk/boost/chrono/io/duration_get.hpp 2011-11-03 18:39:07 EDT (Thu, 03 Nov 2011)
@@ -161,9 +161,6 @@
duration<Rep, Period> &d, const char_type *pattern, const char_type *pat_end) const
{
- if (!std::has_facet<duration_units<CharT> >(ios.getloc())) ios.imbue(
- std::locale(ios.getloc(), new duration_units_default<CharT> ()));
-
typedef typename detail::duration_io_intermediate<Rep>::type intermediate_type;
intermediate_type r;
detail::rt_ratio rt;
@@ -226,7 +223,7 @@
break;
}
loc_found=true;
- std::basic_string<CharT> pat = std::use_facet<duration_units<CharT> >(ios.getloc()).get_pattern();
+ std::basic_string<CharT> pat = duration_units<CharT>::imbue_if_has_not(ios).get_pattern();
if (pattern+1 != pat_end)
pat.append(pattern+1, pat_end);
pattern = pat.data();
@@ -327,10 +324,7 @@
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())) ios.imbue(
- std::locale(ios.getloc(), new duration_units_default<CharT> ()));
-
- std::basic_string < CharT > str = std::use_facet<duration_units<CharT> >(ios.getloc()).get_pattern();
+ std::basic_string < CharT > str = duration_units<CharT>::imbue_if_has_not(ios).get_pattern();
return get(s, end, ios, err, d, str.data(), str.data() + str.size());
}
@@ -360,9 +354,7 @@
iter_type get_unit(iter_type i, iter_type e, std::ios_base& is, std::ios_base::iostate& err,
detail::rt_ratio &rt) const
{
- if (!std::has_facet<duration_units<CharT> >(is.getloc()))
- is.imbue(std::locale(is.getloc(), new duration_units_default<CharT> ()));
- duration_units<CharT> const &facet = std::use_facet<duration_units<CharT> >(is.getloc());
+ duration_units<CharT> const &facet = duration_units<CharT>::imbue_if_has_not(is);
if (*i == '[')
{
@@ -582,8 +574,8 @@
/**
* Unique identifier for this type of facet.
*/
- template <class CharT, class OutputIterator>
- std::locale::id duration_get<CharT, OutputIterator>::id;
+ template <class CharT, class InputIterator>
+ std::locale::id duration_get<CharT, InputIterator>::id;
} // chrono
}
Modified: trunk/boost/chrono/io/duration_put.hpp
==============================================================================
--- trunk/boost/chrono/io/duration_put.hpp (original)
+++ trunk/boost/chrono/io/duration_put.hpp 2011-11-03 18:39:07 EDT (Thu, 03 Nov 2011)
@@ -91,8 +91,7 @@
iter_type put(iter_type s, std::ios_base& ios, duration<Rep, Period> const& d, const CharT* pattern,
const CharT* pat_end) const
{
- if (!std::has_facet<duration_units<CharT> >(ios.getloc())) ios.imbue(
- std::locale(ios.getloc(), new duration_units_default<CharT> ()));
+ duration_units<CharT,OutputIterator> const& units_facet = duration_units<CharT,OutputIterator>::imbue_if_has_not(ios);
const std::ctype<char_type>& ct = std::use_facet<std::ctype<char_type> >(ios.getloc());
for (; pattern != pat_end; ++pattern)
@@ -119,7 +118,7 @@
}
case 'x':
{
- std::basic_string<CharT> pat = std::use_facet<duration_units<CharT> >(ios.getloc()).get_pattern();
+ std::basic_string<CharT> pat = units_facet.get_pattern();
pattern = pat.data();
pat_end = pattern + pat.size();
break;
@@ -150,10 +149,7 @@
template <typename Rep, typename Period>
iter_type put(iter_type s, std::ios_base& ios, duration<Rep, Period> const& d) const
{
- if (!std::has_facet<duration_units<CharT> >(ios.getloc())) ios.imbue(
- std::locale(ios.getloc(), new duration_units_default<CharT> ()));
-
- std::basic_string<CharT> str = std::use_facet<duration_units<CharT> >(ios.getloc()).get_pattern();
+ std::basic_string<CharT> str = duration_units<CharT,OutputIterator>::imbue_if_has_not(ios).get_pattern();
return put(s, ios, d, str.data(), str.data() + str.size());
}
@@ -179,16 +175,13 @@
* @param d the duration
* @param pattern
* @Effects imbue in @c ios the @c duration_units_default facet if not already present.
- * @Effects Calls std::use_facet<duration_units<CharT> >(ios.getloc()).put(s, ios, d).
+ * @Effects Calls std::use_facet<duration_units<CharT,OutputIterator> >(ios.getloc()).put(s, ios, d).
* @Returns An iterator pointing immediately after the last character produced.
*/
template <typename Rep, typename Period>
iter_type put_unit(iter_type s, std::ios_base& ios, duration<Rep, Period> const& d) const
{
- if (!std::has_facet<duration_units<CharT> >(ios.getloc())) ios.imbue(
- std::locale(ios.getloc(), new duration_units_default<CharT> ()));
-
- return std::use_facet<duration_units<CharT> >(ios.getloc()).put(s, ios, d);
+ return duration_units<CharT,OutputIterator>::imbue_if_has_not(ios).put(s, ios, d);
}
/**
Modified: trunk/boost/chrono/io/duration_units.hpp
==============================================================================
--- trunk/boost/chrono/io/duration_units.hpp (original)
+++ trunk/boost/chrono/io/duration_units.hpp 2011-11-03 18:39:07 EDT (Thu, 03 Nov 2011)
@@ -16,6 +16,7 @@
#include <boost/chrono/io/ios_base_state.hpp>
#include <string>
#include <iostream>
+#include <ios>
//#include <locale>
#include <boost/utility/enable_if.hpp>
#include <algorithm>
@@ -136,6 +137,7 @@
template <typename CharT=char, class OutputIterator = std::ostreambuf_iterator<CharT> >
class duration_units: public std::locale::facet
{
+ static duration_units* global_;
public:
typedef CharT char_type;
typedef OutputIterator iter_type;
@@ -147,6 +149,50 @@
{
}
+ /**
+ * @Return Gets the global duration_units,
+ * used when the stream has no associated duration_units facet.
+ * @Throws an exception if the global is 0.
+ Ê
+ */
+ static duration_units* global()
+ {
+ return global_;
+ }
+
+ /**
+ If the facet is not 0, sets the new global duration_units, after deleting the preceding one. This is used when the stream has no associated duration_units facet.
+ Otherwise throw an exception.
+ */
+ static void global(duration_units* ptr)
+ {
+ global_ = ptr;
+ }
+
+ /**
+ * Factory cloning a the global instance.
+ * @return a clone of the global instance.
+ */
+ static duration_units* make()
+ {
+ return global_->clone();;
+ }
+
+ /**
+ * imbue a clone of this facet in @c ios.
+ * @param ios the ios to imbue.
+ */
+#if defined BOOST_CHRONO_USES_DURATION_UNITS_GLOBAL
+ // FIXME: This cause a linker problem on compilers other than clang-3.0 c++03 or c++0x
+ static duration_units<CharT,OutputIterator> const& imbue_if_has_not(std::ios_base& ios)
+ {
+ if (!std::has_facet<duration_units<CharT,OutputIterator> >(ios.getloc()))
+ ios.imbue(std::locale(ios.getloc(), make()));
+ return std::use_facet<duration_units<CharT,OutputIterator> >(ios.getloc());
+ }
+#else
+ static inline duration_units<CharT,OutputIterator> const& imbue_if_has_not(std::ios_base& ios);
+#endif
/* TBR */
virtual bool swaps_value_unit_order() const = 0;
@@ -245,6 +291,10 @@
}
protected:
+
+ virtual ~duration_units() {}
+ virtual duration_units<CharT, OutputIterator>* clone() const = 0;
+
virtual std::basic_string<CharT> do_get_pattern() const=0;
virtual std::size_t do_get_plural_forms() const = 0;
virtual std::size_t do_get_plural_form(int_least64_t value) const = 0;
@@ -315,6 +365,8 @@
template <typename CharT, class OutputIterator>
std::locale::id duration_units<CharT, OutputIterator>::id;
+
+
///////////////////////////
// This class is used to define the strings for the default English
template <typename CharT=char, class OutputIterator = std::ostreambuf_iterator<CharT> >
@@ -328,12 +380,19 @@
duration_units<CharT, OutputIterator> (refs)
{
}
+ ~duration_units_default() {}
+
bool swaps_value_unit_order() const
{
return false;
}
protected:
+ duration_units<CharT, OutputIterator>* clone() const
+ {
+ return new duration_units_default<CharT, OutputIterator>();
+ }
+
std::size_t do_get_plural_forms() const
{
return 2;
@@ -801,6 +860,21 @@
};
+ template <typename CharT, class OutputIterator>
+ duration_units<CharT, OutputIterator>* duration_units<CharT, OutputIterator>::global_=new duration_units_default<CharT, OutputIterator>();
+
+#if ! defined BOOST_CHRONO_USES_DURATION_UNITS_GLOBAL
+ template <typename CharT, class OutputIterator>
+ duration_units<CharT,OutputIterator> const&
+ duration_units<CharT, OutputIterator>::imbue_if_has_not(std::ios_base& ios)
+ {
+ if (!std::has_facet<duration_units<CharT,OutputIterator> >(ios.getloc())) ios.imbue(
+ std::locale(ios.getloc(), new duration_units_default<CharT,OutputIterator>()));
+ return std::use_facet<duration_units<CharT,OutputIterator> >(ios.getloc());
+ }
+
+#endif
+
#if defined BOOST_CHRONO_IS_LOCALIZABLE_VIRTUAL
template <typename CharT, typename T>
Modified: trunk/boost/chrono/io/utility/ios_base_state_ptr.hpp
==============================================================================
--- trunk/boost/chrono/io/utility/ios_base_state_ptr.hpp (original)
+++ trunk/boost/chrono/io/utility/ios_base_state_ptr.hpp 2011-11-03 18:39:07 EDT (Thu, 03 Nov 2011)
@@ -24,19 +24,32 @@
namespace chrono
{
+ /**
+ * @c ios_base_state_ptr is a smart pointer to a ios_base specific state.
+ */
template<typename T>
class ios_base_state_ptr
{
public:
+ /**
+ * Explicit constructor.
+ * @param ios the ios
+ * @Effects Constructs a @c ios_base_state_ptr by storing the associated @c ios.
+ */
explicit ios_base_state_ptr(std::ios_base& ios) :
ios_(ios)
{
}
- //ios_base_state_ptr(std::ios_base ios, void (*cleanup_function)(T*));
~ios_base_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.
+ */
T const* get() const BOOST_NOEXCEPT
{
register_once(index(), ios_);
@@ -57,6 +70,10 @@
}
return static_cast<T*> (pw);
}
+ /**
+ * @Effects as if @c return get();
+ * @return the retrieved pointer.
+ */
T * operator->() BOOST_NOEXCEPT
{
return get();
@@ -66,6 +83,11 @@
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();
@@ -75,6 +97,10 @@
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
{
T const* f = get();
@@ -82,18 +108,23 @@
return f;
}
- void reset(T* new_value=0) BOOST_NOEXCEPT
+ /**
+ *
+ * @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());
- if (pw != 0)
- {
- delete static_cast<T*> (pw);
- }
- pw = new_value;
+ delete static_cast<T*> (pw);
+ pw = new_ptr;
}
//explicit
+ /**
+ * Explicit conversion to bool.
+ */
operator bool() const BOOST_NOEXCEPT
{
return get()!=0;
@@ -177,9 +208,9 @@
};
/**
- *
-
-
+ * @c ios_base_state is a non null variant of @c ios_base_state_ptr.
+ * @tparm T
+ * @Requires Must be DefaultConstructible and HeapAllocatable
*/
template<typename T>
class ios_base_state : public ios_base_state_ptr<T>
@@ -194,7 +225,6 @@
this->base_type::reset(new T());
}
}
- //ios_base_state(std::ios_base ios, void (*cleanup_function)(T*));
~ios_base_state()
{
}
@@ -228,7 +258,7 @@
long flags() const BOOST_NOEXCEPT
{
- return get();
+ return value();
}
long flags(long v) BOOST_NOEXCEPT
{
@@ -239,7 +269,7 @@
long setf(long v)
{
- long tmp = get();
+ long tmp = value();
ref() |= v;
return tmp;
}
@@ -251,7 +281,7 @@
long setf(long v, long mask)
{
- long tmp = get();
+ long tmp = value();
unsetf(mask);
ref() |= v & mask;
return tmp;
@@ -266,7 +296,7 @@
return ios_;
}
private:
- long get() const BOOST_NOEXCEPT
+ long value() const BOOST_NOEXCEPT
{
return ios_.iword(index());
}
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk