9 #ifndef ThePEG_UnitIO_H
10 #define ThePEG_UnitIO_H
21 #if defined __APPLE__ && defined __MACH__
22 extern "C" int isnan(
double) throw();
23 extern "C"
int isinf(
double) throw();
41 template <
typename T,
typename UT>
69 template <
typename T,
typename UT>
89 template <
typename T,
typename UT>
96 template <
typename T,
typename UT>
103 template <
typename OStream,
typename T,
typename UT>
110 template <
typename IStream,
typename T,
typename UT>
119 template <
typename IStream,
typename T,
typename UT>
121 std::complex<double> d;
127 template <
typename OStream,
typename T,
typename UT>
128 OStream & operator<<(OStream & os, const OUnit<T,UT> & u) {
134 template <
typename IStream,
typename T,
typename UT>
151 template <
typename T,
typename UT>
156 OUnitErr(
const T & t,
const T & dt,
const UT & u):
x(t/u),
dx(dt/u) {}
167 template <
typename T,
typename UT>
178 template <
typename OStream,
typename T,
typename UT>
179 OStream & operator<<(OStream & os, const OUnitErr<T,UT> & u) {
180 if ( isnan(u.x) || isinf(u.x) )
return os << u.x;
181 if ( isnan(u.dx) || isinf(u.dx) )
return os << u.x <<
'(' << u.dx <<
')';
182 double dx = min(u.dx, abs(u.x));
183 if ( dx <= 0.0 )
return os << u.x;
185 osse << std::scientific << setprecision(0) << dx;
186 string sse = osse.str();
187 string::size_type ee = sse.find(
'e');
188 long m =
static_cast<long>(round(abs(u.x)/std::pow(10.0,std::atoi(sse.substr(ee + 1).c_str()))));
189 int powx = m <= 0? os.precision(): int(log10(
double(m)));
190 if ( m <= 0 || powx > os.precision() ) sse[0]=
'0';
192 oss << std::scientific << setprecision(powx) << u.x;
193 string ss = oss.str();
194 string::size_type e = ss.find(
'e');
196 int pp = std::atoi(ss.substr(e + 1).c_str());
198 out << ss.substr(0, e) <<
"(" << sse[0] <<
")" << ss.substr(e);
199 else if ( (pp - 1)%3 == 0 ) {
201 oss << std::scientific << setprecision(powx) << u.x/10.0;
202 string ss = oss.str();
203 string::size_type e = ss.find(
'e');
205 out << ss.substr(0, e) <<
"0(" << sse[0] <<
"0)" << ss.substr(e);
206 else if ( powx == 1 )
207 out << ss.substr(0, ss.find(
'.'))
208 << ss.substr(ss.find(
'.') + 1, e - ss.find(
'.') - 1)
209 <<
"(" << sse[0] <<
")" << ss.substr(e);
211 swap(ss[ss.find(
'.')], ss[ss.find(
'.') + 1]);
212 out << ss.substr(0, e) <<
"(" << sse[0] <<
")" << ss.substr(e);
217 oss << std::scientific << setprecision(powx) << u.x*10.0;
218 string ss = oss.str();
219 string::size_type e = ss.find(
'e');
221 out <<
"0." << ss.substr(0, e) <<
"(" << sse[0] <<
")" << ss.substr(e);
223 swap(ss[ss.find(
'.')], ss[ss.find(
'.') - 1]);
224 out << ss.substr(0, ss.find(
'.')) <<
"0" << ss.substr(ss.find(
'.'), e)
225 <<
"(" << sse[0] <<
")" << ss.substr(e);
228 return os << out.str();
236 template <
typename T,
typename UT>
255 template <
typename T,
typename UT>
266 template <
typename IStream,
typename T,
typename UT>
273 string::size_type open = s.find(
'(');
274 string::size_type close = s.find(
')');
278 if ( open != string::npos && close != string::npos ) {
279 se = s.substr(open + 1);
280 sp += s.substr(close + 1);
281 string::size_type dot = s.find(
'.');
282 if ( dot != string::npos && dot < open ) pe = std::pow(10.0, 1.0 - (open - dot));
285 istringstream(s) >> x;
286 istringstream(se) >> dx;
287 istringstream(sp) >> ex;
290 u.
dx = dx*ex*pe*u.
ut;
IUnit(const IUnit< T, UT > &iu)
Copy constructor.
OUnitErr< T, UT > ouniterr(const T &t, const T &dt, const UT &ut)
Helper function creating a OUnitErr object.
OUnitErr is used to write out unitful numbers with an error estimate on a standard ostream...
void ounitstream(OStream &os, const vector< T, Alloc > &v, UT &u)
Ouput a vector of objects with the specified unit.
double dx
The estimated error of the number to be written.
OUnit(const OUnit< T, UT > &iu)
Copy constructor.
double x
The number to be written.
This is the main namespace within which all identifiers in ThePEG are declared.
The OUnit< class is used to facilitate output of unitful numbers to a persistent stream.
const T & theX
Reference to the object to be written.
void iunitstream(IStream &is, vector< T, Alloc > &v, UT &u)
Input a vector of objects with the specified unit.
OUnit(const T &t, const UT &u)
Constructor given an object to be written assuming the given unit.
IUnitErr(T &t, T &dt, const UT &u)
Constructor given an object to be read assuming the given unit.
The IUnit class is used to facilitate input of unitful numbers from and to a persistent stream...
IUnit(T &t, const UT &u)
Constructor given an object to be read assuming the given unit.
UT ut
The unit assumed when reading the object.
T & dx
The estimated error of the number to be read.
const UT & theUnit
The unit assumed when writing the object.
const UT & theUnit
The unit assumed when reading the object.
OUnit< T, UT > ounit(const T &t, const UT &ut)
Helper function creating a OUnit object given an object and a unit.
vector< T > & operator>>(vector< T > &tv, U &u)
Overload the right shift operator for vector to pop objects from a vector.
OUnitErr(const T &t, const T &dt, const UT &u)
Constructor given an object to be written assuming the given unit.
The IUnitErr class is used to facilitate input of unitful numbers with error estimates written out us...
IUnitErr< T, UT > iuniterr(T &t, T &dt, const UT &ut)
Helper function creating a IUnitErr object.
T & theX
Reference to the object to be read.
T & x
Reference to the object to be read.
IUnit< T, UT > iunit(T &t, const UT &ut)
Helper function creating a IUnit object given an object and a unit.