1 //  (C) Copyright Howard Hinnant
2 //  (C) Copyright 2011 Vicente J. Botet Escriba
3 //  Copyright (c) Microsoft Corporation 2014
4 //  Use, modification and distribution are subject to the Boost Software License,
5 //  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
6 //  http://www.boost.org/LICENSE_1_0.txt).
7 //
8 
9 #ifndef BOOST_CHRONO_IO_TIME_POINT_UNITS_HPP
10 #define BOOST_CHRONO_IO_TIME_POINT_UNITS_HPP
11 
12 #include <boost/chrono/config.hpp>
13 #include <boost/chrono/process_cpu_clocks.hpp>
14 #include <boost/chrono/system_clocks.hpp>
15 #include <boost/chrono/thread_clock.hpp>
16 #include <boost/chrono/io/ios_base_state.hpp>
17 #include <string>
18 #include <iosfwd>
19 #include <ios>
20 #include <locale>
21 #include <algorithm>
22 
23 namespace boost
24 {
25   namespace chrono
26   {
27     /**
28      * customization point to the epoch associated to the clock @c Clock
29      * The default calls @c f.do_get_epoch(Clock()). The user can overload this function.
30      * @return the string epoch associated to the @c Clock
31      */
32     template <typename CharT, typename Clock, typename TPUFacet>
get_epoch_custom(Clock,TPUFacet & f)33     std::basic_string<CharT> get_epoch_custom(Clock, TPUFacet& f)
34     {
35       return f.do_get_epoch(Clock());
36     }
37 
38     /**
39      * @c time_point_units facet gives useful information about the time_point pattern,
40      * the text associated to a time_point's epoch,
41      */
42     template <typename CharT=char>
43     class time_point_units: public std::locale::facet
44     {
45     public:
46       /**
47        * Type of character the facet is instantiated on.
48        */
49       typedef CharT char_type;
50       /**
51        * Type of character string used by member functions.
52        */
53       typedef std::basic_string<char_type> string_type;
54 
55       /**
56        * Unique identifier for this type of facet.
57        */
58       static std::locale::id id;
59 
60       /**
61        * Construct a @c time_point_units facet.
62        * @param refs
63        * @Effects Construct a @c time_point_units facet.
64        * If the @c refs argument is @c 0 then destruction of the object is
65        * delegated to the @c locale, or locales, containing it. This allows
66        * the user to ignore lifetime management issues. On the other had,
67        * if @c refs is @c 1 then the object must be explicitly deleted;
68        * the @c locale will not do so. In this case, the object can be
69        * maintained across the lifetime of multiple locales.
70        */
time_point_units(size_t refs=0)71       explicit time_point_units(size_t refs = 0) :
72         std::locale::facet(refs)
73       {
74       }
75 
76       /**
77        * @return the pattern to be used by default.
78        */
79       virtual string_type get_pattern() const =0;
80 
81       /**
82        * @return the epoch associated to the clock @c Clock calling @c do_get_epoch(Clock())
83        */
84       template <typename Clock>
get_epoch() const85       string_type get_epoch() const
86       {
87         return get_epoch_custom<CharT>(Clock(), *this);
88       }
89 
90     protected:
91       /**
92        * Destroy the facet.
93        */
~time_point_units()94       virtual ~time_point_units() {}
95 
96     public:
97 
98       /**
99        *
100        * @param c a dummy instance of @c system_clock.
101        * @return The epoch string associated to the @c system_clock.
102        */
103       virtual string_type do_get_epoch(system_clock) const=0;
104 
105       /**
106        *
107        * @param c a dummy instance of @c steady_clock.
108        * @return The epoch string associated to the @c steady_clock.
109        */
110       virtual string_type do_get_epoch(steady_clock) const=0;
111 
112 #if defined(BOOST_CHRONO_HAS_PROCESS_CLOCKS)
113       /**
114        *
115        * @param c a dummy instance of @c process_real_cpu_clock.
116        * @return The epoch string associated to the @c process_real_cpu_clock.
117        */
118       virtual string_type do_get_epoch(process_real_cpu_clock) const=0;
119 #if ! BOOST_OS_WINDOWS || BOOST_PLAT_WINDOWS_DESKTOP
120       /**
121        *
122        * @param c a dummy instance of @c process_user_cpu_clock.
123        * @return The epoch string associated to the @c process_user_cpu_clock.
124        */
125       virtual string_type do_get_epoch(process_user_cpu_clock) const=0;
126       /**
127        *
128        * @param c a dummy instance of @c process_system_cpu_clock.
129        * @return The epoch string associated to the @c process_system_cpu_clock.
130        */
131       virtual string_type do_get_epoch(process_system_cpu_clock) const=0;
132       /**
133        *
134        * @param c a dummy instance of @c process_cpu_clock.
135        * @return The epoch string associated to the @c process_cpu_clock.
136        */
137       virtual string_type do_get_epoch(process_cpu_clock) const=0;
138 #endif
139 #endif
140 #if defined(BOOST_CHRONO_HAS_THREAD_CLOCK)
141       /**
142        *
143        * @param c a dummy instance of @c thread_clock.
144        * @return The epoch string associated to the @c thread_clock.
145        */
146       virtual string_type do_get_epoch(thread_clock) const=0;
147 #endif
148 
149     };
150 
151     template <typename CharT>
152     std::locale::id time_point_units<CharT>::id;
153 
154 
155     // This class is used to define the strings for the default English
156     template <typename CharT=char>
157     class time_point_units_default: public time_point_units<CharT>
158     {
159     public:
160       /**
161        * Type of character the facet is instantiated on.
162        */
163       typedef CharT char_type;
164       /**
165        * Type of character string returned by member functions.
166        */
167       typedef std::basic_string<char_type> string_type;
168 
time_point_units_default(size_t refs=0)169       explicit time_point_units_default(size_t refs = 0) :
170         time_point_units<CharT> (refs)
171       {
172       }
~time_point_units_default()173       ~time_point_units_default() {}
174 
175       /**
176        * @return the default pattern "%d%e".
177        */
get_pattern() const178       string_type get_pattern() const
179       {
180         static const CharT t[] =
181         { '%', 'd', '%', 'e' };
182         static const string_type pattern(t, t + sizeof (t) / sizeof (t[0]));
183 
184         return pattern;
185       }
186 
187     //protected:
188       /**
189        * @param c a dummy instance of @c system_clock.
190        * @return The epoch string returned by @c clock_string<system_clock,CharT>::since().
191        */
do_get_epoch(system_clock) const192       string_type do_get_epoch(system_clock ) const
193       {
194         return clock_string<system_clock,CharT>::since();
195       }
196       /**
197        * @param c a dummy instance of @c steady_clock.
198        * @return The epoch string returned by @c clock_string<steady_clock,CharT>::since().
199        */
do_get_epoch(steady_clock) const200       string_type do_get_epoch(steady_clock ) const
201       {
202         return clock_string<steady_clock,CharT>::since();
203       }
204 
205 #if defined(BOOST_CHRONO_HAS_PROCESS_CLOCKS)
206       /**
207        * @param c a dummy instance of @c process_real_cpu_clock.
208        * @return The epoch string returned by @c clock_string<process_real_cpu_clock,CharT>::since().
209        */
do_get_epoch(process_real_cpu_clock) const210       string_type do_get_epoch(process_real_cpu_clock ) const
211       {
212         return clock_string<process_real_cpu_clock,CharT>::since();
213       }
214 #if ! BOOST_OS_WINDOWS || BOOST_PLAT_WINDOWS_DESKTOP
215       /**
216        * @param c a dummy instance of @c process_user_cpu_clock.
217        * @return The epoch string returned by @c clock_string<process_user_cpu_clock,CharT>::since().
218        */
do_get_epoch(process_user_cpu_clock) const219       string_type do_get_epoch(process_user_cpu_clock ) const
220       {
221         return clock_string<process_user_cpu_clock,CharT>::since();
222       }
223       /**
224        * @param c a dummy instance of @c process_system_cpu_clock.
225        * @return The epoch string returned by @c clock_string<process_system_cpu_clock,CharT>::since().
226        */
do_get_epoch(process_system_cpu_clock) const227       string_type do_get_epoch(process_system_cpu_clock ) const
228       {
229         return clock_string<process_system_cpu_clock,CharT>::since();
230       }
231       /**
232        * @param c a dummy instance of @c process_cpu_clock.
233        * @return The epoch string returned by @c clock_string<process_cpu_clock,CharT>::since().
234        */
do_get_epoch(process_cpu_clock) const235       string_type do_get_epoch(process_cpu_clock ) const
236       {
237         return clock_string<process_cpu_clock,CharT>::since();
238       }
239 
240 #endif
241 #endif
242 #if defined(BOOST_CHRONO_HAS_THREAD_CLOCK)
243       /**
244        * @param c a dummy instance of @c thread_clock.
245        * @return The epoch string returned by @c clock_string<thread_clock,CharT>::since().
246        */
do_get_epoch(thread_clock) const247       string_type do_get_epoch(thread_clock ) const
248       {
249         return clock_string<thread_clock,CharT>::since();
250       }
251 #endif
252 
253     };
254 
255 
256   } // chrono
257 
258 } // boost
259 
260 #endif  // header
261