type traits update [added is_convertible and alignment_of]

[SVN r7675]
This commit is contained in:
John Maddock
2000-08-02 10:58:59 +00:00
parent fd1ec96f68
commit 8982e52a5f
2 changed files with 181 additions and 3 deletions

View File

@ -10,10 +10,28 @@
// support partial specialisation. (C) John Maddock 2000
/* Release notes:
31st July 2000:
Added is_convertable, alignment_of.
23rd July 2000:
Fixed is_void specialization. (JM)
*/
//
// partial copyright for is_convertible:
//
// Copyright (C) 2000 Jeremy Siek (jsiek@lsc.nd.edu)
// Copyright (C) 1999, 2000 Jaakko J<>rvi (jaakko.jarvi@cs.utu.fi)
//
// Permission to copy and use this software is granted,
// provided this copyright notice appears in all copies.
// Permission to modify the code and to distribute modified code is granted,
// provided this copyright notice appears in all copies, and a notice
// that the code was modified is included with the copyright notice.
//
// This software is provided "as is" without express or implied warranty,
// and with no claim as to its suitability for any purpose.
#ifndef BOOST_OB_TYPE_TRAITS_HPP
#define BOOST_OB_TYPE_TRAITS_HPP
@ -273,6 +291,76 @@ template <typename T> struct is_POD
{ enum{ value = is_scalar<T>::value //JM 7Jan2000
|| BOOST_IS_POD(T) }; };
namespace detail{
// This workaround is necessary to handle when From is void
// which is normally taken care of by the partial specialization
// of the is_convertible class.
#ifdef BOOST_MSVC6_MEMBER_TEMPLATES
struct from_not_void_conversion {
template <class From, class To>
struct bind {
typedef char (&no)[1];
typedef char (&yes)[2];
static no check(...);
static yes check(To);
public:
void foo(); // avoid warning about all members being private
static From from;
enum { exists = sizeof( check(from) ) == sizeof(yes) };
};
};
struct from_is_void_conversion {
template <class From, class To>
struct bind {
enum { exists = is_void<To>::value };
};
};
template <class From>
struct conversion_helper {
typedef from_not_void_conversion type;
};
template <>
struct conversion_helper<void> {
typedef from_is_void_conversion type;
};
#endif
} // namespace detail
template <class From, class To>
class is_convertible
{
#ifdef BOOST_MSVC6_MEMBER_TEMPLATES
typedef typename detail::conversion_helper<From>::type Selector;
typedef Selector::template bind<From,To> Conversion;
public:
enum { value = Conversion::exists };
#else
typedef char (&no)[1];
typedef char (&yes)[2];
static no check(...);
static yes check(To);
public:
void foo(); // avoid warning about all members being private
static From from;
enum { value = sizeof( check(from) ) == sizeof(yes) };
#endif
};
template <class T>
class alignment_of
{
struct padded
{
char c;
T t;
padded();
};
public:
enum{ value = sizeof(padded) - sizeof(T) };
};
//*? is type T an empty composite type (allows cv-qual)
template <typename T> struct is_empty
{ enum{ value = BOOST_IS_EMPTY(T) }; };

View File

@ -5,12 +5,33 @@
// warranty, and with no claim as to its suitability for any purpose.
// See http://www.boost.org for most recent version including documentation.
//
// misc traits classes that operate on or describe a type.
// see libs/utility/type_traits.htm
/* Release notes:
31st July 2000:
Added is_convertable, alignment_of, modified is_empty.
23rd July 2000:
Added Borland specific fixes for reference types (Steve Cleary).
*/
//
// partial copyright for is_convertible:
//
// Copyright (C) 2000 Jeremy Siek (jsiek@lsc.nd.edu)
// Copyright (C) 1999, 2000 Jaakko J<>rvi (jaakko.jarvi@cs.utu.fi)
//
// Permission to copy and use this software is granted,
// provided this copyright notice appears in all copies.
// Permission to modify the code and to distribute modified code is granted,
// provided this copyright notice appears in all copies, and a notice
// that the code was modified is included with the copyright notice.
//
// This software is provided "as is" without express or implied warranty,
// and with no claim as to its suitability for any purpose.
#ifndef BOOST_DETAIL_TYPE_TRAITS_HPP
#define BOOST_DETAIL_TYPE_TRAITS_HPP
@ -419,11 +440,80 @@ public:
template <typename T, std::size_t sz> struct is_POD<T[sz]>
{ static const bool value = is_POD<T>::value; };
//
// is one type convertable to another?
template <class From, class To>
class is_convertible
{
typedef char (&no)[1];
typedef char (&yes)[2];
# if defined(__BORLANDC__) || defined(__GNUC__)
// This workaround for Borland breaks the EDG C++ frontend,
// so we only use it for Borland.
template <class T>
struct checker
{
static no check(...);
static yes check(T);
};
static From from;
public:
static const bool value = sizeof( checker<To>::check(from) ) == sizeof(yes);
# else // not __BORLANDC__
static no check(...);
static yes check(To);
static From from;
public:
static const bool value = sizeof( check(from) ) == sizeof(yes);
# endif
void foo(); // avoid warning about all members being private
};
template <class From>
struct is_convertible<From, void>
{
static const bool value = false;
};
template <class To>
struct is_convertible<void, To>
{
static const bool value = false;
};
template <>
struct is_convertible<void, void>
{
static const bool value = true;
};
//
// get the alignment of some arbitrary type:
template <class T>
class alignment_of
{
struct padded
{
char c;
T t;
padded();
};
public:
static const unsigned value = sizeof(padded) - sizeof(T);
};
//
// references have to be treated specially, assume
// that a reference is just a special pointer:
template <class T>
class alignment_of<T&>
{
public:
static const unsigned value = alignment_of<T*>::value;
};
//
// JM 7Jan2000
//
namespace detail{
template <typename T, bool b>
template <typename T, bool b, bool b2>
struct empty_helper{ static const bool value = false; };
template <typename T>
@ -437,7 +527,7 @@ struct empty_helper_t1 : public T
struct empty_helper_t2 { int i[256]; };
template <typename T>
struct empty_helper<T, true>
struct empty_helper<T, true, false>
{
static const bool value = (sizeof(empty_helper_t1<T>) == sizeof(empty_helper_t2));
};
@ -449,7 +539,7 @@ template <typename T> struct is_empty
private:
typedef typename remove_cv<T>::type cvt;
public:
static const bool value = ::boost::detail::empty_helper<T, is_class<T>::value>::value
static const bool value = ::boost::detail::empty_helper<T, is_class<T>::value , is_convertible<T,int>::value>::value
|| BOOST_IS_EMPTY(cvt);
};