RE: [boost] type_traits: workaround bias
by Yitzhak Sapir other posts by this author
Mar 17 2002 12:22PM messages near this date
Threads: New version of rw_lock uploaded to files section
|
Re: [boost] Re: Design for a file system library
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 =3D
false}; };
};
template <> struct is_pointer_class_helper<true>
{
template <class T> struct non_specialized { enum { value =3D
boost::is_pointer<T> ::value }; };
};
template <typename T>
struct is_pointer
{
enum { temp_value =3D (sizeof(yes_type) =3D=3D=20
sizeof
(is_pointer_helper1(*is_pointer_helper2(type_wrapper<T> ())))) };
enum { value =3D
is_pointer_class_helper<temp_value> ::non_specialized<T>::value };
};
struct X; // incomplete class
struct Y { virtual void y() =3D 0; virtual ~Y() =3D 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@[...].. ]
> Sent: Wednesday, March 13, 2002 5:33 PM
> To: boost@[...].com
> Subject: [boost] type_traits: workaround bias
> =20
> =20
> 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:
> =20
> ----------
> 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(...);
> =20
> =20
> template <typename T>
> struct is_pointer
> {
> private:
> static T t;
> public:
> BOOST_STATIC_CONSTANT(bool, value =3D
> (::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 =3D=3D sizeof(detail::is_pointer_helper(t))),
> (1 =3D=3D sizeof(detail::is_function_tester(t)))
> >::value)
> >::value ) );
> };
> template <>
> struct is_pointer <void>
> {
> BOOST_STATIC_CONSTANT(bool, value =3D false);
> };
> -----------
> =20
> The above is our current implementation, which cannot be instantiated
> when T is a class with an unimplemented pure virtual function.
> =20
> Now let's examine an alternative implementation, which doesn't support
> array types, but supports abstract classes:
> =20
> ---------
> 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 =3D
> (::boost::type_traits::ice_or<
> (1 =3D=3D
> sizeof(detail::is_pointer_helper((T(*)())0))),
> (1 =3D=3D sizeof(detail::is_function_tester(t)))
> >::value)
> >::value ) );
> };
> ----------
> =20
> 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,=20
> with function
> arguments and return values, it seems to me that abstract classes are
> going to arise far more often than arrays.
> =20
> 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=20
> me that it
> work for array types.
> =20
> Thoughts?
> Dave
> =20
> +---------------------------------------------------------------+
> David Abrahams
> C++ Booster ( http://www.boost.org ) O__ =3D=3D
> Pythonista ( http://www.python.org ) c/ /'_ =3D=3D
> resume: http://users.rcn.com/abrahams/resume.html (*) \(*) =3D=3D
> email: david.abrahams@[...]..
> +---------------------------------------------------------------+
> =20
> =20
> Info: http://www.boost.org Send unsubscribe requests to:=20
> <mailto: boost-unsubscribe@[...].com>=20
> =20
> Your use of Yahoo! Groups is subject to=20
> http://docs.yahoo.com/info/terms/=20
> =20
> =20
|