|
Boost : |
From: David Abrahams (david.abrahams_at_[hidden])
Date: 2002-03-17 13:26:35
The problems have already been solved in CVS. However, it's not clear
that the solutions don't exploit bugs in the MSVC compilers. You might
try substituting your approach to see if any of the regression tests
fail. If not, a patch from you would probably be appreciated.
-Dave
----- Original Message -----
From: "Yitzhak Sapir" <ysapir_at_[hidden]>
To: <boost_at_[hidden]>
Sent: Sunday, March 17, 2002 7:22 AM
Subject: RE: [boost] type_traits: workaround bias
> I tried experimenting with this a bit. I think now that essentially
> this is the result of the "reference/pointer to reference" problem.
If
> you had a solution to that, you could declare all the static T's as T&
> and solve the issue.
>
> I have the following code which prints 1 four times and then 0 five
> times on MSVC6SP5. Does this solve all potential issues. Am I
missing
> anything here?
>
> using namespace boost;
> using namespace boost::type_traits;
>
> template <class T> struct type_wrapper{ };
>
> template<class T1> yes_type is_pointer_helper1(T1*);
> no_type is_pointer_helper1(...);
> template <class T> T* is_pointer_helper2(type_wrapper<T>);
>
> template <bool IsPointerOrReference> struct is_pointer_class_helper;
> template <> struct is_pointer_class_helper<false>
> {
> template <class T> struct non_specialized { enum { value =
> false}; };
> };
>
> template <> struct is_pointer_class_helper<true>
> {
> template <class T> struct non_specialized { enum { value =
> boost::is_pointer<T>::value }; };
> };
>
> template <typename T>
> struct is_pointer
> {
> enum { temp_value = (sizeof(yes_type) ==
> sizeof
> (is_pointer_helper1(*is_pointer_helper2(type_wrapper<T>())))) };
> enum { value =
> is_pointer_class_helper<temp_value>::non_specialized<T>::value };
> };
>
> struct X; // incomplete class
> struct Y { virtual void y() = 0; virtual ~Y() = 0 {}; }; // abstract
> class
> struct Z {}; // regular class
> typedef Z W[3]; // array type
> typedef Z& V; // reference
>
> int main()
> {
> std::cout << is_pointer<W*>::value << std::endl;
> std::cout << is_pointer<X*>::value << std::endl;
> std::cout << is_pointer<Y*>::value << std::endl;;
> std::cout << is_pointer<Z*>::value << std::endl;
> std::cout << is_pointer<V>::value << std::endl;
> std::cout << is_pointer<W>::value << std::endl;
> std::cout << is_pointer<X>::value << std::endl;
> std::cout << is_pointer<Y>::value << std::endl;;
> std::cout << is_pointer<Z>::value << std::endl;
> return 0;
> }
>
> > -----Original Message-----
> > From: David Abrahams [mailto:david.abrahams_at_[hidden]]
> > Sent: Wednesday, March 13, 2002 5:33 PM
> > To: boost_at_[hidden]
> > Subject: [boost] type_traits: workaround bias
> >
> >
> > It seems that the known technologies for writing type traits for
> > compilers without partial specialization nearly always force us to
> > choose between supporting array types and supporting abstract
classes.
> > Let's just look at is_pointer, for an example:
> >
> > ----------
> > struct pointer_helper
> > {
> > pointer_helper(const volatile void*);
> > };
> > yes_type BOOST_TT_DECL is_pointer_helper(pointer_helper);
> > no_type BOOST_TT_DECL is_pointer_helper(...);
> >
> >
> > template <typename T>
> > struct is_pointer
> > {
> > private:
> > static T t;
> > public:
> > BOOST_STATIC_CONSTANT(bool, value =
> > (::boost::type_traits::ice_and<
> > ::boost::type_traits::ice_not<
> > ::boost::is_reference<T>::value
> > >::value,
> > ::boost::type_traits::ice_not<
> > ::boost::is_array<T>::value
> > >::value,
> > (::boost::type_traits::ice_or<
> > (1 == sizeof(detail::is_pointer_helper(t))),
> > (1 == sizeof(detail::is_function_tester(t)))
> > >::value)
> > >::value ) );
> > };
> > template <>
> > struct is_pointer <void>
> > {
> > BOOST_STATIC_CONSTANT(bool, value = false);
> > };
> > -----------
> >
> > The above is our current implementation, which cannot be
instantiated
> > when T is a class with an unimplemented pure virtual function.
> >
> > Now let's examine an alternative implementation, which doesn't
support
> > array types, but supports abstract classes:
> >
> > ---------
> > template <class T>
> > yes_type BOOST_TT_DECL is_pointer_helper(T*(*)());
> > no_type BOOST_TT_DECL is_pointer_helper(...);
> > template <typename T>
> > struct is_pointer
> > {
> > public:
> > BOOST_STATIC_CONSTANT(bool, value =
> > (::boost::type_traits::ice_or<
> > (1 ==
> > sizeof(detail::is_pointer_helper((T(*)())0))),
> > (1 == sizeof(detail::is_function_tester(t)))
> > >::value)
> > >::value ) );
> > };
> > ----------
> >
> > Leaving aside from the technical argument that the 2nd version is
much
> > simpler, I wonder if we have made the right choice in our support
for
> > array types over abstract classes. In the work I'm doing,
> > with function
> > arguments and return values, it seems to me that abstract classes
are
> > going to arise far more often than arrays.
> >
> > In particular, it would be very useful to me if I could instantiate
> > is_class<T> for abstract classes. It's much less important to
> > me that it
> > work for array types.
> >
> > Thoughts?
> > Dave
> >
> > +---------------------------------------------------------------+
> > David Abrahams
> > C++ Booster (http://www.boost.org) O__ ==
> > Pythonista (http://www.python.org) c/ /'_ ==
> > resume: http://users.rcn.com/abrahams/resume.html (*) \(*) ==
> > email: david.abrahams_at_[hidden]
> > +---------------------------------------------------------------+
> >
> >
> > Info: http://www.boost.org Send unsubscribe requests to:
> > <mailto:boost-unsubscribe_at_[hidden]>
> >
> > Your use of Yahoo! Groups is subject to
> > http://docs.yahoo.com/info/terms/
> >
> >
>
> Info: http://www.boost.org Send unsubscribe requests to:
<mailto:boost-unsubscribe_at_[hidden]>
>
> Your use of Yahoo! Groups is subject to
http://docs.yahoo.com/info/terms/
>
>
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk