
On Fri, Dec 16, 2011 at 3:26 PM, Jeffrey Lee Hellrung, Jr. <jeffrey.hellrung@gmail.com> wrote:
On Fri, Dec 16, 2011 at 10:23 AM, John Maddock <boost.regex@virgin.net>wrote:
Folks we have a problem: rather late in the day I've discovered that our Math.Constants code doesn't compile on anything except VC++, and the problem is preprocessor token pasting. So I'm hoping we have some experts around here that can help!
The issue is we currently construct the constants from a macro invocation such as:
BOOST_DEFINE_MATH_CONSTANT(**half, 5.**000000000000000000000000000000**000000, 000000000000000000000000000000**000000000000000000000000000000**00000000000000, -01);
But the "-01" part (the exponent) isn't a valid pp-token, so trying to token-paste it fails on GCC (compiler error).
Does anyone know if there's a way to overcome this?
Maybe include the "e" in that 4th argument? E.g., "e-01". If you actually need to recover the "-01" without the e, I'm pretty sure you can do something like
#define BOOST_DEFINE_MATH_CONSTANT(name, x, y, exp) Yes, as indicated by Jeff, you can have your users to always prefix exp with e (I looked at your macro and you always CAT(e, exp)). BTW, can x ever start with a symbol (-)? BOOST_DEFINE_MATH_CONSTANT(half, 5.000000000000000000000000000000000000, 00000000000000000000000000000000000000000000000000000000000000000000000000, e-01); // OK Otherwise it seems you can use PP_SEQ_CAT: #include <boost/preprocessor/seq/cat.hpp> #include <boost/preprocessor/stringize.hpp> #define BOOST_DEFINE_MATH_CONSTANT(name, x, y, exp)\ template <class T> inline T name(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(T))\ {\ static const T result = ::boost::lexical_cast<T>(BOOST_PP_STRINGIZE( \ BOOST_PP_SEQ_CAT( (x) (y) (e) (exp) )));\ return result;\ }\ template <> inline float name<float>(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(float))\ { return BOOST_PP_SEQ_CAT( (x) (e) (exp) (F)); }\ template <> inline double name<double>(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(double))\ { return BOOST_PP_SEQ_CAT( (x) (e) (exp) ); }\ template <> inline long double name<long double>(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(long double))\ { return BOOST_PP_SEQ_CAT( (x) (e) (exp) (L) ); } BOOST_DEFINE_MATH_CONSTANT(half, 5.000000000000000000000000000000000000, 00000000000000000000000000000000000000000000000000000000000000000000000000, -01); // ok but no e This seems to work even with x = -1.0: BOOST_PP_SEQ_CAT( (-1.0) (123) (e) (-10) ) // -1.0123e- 10 But I'm not sure how this actually works inside Boost.Preprocessor... HTH, --Lorenzo