Boost logo

Boost :

From: Boris Fomitchev (fbp_at_[hidden])
Date: 1999-12-14 20:01:44


I see. Looks like full-scale solution is needed then :

template <class _Tp>
struct _STL_math_proxy {
  static inline _Tp _do_abs(const _Tp& __x) { return __STL_MATH_STD::abs(__x); }
  static inline _Tp _do_acos(const _Tp& __x) { return __STL_MATH_STD::acos(__x); }
  static inline _Tp _do_asin(const _Tp& __x) { return __STL_MATH_STD::asin(__x); }
  static inline _Tp _do_atan(const _Tp& __x) { return __STL_MATH_STD::atan(__x); }
  static inline _Tp _do_atan2(const _Tp& __x, const _Tp& __y) { return __STL_MATH_STD::atan2(__x,
__y); }
  static inline _Tp _do_cos(const _Tp& __x) { return __STL_MATH_STD::cos(__x); }
  static inline _Tp _do_cosh(const _Tp& __x) { return __STL_MATH_STD::cosh(__x); }
  static inline _Tp _do_log(const _Tp& __x) { return __STL_MATH_STD::log(__x); }
  static inline _Tp _do_log10(const _Tp& __x) { return __STL_MATH_STD::log10(__x); }
  static inline _Tp _do_pow(const _Tp& __x, const _Tp& __y) { return __STL_MATH_STD::pow(__x, __y);
}
  static inline _Tp _do_sin(const _Tp& __x) { return __STL_MATH_STD::sin(__x); }
  static inline _Tp _do_sinh(const _Tp& __x) { return __STL_MATH_STD::sinh(__x); }

  static inline _Tp _do_sqrt(const _Tp& __x) { return __STL_MATH_STD::sqrt(__x); }
  static inline _Tp _do_tan(const _Tp& __x) { return __STL_MATH_STD::tan(__x); }
  static inline _Tp _do_tanh(const _Tp& __x) { return __STL_MATH_STD::tanh(__x); }
  static inline _Tp _do_exp(const _Tp& __x) { return __STL_MATH_STD::exp(__x); }
  static inline _Tp _do_hypot(const _Tp& __x, const _Tp& __y) { return __STL_MATH_STD::hypot(__x,
__y); }
};

where __STL_MATH_STD is empty for VC++.
Then you have to write specialization for complex<> (you cannot do partial with VC++, so the best you
can do
is to provide two full specializations for complex<float> and complex<double>), which would use
std::abs instead of ::abs.

From rational<Tp>::abs you call __STL_math_proxy<Tp>::abs()

Looks like a crap, doesn't it ? ;).

BTW, if you intend to use rational on complex<>, you also have to change default in rational
constructor to IntType().

-Boris.

jsiek_at_[hidden] wrote:

