From d23af42bc3a62bd3561a8985630ad63b8a7478d0 Mon Sep 17 00:00:00 2001 From: John Maddock Date: Thu, 31 Oct 2002 12:35:28 +0000 Subject: [PATCH] Updated is_convertible tests. Updated docs to reflec most of the recent changes. [SVN r16032] --- index.htm | 2122 ++++++++++++++-------------------- test/is_convertible_test.cpp | 1 - 2 files changed, 867 insertions(+), 1256 deletions(-) diff --git a/index.htm b/index.htm index 36e5f9a..b4eeb00 100644 --- a/index.htm +++ b/index.htm @@ -1,1215 +1,850 @@ - - - - - -Type Traits - - - - -

Header -<boost/type_traits.hpp>

- -

The contents of <boost/type_traits.hpp> are declared in -namespace boost.

- -

The file <boost/type_traits.hpp> -contains various template classes that describe the fundamental -properties of a type; each class represents a single type -property or a single type transformation. If you are new to this -library then read the accompanying article -first.

- -

This documentation is divided up into the following sections:

- -
Primary Type Categorisation
+   
+      Type Traits
+      
+      
+      
+   
+   
+      

Header <boost/type_traits.hpp>

+

Contents

+
Introduction
+Primary Type Categorisation
 Secondary Type Categorisation
 Type Properties
 Relationships Between Types
 Transformations Between Types
 Synthesizing Types
 Function Traits
-Compiler Support Information
 Type traits headers
 Example Code
- -

All of the integral expressions in this library are integral constant -expressions, these can sometimes cause compiler problems -in use, so there is a related set of coding guidelines -to help you write portable code using this library.

- -

Primary Type Categorisation

- -

The following type traits templates identify which type -category the type belongs to. For any given type, exactly one of -the following expressions will evaluate to true. Note that this -means that is_integral<T>::value and is_float<T>::value -will only every be true for built-in types; if you want to check -for a user-defined type that may behave "as if" it is -an integral or floating point type, then use the std::numeric_limits -template instead.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 

Expression

-

Description

-

Reference

-

Compiler requirements

-
 
 ::boost::is_void<T>::valueEvaluates - to true only if T is a cv-qualified void type.

3.9.1p9

-
  
 ::boost::is_integral<T>::valueEvaluates - to true only if T is an cv-qualified integral type.

3.9.1p7

-
  
 ::boost::is_float<T>::valueEvaluates - to true only if T is a cv-qualified floating point type.

3.9.1p8

-
  
 ::boost::is_pointer<T>::valueEvaluates - to true only if T is cv-qualified pointer type (includes - function pointers, but excludes pointers to members).

3.9.2p2

-

8.3.1

-
  
 ::boost::is_reference<T>::valueEvaluates - to true only if T is a reference type.

3.9.2

-

8.3.2

-
  
 ::boost::is_member_pointer<T>::valueEvaluates - to true only if T is a cv-qualified pointer to a data-member - or member-function.

3.9.2

-

8.3.3

-
  
 ::boost::is_array<T>::valueEvaluates - to true only if T is an array type.

3.9.2

-

8.3.4

-
If the - compiler does not support partial-specialization of class - templates, then some types may be incorrectly identified - as arrays (mainly function types). 
 ::boost::is_union<T>::valueEvaluates - to true only if T is of union type. Currently requires - some kind of compiler support, otherwise unions are - identified as classes.

3.9.2

-

9.5

-
C 
 ::boost::is_class<T>::valueEvaluates - to true only if T is of class/struct type.

3.9.2

-

9.2

-
C 
 ::boost::is_enum<T>::valueEvaluates - to true only if T is of enum type.

3.9.2

-

7.2

-
Requires a - correctly functioning is_convertible template (this means - that is_enum is currently broken under Borland C++). 
 ::boost::is_function<T>::valueEvaluates to true only - if T is a function type (note not a reference or pointer - to function).

3.9.2p1

-

8.3.5

-
Without partial - specialisation support, this template does not compile - for reference types. 
- -

 

- -

Secondary Type Categorisation

- -

The following type categories are made up of the union of one -or more primary type categorisations. A type may belong to more -than one of these categories, in addition to one of the primary -categories.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 

Expression

-

Description

-

Reference

-

Compiler requirements

-
 
 ::boost::is_arithmetic<T>::valueEvaluates - to true only if T is a cv-qualified arithmetic type. That - is either an integral or floating point type.

3.9.1p8

-
  
 ::boost::is_fundamental<T>::valueEvaluates - to true only if T is an cv-qualified fundamental type. - That is either an integral, a floating point, or a void - type.

3.9.1

-
  
 ::boost::is_object<T>::valueEvaluates - to true only if T is a cv-qualified object type. That is - not a function, reference, or void type.

3.9p9

-
  
 ::boost::is_scalar<T>::valueEvaluates - to true only if T is cv-qualified scalar type. That is an - arithmetic, a pointer or a pointer to member type.

3.9p10

-
  
 ::boost::is_compound<T>::valueEvaluates - to true only if T is a compound type. That is an array, - function, pointer, reference, enumerator, union, class or - member function type.

