Boost logo

Boost :

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


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk