$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
From: Chris Fairles (chris.fairles_at_[hidden])
Date: 2007-09-15 11:19:51
I was browsing through the math-toolkit and noticed a neat way of
type-a-fying mathematical constants. I had been doing something
similar but with static constants in a struct which required
definitions to be linked into each translation unit.
Here's a simplified version:
#define DEFINE_MATH_CONSTANT(name, x, exp)\
template <class T> inline T name()
{
static const T result =
::boost::lexical_cast<T>(STRINGIZE(JOIN(x, JOIN(e, exp))));
return result;
}
template <> inline float name<float>()
{ return JOIN(JOIN(x, JOIN(e, exp)), F); }
template <> inline double name<double>()
{ return JOIN(x, JOIN(e, exp)); }
template <> inline long double name<long double>()
{ return JOIN(JOIN(x, JOIN(e, exp)), L); }
But then I went to do something like:
DEFINE_MATH_CONSTANT(h, 6.62606896, -34)
And got:
error: pasting "e" and "-" does not give a valid preprocessing token
error: exponent has no digits
error: invalid suffix "F" on integer constant
...
etc. etc.
So I modified it to this:
#define DEFINE_MATH_CONSTANT(name, x, sign, exp)\
template <class T> inline T name()\
{\
static const T result =
::boost::lexical_cast<T>(STRINGIZE(JOIN(x, JOIN(JOIN(0e, sign),
exp))));\
return result;\
}\
template <> inline float name<float>()\
{ return JOIN(JOIN(x, JOIN(JOIN(0e, sign), exp)), F); }\
template <> inline double name<double>()\
{ return JOIN(x, JOIN(JOIN(0e, sign), exp)); }\
template <> inline long double name<long double>()\
{ return JOIN(JOIN(x, JOIN(JOIN(0e, sign), exp)), L); }
and now:
DEFINE_MATH_CONSTANT(h, 6.62606896, -, 34)
works as expected.
If its not too complicated, can someone walk through the substitution
process that the preprocessor is performing and highlight why pasting
'e' and '-' gives rise to an error where '0e' and '-' does not? I took
a brief look at the standard and I'm guiessing it has to do with ##
resulting in an invalid preprocessing token (with "e-" being invalid
where "0e-" isn't??).
The author of math-toolkit might want to implement such a solution as
well if negative exponents could potentially be used in defining math
constants.
Cheers,
Chris