3.9.2

-
  
 ::boost::is_member_function_pointer<T>::valueEvaluates to true only if T is a - pointer to a member function (and not a pointer to a - member object). This template splits is_member_pointer - into two sub-categories.

3.9.2

-

8.3.3

-
  
- -

 

- -

Type Properties

- -

The following templates identify the properties that a type -has.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 

Expression

-

Description

-

Reference

-

Compiler requirements

-
 
 ::boost::alignment_of<T>::valueIdentifies - the alignment requirements of T. Actually returns a value - that is only guaranteed to be a multiple of the actual - alignment requirements of T   
 ::boost::is_empty<T>::valueTrue if T - is an empty struct or class. If the compiler implements - the "zero sized empty base classes" - optimisation, then is_empty will correctly guess whether - T is empty. Relies upon is_class to determine whether T - is a class type.

10p5

-

PCD

-
 
 ::boost::is_const<T>::valueEvaluates - to true only if T is top-level const-qualified.

3.9.3

-
  
 ::boost::is_volatile<T>::valueEvaluates - to true only if T is volatile-qualified.

3.9.3

-
  
 ::boost::is_POD<T>::valueEvaluates - to true only if T is a cv-qualified POD type.

3.9p10

-

9p4

-
  
 ::boost::has_trivial_constructor<T>::valueTrue if T - has a trivial default constructor - that is T() is - equivalent to memset. 

PC

-
 
 ::boost::has_trivial_copy<T>::valueTrue if T - has a trivial copy constructor - that is T(const T&) - is equivalent to memcpy. 

PC

-
 
 ::boost::has_trivial_assign<T>::valueTrue if T - has a trivial assignment operator - that is if T::operator=(const - T&) is equivalent to memcpy. 

PC

-
 
 ::boost::has_trivial_destructor<T>::valueTrue if T - has a trivial destructor - that is if T::~T() has no - effect. 

PC

-
 
 ::boost::is_stateless<T>::valueTrue if T - is stateless, meaning that T has no storage and its - constructors and destructors are trivial. 

PC

-
 
 ::boost::has_nothrow_constructor<T>::valueTrue if T has a non-throwing - default constructor. PC 
 ::boost::has_nothrow_copy<T>::valueTrue if T has a non-throwing copy - constructor. PC 
 ::boost::has_nothrow_assign<T>::valueTrue if T has a non-throwing - assignment operator. PC 
- -

 

- -

Relationships Between Types

- -

The following templates determine the whether there is a -relationship between two types:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 

Expression

-

Description

-

Reference

-

Compiler requirements

-
 
 
::boost::is_same<T,U>::value
-

Evaluates to true if T and U are the same - type.

-
   
 ::boost::is_convertible<T,U>::valueEvaluates - to true if type T is convertible to type U.

4

-

8.5

-
Note that - this template is currently broken with Borland's - compiler, for constructor-based conversions, and for the - Metrowerks compiler in all cases. 
 ::boost::is_base_and_derived<T,U>::valueEvaluates to true if type T is a - base class to type U.10P 
- -

Note that both is_convertible, and is_base_and_derived -can produce compiler errors if the convertion is ambiguous:

- -
struct A {};
+      

Introduction

+

The contents of <boost/type_traits.hpp> are declared in namespace boost.

+

The file <boost/type_traits.hpp> + defines three kinds of type trait:

+
    +
  1. + The properties of a specific type. +
  2. + The relationship between two types. +
  3. + A transformation from one type to another.
  4. +
+

If you are new to this library then the accompanying + article provides a the background information and motivation.

+

All of the integral expressions in this library are + integral constant expressions, these can sometimes cause + compiler problems in use, so there is a related set of + coding guidelines to help you write portable code using this library.

+

Primary Type Categorisation

+

The following type traits templates identify which type category the type + belongs to. For any given type, exactly one of the following expressions will + evaluate to true. Note that this means that is_integral<T>::value + and is_float<T>::value will only every be true for built-in + types; if you want to check for a user-defined type that may behave "as if" it + is an integral or floating point type, then use the std::numeric_limits + template instead.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 

Expression

+

Description

+

Reference

+

Compiler + requirements

+
 
 ::boost::is_void<T>::valueEvaluates to true only if T is a + cv-qualified void type.

3.9.1p9

+
  
 ::boost::is_integral<T>::valueEvaluates to true only if T is an + cv-qualified integral type.

3.9.1p7

+
  
 ::boost::is_float<T>::valueEvaluates to true only if T is a + cv-qualified floating point type.

3.9.1p8

+
  
 ::boost::is_pointer<T>::valueEvaluates to true only if T is + cv-qualified pointer type (includes function pointers, but excludes pointers to + members).

3.9.2p2

+

8.3.1

+
  
 ::boost::is_reference<T>::valueEvaluates to true only if T is a + reference type.

3.9.2

+

8.3.2

+
If the compiler does not support + partial-specialization of class templates, then this template may report the + wrong result for function types. 
 ::boost::is_member_pointer<T>::valueEvaluates to true only if T is a + cv-qualified pointer to a data-member or member-function.

