|
Boost : |
From: JOAQUIN LOPEZ MU?Z (joaquin_at_[hidden])
Date: 2003-09-09 07:45:31
This crucial point of this technique is having an utility
to determine member function existence at compile-time.
A quick google on the Usenet reveals similar snippets
of code to do this, all of them more or less related and
with various degrees of success across a wide span of
compilers. Maybe some bold booster can have them refactored
in a metaprogramming utility with as many compilers supported
as possible. I see applications of this outside the swap problem.
Just my 2c
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
----- Mensaje Original -----
De: John Maddock <john_at_[hidden]>
Fecha: Martes, Septiembre 9, 2003 1:54 pm
Asunto: [boost] Fw: An omnipotant swap?
> It seems to me that this may be of interest here as well:
>
> > To: C++ libraries mailing list
> > Message c++std-lib-11916
> >
> > Unless I've missed it, we seem to be no further forward in
> solving the
> "swap
> > problem" - namely is it permitted to provide user defined
> overloads of
> > std::swap in namespace std?
> >
> > I don't want to rehearse the old arguments again here, but
> instead ask a
> > different question: what would happen if std::swap were
> omnipotent and
> just
> > simply "knows" whether a type has a member function swap or not.
> std::swap
> > could now be implemented to call the member swap if it were
> available,> otherwise to fall back on the slow but safe copy based
> swap.>
> > The interesting thing is, this is actually implementable right
> now within
> > the current language - I've attached a sample implementation to
> the end of
> > this message, hopefully it really is legal code, although I
> admit that
> only
> > one of the three compilers I've tried (VC7.1) would compile it....
> >
> > Anyway, maybe some food for thought,
> >
> > regards,
> >
> > John Maddock
> >
> > Code follows:
> >
> > #include <list>
> >
> > namespace omni{
> >
> > template <class T, T val>
> > struct member_wrapper{};
> >
> > template <class T>
> > char test_for_swap(const T&, member_wrapper<void (T::*)(T&),
> &T::swap>* p
> =
> > 0);
> >
> > template <class T>
> > double test_for_swap(const T&, ...);
> >
> > template <class T>
> > struct has_member_swap
> > {
> > static T t;
> > static const bool value =
> > (1 == sizeof(test_for_swap(t)));
> > };
> >
> > //BOOST_STATIC_ASSERT(has_member_swap<std::list<int> >::value);
> > //BOOST_STATIC_ASSERT(!has_member_swap<int>::value);
> > //BOOST_STATIC_ASSERT(!has_member_swap<noswap>::value);
> >
> > template<bool b>
> > struct swapper
> > {
> > template <class T>
> > static void swap(T& t1, T& t2)
> > { std::swap(t1, t2); }
> > };
> >
> > template<>
> > struct swapper<true>
> > {
> > template <class T>
> > static void swap(T& t1, T& t2)
> > { t1.swap(t2); }
> > };
> >
> > template <class T>
> > void swap(T& t1, T& t2)
> > {
> > swapper<has_member_swap<T>::value>::swap(t1, t2);
> > }
> >
> > } // namespace omni
> >
> > struct noswap{};
> >
> > int main()
> > {
> > std::list<int> l1, l2;
> > omni::swap(l1, l2);
> > noswap s1, s2;
> > omni::swap(s1, s2);
> > int i1, i2;
> > omni::swap(i1, i2);
> > return 0;
> > }
> >
> >
> >
>
>
> _______________________________________________
> Unsubscribe & other changes:
> http://lists.boost.org/mailman/listinfo.cgi/boost
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk