Tomographer  v1.0a
Tomographer C++ Framework Documentation
fmt.h
Go to the documentation of this file.
1 /* This file is part of the Tomographer project, which is distributed under the
2  * terms of the MIT license.
3  *
4  * The MIT License (MIT)
5  *
6  * Copyright (c) 2015 ETH Zurich, Institute for Theoretical Physics, Philippe Faist
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining a copy
9  * of this software and associated documentation files (the "Software"), to deal
10  * in the Software without restriction, including without limitation the rights
11  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12  * copies of the Software, and to permit persons to whom the Software is
13  * furnished to do so, subject to the following conditions:
14  *
15  * The above copyright notice and this permission notice shall be included in
16  * all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24  * SOFTWARE.
25  */
26 
27 #ifndef TOMOGRAPHER_TOOLS_FMT_H
28 #define TOMOGRAPHER_TOOLS_FMT_H
29 
36 #include <cstdio>
37 #include <cstdarg>
38 
39 #include <chrono>
40 #include <string>
41 #include <sstream> // stringstream
42 #include <iostream>
43 
44 #include <tomographer/tools/util.h> // PRINTFN_ARGS_SAFE
45 
46 
47 namespace Tomographer
48 {
49 namespace Tools
50 {
51 
52 
53 
54 //
55 // =============================================================================
56 //
57 // Formatting Utilities
58 //
59 
60 
67 {
68  std::string msg;
69 public:
71  bad_fmts_format(const std::string& msg_) : msg(msg_) { }
72  ~bad_fmts_format() throw() { }
73 
74  const char * what() const throw() {
75  return msg.c_str();
76  }
77 };
78 
79 
80 
85 inline std::string vfmts(const char* fmt, va_list vl)
86 {
87  // check out printf() formatting for std::string:
88  // http://stackoverflow.com/a/10150393/1694896
89  // http://stackoverflow.com/a/26197300/1694896
90 
91  int size = 10;
92  char * buffer = new char[size];
93  va_list ap1;
94  va_copy(ap1, vl);
95  int nsize = std::vsnprintf(buffer, size, fmt, ap1);
96  if (nsize < 0) {
97  // failure: bad format probably
98  throw bad_fmts_format("vsnprintf("+std::string(fmt)+") failure: code="+std::to_string(nsize));
99  }
100  if(size <= nsize) {
101  // buffer too small: delete buffer and try again
102  delete[] buffer;
103  size = nsize+1; // +1 for "\0"
104  buffer = new char[size];
105  nsize = std::vsnprintf(buffer, size, fmt, vl);
106  }
107  std::string ret(buffer);
108  delete[] buffer;
109  va_end(ap1);
110  return ret;
111 }
112 
113 
118 inline std::string fmts(const char * fmt, ...) PRINTF1_ARGS_SAFE;
119 
120 // definition. It seems definitions cannot have function attributes (here
121 // PRINTF1_ARGS_SAFE), so that's why it's separate
122 inline std::string fmts(const char * fmt, ...)
123 {
124  va_list ap;
125  va_start(ap, fmt);
126  std::string result = vfmts(fmt, ap);
127  va_end(ap);
128  return result;
129 }
130 
131 
143 #define streamstr(tokens) \
144  dynamic_cast<std::ostringstream&>( \
145  std::ostringstream().seekp(0) << tokens \
146  ).str() \
147 
148 
155 #define streamcstr(tokens) streamstr(tokens).c_str()
156 
157 
158 
159 
160 // =============================================================================
161 
162 
170 inline std::string fmt_duration(double seconds)
171 {
172  // split `seconds' into integral part and fractional part
173  double dt_i_d;
174  double dt_f = std::modf(seconds, &dt_i_d);
175  int dt_i = (int)(dt_i_d+0.5);
176 
177  return fmts("%d:%02d:%02d.%03d", dt_i/3600, (dt_i/60)%60, dt_i%60, (int)(dt_f*1000+0.5));
178 };
179 
189 template<typename Rep, typename Period>
191 {
192  typedef std::chrono::duration<Rep, Period> Duration;
193 
194  // delta-time, in seconds and fraction of seconds
195  double seconds = (double)dt.count() * Duration::period::num / Duration::period::den ;
196 
197  return fmt_duration(seconds);
198 };
199 
200 
201 
202 } // namespace Tools
203 } // namespace Tomographer
204 
205 
206 #endif
Base namespace for the Tomographer project.
Definition: dmmhrw.h:51
std::string vfmts(const char *fmt, va_list vl)
printf- formatting to a std::string, with va_list pointer
Definition: fmt.h:85
T to_string(T...args)
STL namespace.
T modf(T...args)
STL class.
Exception for bad printf format.
Definition: fmt.h:66
STL class.
T vsnprintf(T...args)
#define PRINTF1_ARGS_SAFE
attributes for a function accepting printf-like variadic arguments
Definition: util.h:72
std::string fmts(const char *fmt,...)
printf- format to a std::string
Definition: fmt.h:122
Some C++ utilities, with a tad of C++11 tricks.
T c_str(T...args)
std::string fmt_duration(double seconds)
Format a number of seconds into a human-readable string.
Definition: fmt.h:170
bad_fmts_format(const std::string &msg_)
Construct an exception for bad printf formatting. Provide an error message here.
Definition: fmt.h:71