3.9.2

+

8.3.3

+
  
 ::boost::is_array<T>::valueEvaluates to true only if T is an + array type.

3.9.2

+

8.3.4

+
If the compiler does not support + partial-specialization of class templates, then this template can give the + wrong result with function types. 
 ::boost::is_union<T>::valueEvaluates to true only if T is of + union type. Currently requires some kind of compiler support, otherwise unions + are identified as classes.

3.9.2

+

9.5

+
Without (some as yet unspecified) + help from the compiler, we cannot distinguish between union and class types, as + a result this expression will never evaluate to true. 
 ::boost::is_class<T>::valueEvaluates to true only if T is of + class/struct type.

3.9.2

+

9.2

+
Without (some as yet unspecified) + help from the compiler, we cannot distinguish between union and class types, as + a result this expression will eroneously evaluate to true for union types. 
 ::boost::is_enum<T>::valueEvaluates to true only if T is of + enum type.

3.9.2

+

7.2

+
Requires a correctly functioning + is_convertible template (this means that is_enum is currently broken under + Borland C++ Builder 5, and some for some versions of the Metrowerks compiler). 
 ::boost::is_function<T>::valueEvaluates to true only if T is a function type + (note not a reference or pointer to function).

3.9.2p1

+

8.3.5

+
If the compiler does not support + partial-specialization of class templates, then this template does not compile + for reference types. 
+

 

+

Secondary Type Categorisation

+

The following type categories are made up of the union of one or more primary + type categorisations. A type may belong to more than one of these categories, + in addition to one of the primary categories.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 

Expression

+

Description

+

Reference

+

Compiler + requirements

+
 
 ::boost::is_arithmetic<T>::valueEvaluates to true only if T is a + cv-qualified arithmetic type. That is either an integral or floating point + type.

3.9.1p8

+
  
 ::boost::is_fundamental<T>::valueEvaluates to true only if T is an + cv-qualified fundamental type. That is either an integral, a floating point, or + a void type.

3.9.1

+
  
 ::boost::is_object<T>::valueEvaluates to true only if T is a + cv-qualified object type. That is not a function, reference, or void type.

3.9p9

+
  
 ::boost::is_scalar<T>::valueEvaluates to true only if T is + cv-qualified scalar type. That is an arithmetic, a pointer or a pointer to + member type.

3.9p10

+
If the compiler does not support + partial-specialization of class templates, then this template can not be used + with function types. 
 ::boost::is_compound<T>::valueEvaluates to true only if T is a + compound type. That is an array, function, pointer, reference, enumerator, + union, class or member function type.

3.9.2

+
If the compiler does not support + partial-specialization of class templates, then this template can not be used + with function types. 
 ::boost::is_member_function_pointer<T>::valueEvaluates to true only if T is a pointer to a member + function (and not a pointer to a member object). This template splits + is_member_pointer into two sub-categories.

3.9.2

+

8.3.3

+
  
+

 

+

Type Properties

+

The following templates identify the properties that a type has.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 

Expression

+

Description

+

Reference

+

Compiler + requirements

+
 
 ::boost::alignment_of<T>::valueIdentifies the alignment + requirements of T. Actually returns a value that is only guaranteed to be a + multiple of the actual alignment requirements of T   
 ::boost::is_empty<T>::valueTrue if T is an empty struct or + class. If the compiler implements the "zero sized empty base classes" + optimisation, then is_empty will correctly guess whether T is empty. Relies + upon is_class to determine whether T is a class type. +

10p5

+

Relies on the compiler + implementing zero sized empty base classes in order to detect empty classes. +

+

Can not be used with incomplete types.

+

Can not be used with union types, until is_union can be made to + work.

+

If the compiler does not support partial-specialization of class + templates, then this template can not be used with abstract types.

+
 
 ::boost::is_const<T>::valueEvaluates to true only if T is + top-level const-qualified.

3.9.3

+
  
 ::boost::is_volatile<T>::valueEvaluates to true only if T is + volatile-qualified.

3.9.3

+
  
 ::boost::is_POD<T>::valueEvaluates to true only if T is a + cv-qualified POD type.

3.9p10

+

9p4

+
Without some (as yet unspecified) + help from the compiler, is_POD will never report that a class or struct is a + POD; this is always safe, if possibly sub-optimal.

If the compiler does not + support partial-specialization of class templates, then this template can not + be used with function types.

+
 
 ::boost::has_trivial_constructor<T>::valueTrue if T has a trivial default + constructor.12.1p5

Without some (as yet + unspecified) help from the compiler, has_trivial_constructor will + never report that a class or struct has a trivial constructor; this is always + safe, if possibly sub-optimal.

+

If the compiler does not support partial-specialization of class templates, + then this template can not be used with function types.

+
 
 ::boost::has_trivial_copy<T>::valueTrue if T has a trivial copy + constructor.12.8p6

Without some (as yet + unspecified) help from the compiler, has_trivial_copy will never + report that a class or struct has a trivial copy constructor; this is always + safe, if possibly sub-optimal.

+

