Boost logo

Boost :

From: Yitzhak Sapir (ysapir_at_[hidden])
Date: 2002-03-17 07:22:19


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/
>
>


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