Modified call_traits to work with incomplete types.

[SVN r12800]
This commit is contained in:
John Maddock 2002-02-14 12:54:57 +00:00
parent 4b636a7680
commit 1f29191329
2 changed files with 69 additions and 12 deletions

View File

@ -34,20 +34,32 @@ namespace boost{
namespace detail{ namespace detail{
template <typename T, bool isp, bool b1, bool b2> template <typename T, bool small>
struct ct_imp2
{
typedef const T& param_type;
};
template <typename T>
struct ct_imp2<T, true>
{
typedef const T param_type;
};
template <typename T, bool isp, bool b1>
struct ct_imp struct ct_imp
{ {
typedef const T& param_type; typedef const T& param_type;
}; };
template <typename T, bool isp> template <typename T, bool isp>
struct ct_imp<T, isp, true, true> struct ct_imp<T, isp, true>
{ {
typedef T const param_type; typedef typename ct_imp2<T, sizeof(T) <= sizeof(void*)>::param_type param_type;
}; };
template <typename T, bool b1, bool b2> template <typename T, bool b1>
struct ct_imp<T, true, b1, b2> struct ct_imp<T, true, b1>
{ {
typedef T const param_type; typedef T const param_type;
}; };
@ -67,7 +79,11 @@ public:
// however compiler bugs prevent this - instead pass three bool's to // however compiler bugs prevent this - instead pass three bool's to
// ct_imp<T,bool,bool,bool> and add an extra partial specialisation // ct_imp<T,bool,bool,bool> and add an extra partial specialisation
// of ct_imp to handle the logic. (JM) // of ct_imp to handle the logic. (JM)
typedef typename detail::ct_imp<T, ::boost::is_pointer<typename remove_const<T>::type>::value, ::boost::is_arithmetic<typename remove_const<T>::type>::value, sizeof(T) <= sizeof(void*)>::param_type param_type; typedef typename detail::ct_imp<
T,
::boost::is_pointer<T>::value,
::boost::is_arithmetic<T>::value
>::param_type param_type;
}; };
template <typename T> template <typename T>

View File

@ -64,7 +64,8 @@ struct reference_call_traits
typedef T const_reference; typedef T const_reference;
typedef T param_type; typedef T param_type;
}; };
template <bool simple, bool reference>
template <bool pointer, bool arithmetic, bool reference>
struct call_traits_chooser struct call_traits_chooser
{ {
template <class T> template <class T>
@ -73,8 +74,9 @@ struct call_traits_chooser
typedef standard_call_traits<T> type; typedef standard_call_traits<T> type;
}; };
}; };
template <> template <>
struct call_traits_chooser<true, false> struct call_traits_chooser<true, false, false>
{ {
template <class T> template <class T>
struct rebind struct rebind
@ -82,8 +84,9 @@ struct call_traits_chooser<true, false>
typedef simple_call_traits<T> type; typedef simple_call_traits<T> type;
}; };
}; };
template <> template <>
struct call_traits_chooser<false, true> struct call_traits_chooser<false, false, true>
{ {
template <class T> template <class T>
struct rebind struct rebind
@ -91,14 +94,52 @@ struct call_traits_chooser<false, true>
typedef reference_call_traits<T> type; typedef reference_call_traits<T> type;
}; };
}; };
template <bool size_is_small>
struct call_traits_sizeof_chooser2
{
template <class T>
struct small_rebind
{
typedef simple_call_traits<T> small_type;
};
};
template<>
struct call_traits_sizeof_chooser2<false>
{
template <class T>
struct small_rebind
{
typedef standard_call_traits<T> small_type;
};
};
template <>
struct call_traits_chooser<false, true, false>
{
template <class T>
struct rebind
{
enum { sizeof_choice = (sizeof(T) <= sizeof(void*)) };
typedef call_traits_sizeof_chooser2<(sizeof(T) <= sizeof(void*))> chooser;
typedef typename chooser::template small_rebind<T> bound_type;
typedef typename bound_type::small_type type;
};
};
} // namespace detail } // namespace detail
template <typename T> template <typename T>
struct call_traits struct call_traits
{ {
private: private:
typedef detail::call_traits_chooser<(is_pointer<T>::value || is_arithmetic<T>::value) && sizeof(T) <= sizeof(void*), is_reference<T>::value> chooser; typedef detail::call_traits_chooser<
typedef typename chooser::template rebind<T> bound_type; ::boost::is_pointer<T>::value,
typedef typename bound_type::type call_traits_type; ::boost::is_arithmetic<T>::value,
::boost::is_reference<T>::value
> chooser;
typedef typename chooser::template rebind<T> bound_type;
typedef typename bound_type::type call_traits_type;
public: public:
typedef typename call_traits_type::value_type value_type; typedef typename call_traits_type::value_type value_type;
typedef typename call_traits_type::reference reference; typedef typename call_traits_type::reference reference;