If the compiler does not support partial-specialization of class templates, + then this template can not be used with function types.

+
 
 ::boost::has_trivial_assign<T>::valueTrue if T has a trivial assignment + operator.12.8p11

Without some (as yet + unspecified) help from the compiler, has_trivial_assign will never + report that a class or struct has a trivial assignment operator; this is always + safe, if possibly sub-optimal.

+

If the compiler does not support partial-specialization of class templates, + then this template can not be used with function types.

+
 
 ::boost::has_trivial_destructor<T>::valueTrue if T has a trivial destructor.12.4p3

Without some (as yet + unspecified) help from the compiler, has_trivial_destructor will + never report that a class or struct has a trivial destructor; this is always + safe, if possibly sub-optimal.

+

If the compiler does not support partial-specialization of class templates, + then this template can not be used with function types.

+
 
 ::boost::is_stateless<T>::valueTrue if T is stateless, meaning + that T has no storage and its constructors and destructors are trivial. 

Without some (as yet + unspecified) help from the compiler, is_stateless will never + report that a class or struct is_stateless; this is always safe, if possibly + sub-optimal.

+

Will report true only if all of the following also report true:

+
::boost::has_trivial_constructor<T>::value,
+::boost::has_trivial_copy<T>::value,
+::boost::has_trivial_destructor<T>::value,
+::boost::is_class<T>::value,
+::boost::is_empty<T>::value
+
+

If the compiler does not support partial-specialization of class templates, + then this template can not be used with function types.

+
 
 ::boost::has_nothrow_constructor<T>::valueTrue if T has a non-throwing default + constructor. 

Without some (as yet + unspecified) help from the compiler, has_nothrow_constructor will + never report that a class or struct has a non-throwing constructor; this is + always safe, if possibly sub-optimal.

+

If the compiler does not support partial-specialization of class + templates, then this template can not be used with function types.

+
 
 ::boost::has_nothrow_copy<T>::valueTrue if T has a non-throwing copy constructor. 

Without some (as yet + unspecified) help from the compiler, has_nothrow_destructor will + never report that a class or struct has a non-throwing destructor; this is + always safe, if possibly sub-optimal.

+

If the compiler does not support partial-specialization of class + templates, then this template can not be used with function types.

+
 
 ::boost::has_nothrow_assign<T>::valueTrue if T has a non-throwing assignment + operator. 

Without some (as yet + unspecified) help from the compiler, has_nothrow_destructor will + never report that a class or struct has a non-throwing assignment operator; + this is always safe, if possibly sub-optimal.

+

If the compiler does not support partial-specialization of class + templates, then this template can not be used with function types.

+
 
+

 

+

Relationships Between Types

+

The following templates determine the whether there is a relationship between + two types:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 

Expression

+

Description

+

Reference

+

Compiler + requirements

+
 
 
::boost::is_same<T,U>::value
+
+

Evaluates to true if T + and U are the same type.

+
 If the compiler does not support + partial-specialization of class templates, then this template can not be used + with abstract, incomplete or function types. 
 ::boost::is_convertible<T,U>::valueEvaluates to true if type T is + convertible to type U.

Types T and U must not be incomplete, abstract or + function types.

+

4

+

8.5

+
Note that this template is + currently broken with Borland C++ Builder 5 (and earlier), for + constructor-based conversions, and for the Metrowerks 7 (and earlier) compiler + in all cases. 
 ::boost::is_base_and_derived<T,U>::valueEvaluates to true if type T is a base class to type U.

Types + T and U must not be incomplete types.

+
10

This template relies upon a + functioning is_convertible template.

+

If the compiler does not support partial-specialization of class + templates, then this template can not be used with function types.

+
 
+

Note that both is_convertible, and is_base_and_derived + can produce compiler errors if the convertion is ambiguous:

+
struct A {};
 struct B : A {};
 struct C : A {};
 struct D : B, C {};
 bool const x = boost::is_base_and_derived<A,D>::value;  // error
 bool const y = boost::is_convertible<D*,A*>::value;     // error
 
- -

Transformations Between Types

- -

The following templates transform one type to another, based -upon some well-defined rule. Each template has a single member -called type that is the result of applying the -transformation to the template argument T:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 

Expression

-

Description

-

Reference

-

Compiler requirements

-
 
 ::boost::remove_const<T>::typeCreates a - type the same as T but with any top level const qualifier - removed. For example "const int" would become - "int", but "const int*" would remain - unchanged.3.9.3

P

-
 
 ::boost::remove_volatile<T>::typeCreates a - type the same as T but with any top level volatile - qualifier removed. For example "volatile int" - would become "int".

3.9.3

-

P

-
 
 ::boost::remove_cv<T>::typeCreates a type the same as T but - with any top level cv-qualifiers removed. For example - "const volatile int" would become "int".3.9.3

P

-
 
 ::boost::remove_reference<T>::typeIf T is a - reference type then removes the reference, otherwise - leaves T unchanged. For example "int&" - becomes "int" but "int*" remains - unchanged.8.3.2

P

