tostring.h
1//-*-C++-*-
2/***************************************************************************
3 *
4 * Copyright (C) 2004 - 2016 by Willem van Straten
5 * Licensed under the Academic Free License version 2.1
6 *
7 ***************************************************************************/
8
9// psrchive/Util/units/tostring.h
10
11#ifndef __TOSTRING_H
12#define __TOSTRING_H
13
14#include <string>
15#include <sstream>
16#include <limits>
17#include <typeinfo>
18
19// works around the circular dependence between Error and tostring
20void raise (const char* name, const std::string& exception);
21
22class ToString
23{
24 typedef std::ios_base::fmtflags fmtflags;
25
26#define fmtzero fmtflags(0)
27
28 unsigned precision;
29 bool precision_set;
30
31 fmtflags setf;
32 bool setf_set;
33
34 fmtflags unsetf;
35 bool unsetf_set;
36
37public:
38
39 ToString () { reset_modifiers(); }
40
41 void reset_modifiers ()
42 {
43 precision_set = setf_set = unsetf_set = false;
44 precision = 0;
45 setf = unsetf = fmtzero;
46 }
47
48 void set_precision (unsigned p) { precision = p; precision_set = true; }
49 void set_setf (fmtflags f) { setf = f; setf_set = true; }
50 void set_unsetf (fmtflags f) { unsetf = f; unsetf_set = true; }
51
52 template<class T>
53 std::string operator () (const T& input) const
54 {
55 std::ostringstream ost;
56
57 if (setf_set)
58 ost.setf (setf);
59
60 if (unsetf_set)
61 ost.unsetf (unsetf);
62
63 if (precision_set)
64 ost.precision (precision);
65 else
66 ost.precision (std::numeric_limits<T>::digits10);
67
68 ost << input;
69
70 if (ost.fail())
71 raise ("tostring",
72 "failed to convert "+ std::string(typeid(T).name()) +" to string");
73
74 return ost.str();
75 }
76};
77
78
79/* the following global variables are not nested-call or multi-thread
80 safe and should be used only when it is extremely difficult to pass
81 the relevant arguments directly to the tostring function */
82
83extern unsigned tostring_precision;
84extern std::ios_base::fmtflags tostring_setf;
85extern std::ios_base::fmtflags tostring_unsetf;
86
87#define FMTFLAGS_ZERO std::ios_base::fmtflags(0)
88
89template<class T>
90std::string tostring (const T& input,
91 unsigned precision = std::numeric_limits<T>::digits10,
92 std::ios_base::fmtflags set = FMTFLAGS_ZERO,
93 std::ios_base::fmtflags unset = FMTFLAGS_ZERO)
94{
95 ToString tostr;
96
97 if (tostring_setf)
98 tostr.set_setf (tostring_setf);
99 else if (set)
100 tostr.set_setf (set);
101
102 if (tostring_unsetf)
103 tostr.set_unsetf (tostring_unsetf);
104 else if (unset)
105 tostr.set_unsetf (unset);
106
107 if (tostring_precision)
108 tostr.set_precision (tostring_precision);
109 else
110 tostr.set_precision (precision);
111
112 return tostr( input );
113}
114
115template<class T>
116T fromstring (const std::string& input)
117{
118 std::istringstream ist;
119
120 ist.clear();
121 ist.str(input);
122
123 T retval = T();
124 ist >> retval;
125
126 if (ist.fail())
127 raise ("fromstring", "failed to parse '"+ input +"'");
128
129 return retval;
130}
131
132// string class specialization
133inline std::string tostring (const std::string& input)
134{
135 return input;
136}
137
138// string class specialization
139template<>
140inline std::string fromstring<std::string> (const std::string& input)
141{
142 return input;
143}
144
145// char* specialization
146inline std::string tostring (const char* input)
147{
148 return input;
149}
150
151#include "Error.h"
152
153/*
154 If you've already written a function that converts string to Type,
155 and this function throws an exception of type Error when the string
156 cannot be parsed, then you can use this template to implement an
157 extraction operator (operator >>). See Util/genutil/Types.C for an
158 example.
159*/
160template<typename Type, typename String2Type>
161std::istream& extraction (std::istream& is, Type& t, String2Type string2type)
162{
163 std::streampos pos = is.tellg();
164 std::string ss;
165
166 try {
167 is >> ss;
168 t = string2type (ss);
169 }
170 catch (Error& e) {
171 is.setstate(std::istream::failbit);
172 is.seekg(pos);
173 }
174 return is;
175}
176
177#endif
A convenient exception handling class.
Definition Error.h:54

Generated using doxygen 1.14.0