Boost logo

Boost :

From: Fernando Luis Cacciola Carballal (fcacciola_at_[hidden])
Date: 2001-05-08 09:18:34


Hello Everyone,

Altough I've been using part of the boost library for some time
I just recently joined the mailing this.
(actually, I joined about a year ago but didn't get the time to
follow it
so I drop off; but here I am again)

> Paul Bristow wrote...
> > I don't how to get down to just pi [...] so one can write
> >
> > double area = pi * r * r;
> >
> > User who are naive and experts who value clarity
> > both will demand this.
> > [snip]
> > Writing
> > boost::math::constants<const double>::pi
> > is just too much
> > pi<const double> is just bearable,
> > but it should be possible to disguise it and write just pi.
>
> I think we hit the buffers here. I agree that naive users will
> want to be able to say just "pi", but those who want the maths
> constants to be extensible to non-floating-point types will
> want just "pi" to be ambiguous. (If "r" is a float, did you
> want "pi" to be float, double, or long double?)
>
As a matter of fact, even

  boost::math::constants<const double>::pi

is not enough.

The reason is that it uses a constant expression, but for a user
defined type
there might not be any such expression that can be used.

I personally use the following:

template<class T> inline T cPi()
  { return boost::implicit_cast<T>(M_PI) ; }

Altough it requires the user to write:

double area = cPi<double>() * r * r;

which is even more intrusive, but it is 100% extensible.

For example, suppose you have a user defined 'real_t' number type,
you can:

real_t real_pi()
{
  static real_t r ( /* whatever */ ) ;
  return r ;
}

template<> inline real_t cPi<real_t>() { return real_pi() ; }

Furthermore, if the return expression inside cPi<>() is a constant
expression then
the optimizer will propagate this to expressions involving cPi<>, so
the runtime result
will be just the same.

Additionally, this approach allows you to add any number of new cPi<>
variations in a
system with only local changes, which is very important in large
systems.

> My suggestion that pi should be a class (with user defined
> conversion to the desired types) ...

I don't think so.
For different types we need different representations,
and we need to be able to use have a pi for a new type we just
started using.

Well, a template class maybe; but then it would have a single
conversion operator,
so it would be fundamentally the same as a free function.
(Unless your are thinking of having static instances of the class
floating around,
but I don't like it in that it introduces concurrency problems)

Regards,

Fernando Cacciola
Sierra s.r.l.
fcacciola_at_[hidden]
www.gosierra.com


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