-
 
 ::boost::remove_bounds<T>::typeIf T is an - array type then removes the top level array qualifier - from T, otherwise leaves T unchanged. For example "int[2][3]" - becomes "int[3]".8.3.4

P

-
 
 ::boost::remove_pointer<T>::typeIf T is a - pointer type, then removes the top-level indirection from - T, otherwise leaves T unchanged. For example "int*" - becomes "int", but "int&" remains - unchanged.8.3.1

P

-
 
 ::boost::add_reference<T>::typeIf T is a - reference type then leaves T unchanged, otherwise - converts T to a reference type. For example "int&" - remains unchanged, but "double" becomes "double&".8.3.2

P

-
 
 ::boost::add_pointer<T>::typeIf "t" - is an instance of T, then add_pointer<T>::type is - the type returned by "&t". For example - "int" and "int&" both become - "int*".8.3.1

P

-
 
 ::boost::add_const<T>::typeThe same as "T - const" for all T.3.9.3  
 ::boost::add_volatile<T>::typeThe same as "T - volatile" for all T.3.9.3  
 ::boost::add_cv<T>::typeThe same as "T - const volatile" for all T.3.9.3  
- -

As the table above indicates, support for partial -specialization of class templates is required to correctly -implement the type transformation templates. On the other hand, -practice shows that many of the templates from this category are -very useful, and often essential for implementing some generic -libraries. Lack of these templates is often one of the major -limiting factors in porting those libraries to compilers that do -not yet support this language feature. As some of these compilers -are going to be around for a while, and at least one of them is -very wide-spread, it was decided that the library should provide -workarounds where possible. The basic idea behind the workaround -is

- -
    -
  1. To manually define full specializations of all type - transformation templates for all fundamental types, and - all their 1st and 2nd rank cv-[un]qualified derivative - pointer types, and to
  2. -
  3. Provide a user-level macro that will define such explicit - specializations for any user-defined type T.
  4. -
- -

The first part guarantees the successful compilation of -something like this:

- -
BOOST_STATIC_ASSERT((is_same<char, remove_reference<char&>::type>::value));
- -
BOOST_STATIC_ASSERT((is_same<char const, remove_reference<char const&>::type>::value));
- -
BOOST_STATIC_ASSERT((is_same<char volatile, remove_reference<char volatile&>::type>::value));
- -
BOOST_STATIC_ASSERT((is_same<char const volatile, remove_reference<char const volatile&>::type>::value));
- -
BOOST_STATIC_ASSERT((is_same<char*, remove_reference<char*&>::type>::value));
- -
BOOST_STATIC_ASSERT((is_same<char const*, remove_reference<char const*&>::type>::value));
- -
...
- -
BOOST_STATIC_ASSERT((is_same<char const volatile* const volatile* const volatile, remove_reference<char const volatile* const volatile* const volatile&>::type>::value));
- -

and the second part provides library's users with a mechanism -to make the above code work not only for 'char', 'int' or other -built-in type, but for they own types too:

- -
struct my {};
- -
BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(my)
- -
BOOST_STATIC_ASSERT((is_same<my, remove_reference<my&>::type>::value));
- -
BOOST_STATIC_ASSERT((is_same<my, remove_const<my const>::type>::value));
- -
// etc.
- -

Note that the macro -BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION evaluates to -nothing on those compilers that do support partial specialization.

- -

Synthesizing Types

- -

The following template synthesizes a type with the desired -properties.

- - - - - - - - - - - - - - - - - - -
 

Expression

-

Description

-

Reference

-

Compiler requirements

-
 
 ::boost::type_with_alignment<Align>::typeAttempts - to find a built-in or POD type with an alignment that is - a multiple of Align.    
- -

Function Traits

- -

The ::boost::function_traits class template extracts information from function types. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 

Expression

-

Description

-

Reference

-

Compiler requirements

-
 
 ::boost::function_traits<F>::arityDetermine the arity of the function type F.  Without partial specialisation support, this template does not compile for reference types. 
 ::boost::function_traits<F>::result_typeThe type returned by function type F.  P 
 ::boost::function_traits<F>::argN_typeThe Nth argument type of function type F, where 1<=N<=arity of F. P 
- -

Compiler Support Information

- -

The legends used in the tables above have the following -meanings:

- - - - - - - - - - - - - - -

P

-
Denotes that the class - requires support for partial specialization of class - templates to work correctly.

C

-
Denotes that direct compiler - support for that traits class is required.

D

-
Denotes that the traits - class is dependent upon a class that requires direct - compiler support.
- -

 

- -

For those classes that are marked with a D or C, if compiler -support is not provided, this type trait may return "false" -when the correct value is actually "true". The single -exception to this rule is "is_class", which attempts to -guess whether or not T is really a class, and may return "true" -when the correct value is actually "false". This can -happen if: T is a union or T is a compiler-supplied scalar type -that is not specialised for in these type traits.

- -

If there is no compiler support, to ensure that these -traits always return the correct values, specialise -'is_union' for each user-defined union type, 'is_empty' for each -user-defined empty composite type, and 'is_POD' for each user-defined -POD type. The 'has_*' traits should also be specialized if the -user-defined type has those traits and is not a POD.