> Does this work if the type is complex? (perhaps this
> doesn't apply here, but it does to many of my examples)
>
> Thanks,
>
> Jeremy
>
> Boris Fomitchev writes:
> > Well, abs:: already contains the conditional you need, just make it explicit (example below
> > works):
> >
> >
> > template <typename IntType>
> > inline rational<IntType> abs(const rational<IntType>& r)
> > {
> > #ifndef BOOST_NO_STDC_NAMESPACE
> > // We want to use abs() unadorned below, so that if IntType is a
> > // user-defined type, the name lookup rules will work to find an
> > // appropriate abs() defined for IntType.
> > //
> > // We protect this with BOOST_NO_STDC_NAMESPACE, as some compilers
> > // don't put abs into std:: (notably MS Visual C++) and so we can't
> > // "use" it from there.
> > // fbp : changed to explicit qualifier
> > // using std::abs;
> > // Note that with normalized fractions, the denominator is always positive.
> > return rational<IntType>(std::abs(r.num), r.den);
> > #else
> > // Note that with normalized fractions, the denominator is always positive.
> > return rational<IntType>(::abs(r.num), r.den);
> > #endif
> > }
> >
> >
> > If you need more of suct tricks, take a look at STLport (www.stlport.org).
> > There, I often had to resolve this problem in same namespace, which even required
> > proxy functions to be deployed.
> >
> >
> > Best regards,
> > -Boris.
> >
> > Paul Moore wrote:
> >
> > > I am still struggling with implementing abs() for rationals.
> > >
> > > To summarise, I have
> > >
> > > template <typename IntType> class rational {
> > > ...
> > > friend rational abs (const rational &);
> > > }
> > >
> > > template <typename IntType>
> > > inline rational<IntType> abs (const rational<IntType> &r)
> > > {
> > > // point (1)
> > > return rational<IntType>(abs(r.num), r.den);
> > > }
> > >
> > > Now, Koenig Lookup should find the friend abs when abs(r) is called with a
> > > rational. But what about the *definition* of abs()? I use abs() here, as using
> > > std::abs precludes IntType being a user-defined type. But to do this, I need to
> > > add "using std::abs;" at point (1).
> > >
> > > Now we have an issue - the using declaration needs to be protected by
> > > BOOST_NO_STDC_NAMESPACE from <boost/config.hpp>.
> > >
> > > But even with this, MSVC *still* has a problem - it fails to look for ::abs
> > > [[ie, std::abs]] when compiling abs(rational). The error is
> > >
> > > ..\..\boost/rational.hpp(248) : error C2784: 'class boost::rational<IntType>
> > > __cdecl boost::abs (const class boost::rational<IntType> &)' : could not deduce
> > > template argument for 'const class boost::rational<IntType> &' from 'const int'
> > > rational_example.cpp(61) : see reference to function template
> > > instantiation 'class boost::rational<int> __cdecl boost::abs(const class
> > > boost::rational<int> &)' being compiled
> > >
> > > which seems to imply that MSVC isn't looking for the "normal" abs(int).
> > >
> > > Can anybody suggest a workaround for this??? I ought to say that MSVC
> > > compatibility is an absolute requirement - I use MSVC, so I'm not going to write
> > > code which doesn't work with it (even allowing for the fact that I'm not sure
> > > exactly what the standard would mandate on this issue!).
> > >
> > > I'm thinking that I might be reduced to replacing abs(n) with (n < 0 ? -n : n).
> > > This is OK, as we are requiring IntType to have "integer-like" semantics, but it
> > > blows any hope of optimisation for a user-defuined IntType right out of the
> > > water. (If someone can offer me a suitable implementation for
> > > standard-conforming compilers, I'd be willing to put the hack in an ifdef
> > > _MSC_VER).
> > >
> > > All assistance gratefully accepted :-) I attach the header and test program.
> > >
> > > Paul
> > >
> > > ------------------------------------------------------------------------
> > > Check out Media Grok and 14 other FREE newsletters from
> > > The Industry Standard. http://clickhere.egroups.com/click/1762
> > >
> > > -- Talk to your group with your own voice!
> > > -- http://www.egroups.com/VoiceChatPage?listName=boost&m=1
> > >
> > > ------------------------------------------------------------------------
> > > Name: rational.hpp
> > > rational.hpp Type: C++ Header File (application/x-unknown-content-type-hppfile)
> > > Encoding: quoted-printable
> > >
> > > Name: rational_example.cpp
> > > rational_example.cpp Type: C++ Source File (application/x-unknown-content-type-cppfile)
> > > Encoding: 7bit
> >
> >
> > ------------------------------------------------------------------------
> > GRAB THE GATOR! FREE SOFTWARE DOES ALL THE TYPING FOR YOU!
> > Gator fills in forms and remembers passwords with NO TYPING at over
> > 100,000 web sites! Get $100 in coupons for trying Gator!
> > http://clickhere.egroups.com/click/2092
> >
> > -- Create a poll/survey for your group!
> > -- http://www.egroups.com/vote?listname=boost&m=1
> >
> >
> >
>
> ------------------------------------------------------------------------
> GET $100 IN COUPONS FOR TRYING GATOR!
> Grab the Gator! Free software does all the typing for you!
> Gator fills in forms and remembers passwords with NO TYPING at over
> 100,000 web sites! http://clickhere.egroups.com/click/2093
>
> -- Check out your group's private Chat room
> -- http://www.egroups.com/ChatPage?listName=boost&m=1


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