Boost logo

Boost :

From: David Abrahams (david.abrahams_at_[hidden])
Date: 2002-02-02 18:35:28


Fixed is_reference<T const volatile>::value for compilers without partial
specialization.

;-)

This patch uses the fact that the compiler can detect references via
overloading by passing a function pointer to the "sizeof trick":

  no_type non_array_is_reference_helper(...);
  template <typename T>
  yes_type non_array_is_reference_helper(T&(*)());

The only complication is that the compiler barks at T(*)() when T is an
array type, so I used is_array<> to distinguish that before applying this
trick. Since is_array<> relied on is_reference<>, but it seemed to work, I
left it relying on the old definition of is_reference which I renamed more
accurately to is_reference_or_const_volatile. This makes detecting
references quite complex. I'm not really sure if a simpler template can be
substituted for is_reference_or_const_volatile in is_array or not, since I
don't really know what it's doing.

-Dave

---------

Index: composite_traits.hpp
===================================================================
RCS file: /cvsroot/boost/boost/boost/type_traits/composite_traits.hpp,v
retrieving revision 1.14
retrieving revision 1.15
diff -d -u -r1.14 -r1.15
--- composite_traits.hpp 2002/01/31 05:08:35 1.14
+++ composite_traits.hpp 2002/02/02 23:23:42 1.15
@@ -65,6 +65,10 @@
 { BOOST_STATIC_CONSTANT(bool, value = true); };
 #else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
 namespace detail{
+
+ template <typename T>
+ struct is_reference_or_const_volatile;
+
    struct pointer_helper
    {
       pointer_helper(const volatile void*);
@@ -152,7 +156,7 @@
       (::boost::type_traits::ice_and<
          (1 == sizeof(detail::is_array_helper(&t, t))),
          ::boost::type_traits::ice_not<
- ::boost::is_reference<T>::value>::value,
+
::boost::detail::is_reference_or_const_volatile<T>::value>::value,
          ::boost::type_traits::ice_not<
             (1 == sizeof(detail::is_function_tester(t)))>::value
>::value));
@@ -274,20 +278,63 @@
 # pragma warning(push)
 # pragma warning(disable: 4181)
 #endif // BOOST_MSVC
-template <typename T> struct is_reference
-{
-private:
- typedef T const volatile cv_t;
-public:
- BOOST_STATIC_CONSTANT(bool, value =
- (::boost::type_traits::ice_or<
- ::boost::type_traits::ice_not<
- ::boost::is_const<cv_t>::value
- >::value,
- ::boost::type_traits::ice_not<
- ::boost::is_volatile<cv_t>::value>::value
- >::value));
+
+
+namespace detail
+{
+ template <typename T> struct is_reference_or_const_volatile
+ {
+ private:
+ typedef T const volatile cv_t;
+ public:
+ BOOST_STATIC_CONSTANT(bool, value =
+ (::boost::type_traits::ice_or<
+ ::boost::type_traits::ice_not<
+ ::boost::is_const<cv_t>::value
+ >::value,
+ ::boost::type_traits::ice_not<
+ ::boost::is_volatile<cv_t>::value>::value
+ >::value));
+ };
+
+ no_type non_array_is_reference_helper(...);
+ template <typename T>
+ yes_type non_array_is_reference_helper(T&(*)());
+
+ template <bool isarray_>
+ struct is_reference_helper
+ {
+ template <class T>
+ struct apply
+ {
+ typedef T (*pf_t)();
+ static pf_t pf;
+
+ BOOST_STATIC_CONSTANT(
+ bool, value = (1 == sizeof(::boost::detail::non_array_is_reference_helper(pf))));
+ };
+ };
+
+ template <>
+ struct is_reference_helper<true>
+ {
+ template <class T>
+ struct apply
+ {
+ BOOST_STATIC_CONSTANT(bool, value = false);
+ };
+ };
+}
+
+template <typename T>
+struct is_reference
+{
+ BOOST_STATIC_CONSTANT(
+ bool, value = ::boost::detail::is_reference_helper<
+ is_array<T>::value
+ >::template apply<T>::value);
 };
+
 template <> struct is_reference<void>
 {
    BO
OST_STATIC_CONSTANT(bool, value = false);

===================================================
  David Abrahams, C++ library designer for hire
 resume: http://users.rcn.com/abrahams/resume.html

        C++ Booster (http://www.boost.org)
          email: david.abrahams_at_[hidden]
===================================================


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