- -

The following rules are automatically enforced:

- -

is_enum implies is_POD

- -

is_POD implies has_*

- -

This means, for example, if you have an empty POD-struct, just -specialize is_empty and is_POD, which will cause all the has_* to -also return true.

- -

Type Traits Headers

- -

The type traits library is normally included with:

- -

#include <boost/type_traits.hpp>

- -

However the library is actually split up into a number of -smaller headers, sometimes it can be convenient to include one of -these directly in order to get just those type traits classes you -actually need. Note however that the type traits classes are -highly interdependent - so you may not save as much as you think -this way. The following table lists the type traits classes in -alphabetical order, along with the header that contains each -template.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 Template - classHeader 
 add_const<boost/type_traits/transform_traits.hpp> 
 add_const<boost/type_traits/transform_traits.hpp> 
 add_pointer<boost/type_traits/transform_traits.hpp> 
 add_reference<boost/type_traits/transform_traits.hpp> 
 add_volatile<boost/type_traits/transform_traits.hpp> 
 alignment_of<boost/type_traits/alignment_traits.hpp> 
 has_trivial_assign<boost/type_traits/object_traits.hpp> 
 function_traits<boost/type_traits/function_traits.hpp> 
 has_trivial_constructor<boost/type_traits/object_traits.hpp> 
 has_trivial_copy<boost/type_traits/object_traits.hpp> 
 has_trivial_destructor<boost/type_traits/object_traits.hpp> 
 is_arithmetic<boost/type_traits/arithmetic_traits.hpp> 
 is_array - <boost/type_traits/composite_traits.hpp> 
 is_base_and_derived<boost/type_traits/object_traits.hpp> 
 is_class<boost/type_traits/object_traits.hpp> 
 is_compound<boost/type_traits/object_traits.hpp> 
 is_const<boost/type_traits/cv_traits.hpp> 
 is_convertible<boost/type_traits/conversion_traits.hpp> 
 is_empty<boost/type_traits/object_traits.hpp> 
 is_enum<boost/type_traits/composite_traits.hpp> 
 is_float<boost/type_traits/arithmetic_traits.hpp> 
 is_function<boost/type_traits/function_traits.hpp> 
 is_fundamental<boost/type_traits/arithmetic_traits.hpp> 
 is_integral<boost/type_traits/arithmetic_traits.hpp> 
 is_member_pointer<boost/type_traits/composite_traits.hpp> 
 is_member_function_pointer<boost/type_traits/composite_traits.hpp> 
 is_object - <boost/type_traits/object_traits.hpp> 
 is_POD<boost/type_traits/object_traits.hpp> 
 is_pointer<boost/type_traits/composite_traits.hpp> 
 is_reference<boost/type_traits/composite_traits.hpp> 
 is_same<boost/type_traits/same_traits.hpp> 
 is_scalar<boost/type_traits/object_traits.hpp> 
 is_union<boost/type_traits/composite_traits.hpp> 
 is_void<boost/type_traits/arithmetic_traits.hpp> 
 is_volatile<boost/type_traits/cv_traits.hpp> 
 remove_bounds<boost/type_traits/transform_traits.hpp> 
 remove_const<boost/type_traits/cv_traits.hpp> 
 remove_cv<boost/type_traits/cv_traits.hpp> 
 remove_pointer<boost/type_traits/transform_traits.hpp> 
 remove_reference - <boost/type_traits/transform_traits.hpp> 
 remove_volatile<boost/type_traits/cv_traits.hpp> 
 type_with_alignment<boost/type_traits/alignment_traits.hpp> 
- -

 

- -

Example code

- -

Type-traits comes with four example programs that illustrate -some of the ways in which the type traits templates may be used:

- -

Copy_example.cpp

- -

Demonstrates a version of std::copy that uses memcpy where -appropriate to optimise the copy operation;

- -
//
+      

Transformations Between Types

+

The following templates transform one type to another, based upon some + well-defined rule. Each template has a single member called type that is + the result of applying the transformation to the template argument T:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 

Expression

+

Description

+

Reference

+

Compiler + requirements

+
 
 ::boost::remove_const<T>::typeCreates a type the same as T but + with any top level const qualifier removed. For example "const int" would + become "int", but "const int*" would remain unchanged.3.9.3

If the compiler does not support + partial-specialization of class templates, then this template will compile, but + will have no effect, except where noted below.

+
 
 ::boost::remove_volatile<T>::typeCreates a type the same as T but + with any top level volatile qualifier removed. For example "volatile int" would + become "int".

3.9.3

+

If the compiler does not support + partial-specialization of class templates, then this template will compile, but + will have no effect, except where noted below.

+
 
 ::boost::remove_cv<T>::typeCreates a type the same as T but with any top level + cv-qualifiers removed. For example "const volatile int" would become "int".3.9.3 +

If the compiler does not support partial-specialization of class + templates, then this template will compile, but will have no effect, except + where noted below.

+
 
 ::boost::remove_reference<T>::typeIf T is a reference type then + removes the reference, otherwise leaves T unchanged. For example "int&" + becomes "int" but "int*" remains unchanged.8.3.2 +

