Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
time_manip.cpp
Go to the documentation of this file.
1
29#include <ctime> // for localtime(), time()
30#include <iomanip> // for __rw_smanip
31#include <iostream> // for cout
32#include <locale> // for time_get, time_put
33
34#include <examples.h>
35
36
37// implementation class of the extraction manipulator of std::tm values
38template <class charT>
40{
41 std::tm *tmb_;
42
43 explicit time_get_manip (std::tm *tmb)
44 : tmb_ (tmb) { }
45
46 template <class Traits>
47 void operator() (std::basic_istream<charT, Traits>&, const charT*) const;
48};
49
50
51template <class charT>
52template <class Traits>
54operator()(std::basic_istream<charT, Traits> &strm, const charT *fmt) const
55{
56 // begin by constructing a sentry object for the stream
57 const typename std::basic_istream<charT, Traits>::sentry guard (strm);
58
59 if (guard) {
60
61 // compute the end pointer of the format specifier
62 const charT* const end = fmt + Traits::length (fmt);
63
64 std::ios_base::iostate err = strm.goodbit;
65
66 typedef std::istreambuf_iterator<charT> Iter;
67 typedef std::time_get<charT, Iter> TimeGet;
68
69 try {
70 const TimeGet &tg = std::use_facet<TimeGet>(strm.getloc ());
71
72 // try to extract the time from the stream using
73 // an extension of this implementation
74 tg.get (Iter (strm.rdbuf ()), Iter (), strm, err, tmb_, fmt, end);
75 }
76 catch (...) {
77 bool rethrow = false;
78
79 try {
80 // set badbit in exceptions without causing
81 // ios_base::failure to be thrown
82 strm.setstate (strm.badbit);
83 }
84 catch (...) {
85 // set a flag to rethrow the originally caught exception
86 rethrow = true;
87 }
88
89 if (rethrow)
90 throw;
91 }
92
93 if (strm.goodbit != err)
94 strm.setstate (err);
95 }
96}
97
98
99// implementation class of the insertion manipulator of std::tm values
100template <class charT>
102{
103 const std::tm *tmb_;
104
105 explicit time_put_manip (const std::tm *tmb)
106 : tmb_ (tmb) { }
107
108 template <class Traits>
109 void operator() (std::basic_ostream<charT, Traits>&, const charT*) const;
110};
111
112
113template <class charT>
114template <class Traits>
116operator() (std::basic_ostream<charT, Traits> &strm, const charT *fmt) const
117{
118 // begin by constructing a sentry object for the stream
119 const typename std::basic_ostream<charT, Traits>::sentry guard (strm);
120
121 if (guard) {
122
123 // compute the end pointer of the format specifier
124 const charT* const end = fmt + Traits::length (fmt);
125
126 typedef std::ostreambuf_iterator<charT> Iter;
127 typedef std::time_put<charT, Iter> TimePut;
128
129 Iter it (strm.rdbuf ());
130
131 try {
132 const TimePut &tp = std::use_facet<TimePut>(strm.getloc ());
133
134 // try to format and insert the time object into the stream
135 it = tp.put (it, strm, strm.fill (), tmb_, fmt, end);
136 }
137 catch (...) {
138 bool rethrow = false;
139
140 try {
141 // set badbit in exceptions without causing
142 // ios_base::failure to be thrown
143 strm.setstate (strm.badbit);
144 }
145 catch (...) {
146 // set a flag to rethrow the originally caught exception
147 rethrow = true;
148 }
149
150 if (rethrow)
151 throw;
152 }
153
154 // set badbit on failure to insert (which may cause
155 // ios_base::failure to be thrown)
156 if (it.failed ())
157 strm.setstate (strm.badbit);
158 }
159}
160
161
162// manipulator for the extraction of std::tm values
163template <class charT>
164inline std::__rw_smanip<time_get_manip<charT>, const charT*>
165get_time (std::tm *tmb, const charT *fmt)
166{
167 // return an object of the manipulator implementation type
168 // that will store the function arguments until its function
169 // call operator is invoked by the extraction operator for
170 // std::__rw_smanip
171 typedef time_get_manip<charT> GetTime;
172 typedef std::__rw_smanip<GetTime, const charT*> Manip;
173
174 return Manip (GetTime (tmb), fmt);
175}
176
177
178// manipulator for the insertion of std::tm values
179template <class charT>
180inline std::__rw_smanip<time_put_manip<charT>, const charT*>
181put_time (const std::tm *tmb, const charT *fmt)
182{
183 // return an object of the manipulator implementation type
184 // that will store the function arguments until its function
185 // call operator is invoked by the insertion operator for
186 // std::__rw_smanip
187 typedef time_put_manip<charT> PutTime;
188 typedef std::__rw_smanip<PutTime, const charT*> Manip;
189
190 return Manip (PutTime (tmb), fmt);
191}
192
193
194int main (int argc, char *argv[])
195{
196 // the first optional command line argument specifies
197 // the extration format specifier string
198 const char* const get_fmt = argc < 2 ? "%c" : argv [1];
199
200 // the second optional command line argument specifies
201 // the insertion format specifier string
202 const char* const put_fmt = argc < 3 ? "%c" : argv [2];
203
204 // obtain the local time
205 const std::time_t t = std::time (0);
206 std::tm* const tmb = std::localtime (&t);
207
208 // set cout's locale to the one specified in the environment
209 std::cout.imbue (std::locale (""));
210
211 // output the local time using the specified output format
212 std::cout << put_time (tmb, put_fmt) << '\n';
213
214 // input time in the specified input format using the "C" locale
215 std::cin >> get_time (tmb, get_fmt);
216
217 // on success output the extracted time using the specified
218 // output format; otherwise output an error message
219 if (std::cin.good ())
220 std::cout << put_time (tmb, put_fmt) << '\n';
221 else {
222 std::cerr << "get_time (std::tm*, \"" << get_fmt << "\") failed\n";
223 return 1;
224 }
225
226 return 0;
227}
#define t
Definition 17.names.cpp:136
#define charT
Definition 17.names.cpp:456
#define strm
Definition 17.names.cpp:549
std::time_get< char > TimeGet
std::time_put< char > TimePut
const int end
#define main
std::ostream_iterator< int, char, std::char_traits< char > > Iter
Definition alg7.cpp:64
time_get_manip(std::tm *tmb)
std::tm * tmb_
void operator()(std::basic_istream< charT, Traits > &, const charT *) const
const std::tm * tmb_
void operator()(std::basic_ostream< charT, Traits > &, const charT *) const
time_put_manip(const std::tm *tmb)
std::__rw_smanip< time_put_manip< charT >, const charT * > put_time(const std::tm *tmb, const charT *fmt)
std::__rw_smanip< time_get_manip< charT >, const charT * > get_time(std::tm *tmb, const charT *fmt)