If the compiler does not support partial-specialization of class + templates, then this template will compile, but will have no effect, except + where noted below.

+
 
 ::boost::remove_bounds<T>::typeIf T is an array type then removes + the top level array qualifier from T, otherwise leaves T unchanged. For example + "int[2][3]" becomes "int[3]".8.3.4 +

If the compiler does not support partial-specialization of class + templates, then this template will compile, but will have no effect, except + where noted below.

+
 
 ::boost::remove_pointer<T>::typeIf T is a pointer type, then + removes the top-level indirection from T, otherwise leaves T unchanged. For + example "int*" becomes "int", but "int&" remains unchanged.8.3.1

If the compiler does not support + partial-specialization of class templates, then this template will compile, but + will have no effect, except where noted below.

+
 
 ::boost::add_reference<T>::typeIf T is a reference type then + leaves T unchanged, otherwise converts T to a reference type. For example + "int&" remains unchanged, but "double" becomes "double&".8.3.2

 

+
 
 ::boost::add_pointer<T>::typeIf "t" is an instance of T, then + add_pointer<T>::type is the type returned by "&t". For example "int" + and "int&" both become "int*".8.3.1 +

If the compiler does not support partial-specialization of class + templates, then this template will not compile with reference types.

+
 
 ::boost::add_const<T>::typeThe same as "T const" for all T.3.9.3  
 ::boost::add_volatile<T>::typeThe same as "T volatile" for all T.3.9.3  
 ::boost::add_cv<T>::typeThe same as "T const volatile" for all T.3.9.3  
+

As the table above indicates, support for partial specialization of class + templates is required to correctly implement the type transformation templates. + On the other hand, practice shows that many of the templates from this category + are very useful, and often essential for implementing some generic libraries. + Lack of these templates is often one of the major limiting factors in porting + those libraries to compilers that do not yet support this language feature. As + some of these compilers are going to be around for a while, and at least one of + them is very wide-spread, it was decided that the library should provide + workarounds where possible. The basic idea behind the workaround is

+
    +
  1. + To manually define full specializations of all type transformation templates + for all fundamental types, and all their 1st and 2nd rank cv-[un]qualified + derivative pointer types, and to +
  2. + Provide a user-level macro that will define such explicit specializations for + any user-defined type T.
  3. +
+

The first part guarantees the successful compilation of something like this:

+
BOOST_STATIC_ASSERT((is_same<char, remove_reference<char&>::type>::value));
+
BOOST_STATIC_ASSERT((is_same<char const, remove_reference<char const&>::type>::value));
+
BOOST_STATIC_ASSERT((is_same<char volatile, remove_reference<char volatile&>::type>::value));
+
BOOST_STATIC_ASSERT((is_same<char const volatile, remove_reference<char const volatile&>::type>::value));
+
BOOST_STATIC_ASSERT((is_same<char*, remove_reference<char*&>::type>::value));
+
BOOST_STATIC_ASSERT((is_same<char const*, remove_reference<char const*&>::type>::value));
+
...
+
BOOST_STATIC_ASSERT((is_same<char const volatile* const volatile* const volatile, remove_reference<char const volatile* const volatile* const volatile&>::type>::value));
+

and the second part provides library's users with a mechanism to make the above + code work not only for 'char', 'int' or other built-in type, but for they own + types too:

+
struct my {};
+
BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(my)
+
BOOST_STATIC_ASSERT((is_same<my, remove_reference<my&>::type>::value));
+
BOOST_STATIC_ASSERT((is_same<my, remove_const<my const>::type>::value));
+
// etc.
+

Note that the macro BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION evaluates + to nothing on those compilers that do support partial specialization.

+

Synthesizing Types

+

The following template synthesizes a type with the desired properties. +

+ + + + + + + + + + + + + + + + + +
 

Expression

+

Description

+

Reference

+

Compiler + requirements

+
 
 ::boost::type_with_alignment<Align>::typeAttempts to find a built-in or POD + type with an alignment that is a multiple of Align. +    
+

Function Traits

+

The ::boost::function_traits class template extracts information + from function types. +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 

Expression

+

Description

+

Reference

+

Compiler + requirements

+
 
 ::boost::function_traits<F>::arityDetermine the arity of the function + type F. +  Without partial specialisation support, this + template does not compile for reference types. 
 ::boost::function_traits<F>::result_typeThe type returned by function type + F. +  Does not compile without support for partial + specialization of class templates. 
 ::boost::function_traits<F>::argN_typeThe Nth + argument type of function type F, where 1<=N<=arity + of F. Does not compile without support for partial + specialization of class templates. 
+

Type Traits Headers

+

The type traits library is normally included with:

+
#include <boost/type_traits.hpp>
+

However the library is actually split up into a number of smaller headers, + sometimes it can be convenient to include one of these directly in order to get + just those type traits classes you actually need.  The split headers + always have the same name as the template you require, and are located in + boost/type_traits/.  So if for example some code requires + is_class<>, then just include:

+
<boost/type_traits/is_class.hpp>
+

Example code

+

Type-traits comes with four example programs that illustrate some of the ways + in which the type traits templates may be used:

+

Copy_example.cpp

+

Demonstrates a version of std::copy that uses memcpy where appropriate to + optimise the copy operation;

+
//
 // opt::copy
 // same semantics as std::copy
 // calls memcpy where appropiate.
@@ -1264,18 +899,15 @@ inline I2 copy(I1 first, I1 last, I2 out)
          ::boost::has_trivial_assign<v1_t>::value
       >::value>::do_copy(first, last, out);
 }
- -

fill_example.cpp

- -

Demonstrates a version of std::fill that uses memset where -appropriate to optimise fill operations. Also uses call_traits to -optimise parameter passing, to avoid aliasing issues:

- -
namespace opt{
+      

fill_example.cpp

+

Demonstrates a version of std::fill that uses memset where appropriate to + optimise fill operations. Also uses call_traits to optimise parameter passing, + to avoid aliasing issues:

+
namespace opt{
 //
 // fill
 // same as std::fill, uses memset where appropriate, along with call_traits
-// to "optimise" parameter passing.
+// to "optimise" parameter passing.
 //
 namespace detail{
 
@@ -1329,15 +961,11 @@ inline void fill(I first, I last, const T& val)
 }
 
 };   // namespace opt
- -

iter_swap_example.cpp

- -

Demonstrates a version of std::iter_swap that works with -proxying iterators, as well as regular ones; calls std::swap for -regular iterators, otherwise does a "slow but safe" -swap:

- -
namespace opt{
+      

iter_swap_example.cpp

+

Demonstrates a version of std::iter_swap that works with proxying iterators, as + well as regular ones; calls std::swap for regular iterators, otherwise does a + "slow but safe" swap:

+
namespace opt{
 //
 // iter_swap:
 // tests whether iterator is a proxying iterator or not, and
@@ -1385,15 +1013,11 @@ inline void iter_swap(I1 one, I2 two)
 }
 
 };   // namespace opt
- -

Trivial_destructor_example.cpp

- -

This algorithm is the reverse of std::unitialized_copy; it -takes a block of initialized memory and calls destructors on all -objects therein. This would typically be used inside container -classes that manage their own memory:

- -
namespace opt{
+      

Trivial_destructor_example.cpp

+

This algorithm is the reverse of std::unitialized_copy; it takes a block of + initialized memory and calls destructors on all objects therein. This would + typically be used inside container classes that manage their own memory:

+
namespace opt{
 //
 // algorithm destroy_array:
 // The reverse of std::unitialized_copy, takes a block of
@@ -1434,35 +1058,23 @@ inline void destroy_array(T* p1, T* p2)
    detail::array_destroyer<boost::has_trivial_destructor<T>::value>::destroy_array(p1, p2);
 }
 } // namespace opt
- -
- -

Revised 22 April 2001

- -

Documentation © Copyright John Maddock 2001. Permission to -copy, use, modify, sell and distribute this document is granted -provided this copyright notice appears in all copies. This -document is provided "as is" without express or implied -warranty, and with no claim as to its suitability for any purpose.

- -

The type traits library is based on contributions by Steve -Cleary, Beman Dawes, Aleksey Gurtovoy, Howard Hinnant, Jesse -Jones, Mat Marcus, John Maddock and Jeremy Siek.

- -

Mat Marcus and Jesse Jones have worked on, and published a paper -describing the partial specialisation workarounds used in this -library.

- -

The is_convertible template is based on code originally -devised by Andrei Alexandrescu, see "Generic<Programming>: -Mappings between Types and Values".

- -

Maintained by John -Maddock, the latest version of this file can be found at www.boost.org, and the boost -discussion list at www.yahoogroups.com/list/boost.

- +
+

Revised 22 April 2001

+

Documentation © Copyright John Maddock 2001. Permission to copy, use, modify, + sell and distribute this document is granted provided this copyright notice + appears in all copies. This document is provided "as is" without express or + implied warranty, and with no claim as to its suitability for any purpose.

+

The type traits library is based on contributions by Steve Cleary, Beman Dawes, + Aleksey Gurtovoy, Howard Hinnant, Jesse Jones, Mat Marcus, John Maddock and + Jeremy Siek.

+

Mat Marcus and Jesse Jones have worked on, and published a + paper describing the partial specialisation workarounds used in this + library.

+

The is_convertible template is based on code originally devised by Andrei + Alexandrescu, see "Generic<Programming>: + Mappings between Types and Values".

+

Maintained by John Maddock, the + latest version of this file can be found at www.boost.org, + and the boost discussion list at www.yahoogroups.com/list/boost.

+ diff --git a/test/is_convertible_test.cpp b/test/is_convertible_test.cpp index 6f44b0e..1f37842 100644 --- a/test/is_convertible_test.cpp +++ b/test/is_convertible_test.cpp @@ -40,7 +40,6 @@ BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible::value), false); BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible::value), false); -BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible::value), true); BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible::value), false); BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible::value), true); BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible::value), true);