From 0572dd371393295a4fdea0d133559548acbb25a5 Mon Sep 17 00:00:00 2001 From: John Maddock Date: Sat, 1 Feb 2003 12:12:08 +0000 Subject: [PATCH] Updated tests to stress new is_convertible and is_base_and_derived improvements. Updated docs accordingly. [SVN r17147] --- index.htm | 1959 ++++++++++++++++------------- test/is_base_and_derived_test.cpp | 12 +- test/is_convertible_test.cpp | 4 +- test/test.hpp | 3 + 4 files changed, 1102 insertions(+), 876 deletions(-) diff --git a/index.htm b/index.htm index ca3c307..873dc8b 100644 --- a/index.htm +++ b/index.htm @@ -1,14 +1,22 @@ - - Type Traits - - - - - -

Header <boost/type_traits.hpp>

-

Contents

-
Introduction
+
+
+
+
+
+Type Traits
+
+
+
+
+

Header +<boost/type_traits.hpp>

+ +

Contents

+ +
Introduction
 Primary Type Categorisation
 Secondary Type Categorisation
 Type Properties
@@ -18,843 +26,1026 @@
 Function Traits
 Type traits headers
 Example Code
-

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 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_polymorphic<T>::valueEvaluates to true only if T is a - polymorphic type.10.3Requires knowledge of the compilers - ABI, does actually seem to work with the magority of compilers though.
 ::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,
+
+

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. +
  3. The relationship between two types.
  4. +
  5. A transformation from one type to another.
  6. +
+ +

If you are new to this library then the accompanying article provides 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_polymorphic<T>::valueEvaluates + to true only if T is a polymorphic type.10.3Requires + knowledge of the compilers ABI, does actually seem to + work with the magority of compilers though. 
 ::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 {};
+        

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 an imaginary lvalue of type T is convertible + to type U.

Type T must not be an incomplete type.

+

Type U must not be an incomplete, abstract or function + type.

+

No types are considered to be convertible to an array + type.

+

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.

Will detect non-public base + classes, and ambiguous base classes.

+

Note that a class is not considered to be it's own + base class, likewise, if either T or U are non-class + types, then the result will always be false.

+

Types T and U must not be incomplete types.

+
10

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

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;

-
//
+
+

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. +
  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.  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.
@@ -909,15 +1100,18 @@ 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{
 
@@ -971,11 +1165,15 @@ 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
@@ -1023,11 +1221,15 @@ 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
@@ -1068,24 +1270,35 @@ 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 boost@lists.boost.org - (see http://www.boost.org/more/mailing_lists.htm#main).

- + +
+ +

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 boost@lists.boost.org +(see http://www.boost.org/more/mailing_lists.htm#main).

+ diff --git a/test/is_base_and_derived_test.cpp b/test/is_base_and_derived_test.cpp index 94d6cec..24d155d 100644 --- a/test/is_base_and_derived_test.cpp +++ b/test/is_base_and_derived_test.cpp @@ -4,16 +4,23 @@ // in all copies. This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. + #include "test.hpp" #include "check_integral_constant.hpp" #include TYPE_TRAITS(is_base_and_derived) + + TT_TEST_BEGIN(is_base_and_derived) BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_base_and_derived::value), false); -BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_base_and_derived::value), true); -BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_base_and_derived::value), true); +BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_base_and_derived::value), false); +BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_base_and_derived::value), false); BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_base_and_derived::value), true); +BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_base_and_derived::value), true); +BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_base_and_derived::value), true); +BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_base_and_derived::value), true); +BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_base_and_derived::value), true); BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_base_and_derived::value), false); BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_base_and_derived::value), false); BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_base_and_derived::value), false); @@ -34,3 +41,4 @@ TT_TEST_END + diff --git a/test/is_convertible_test.cpp b/test/is_convertible_test.cpp index 1f37842..4bcc2db 100644 --- a/test/is_convertible_test.cpp +++ b/test/is_convertible_test.cpp @@ -49,6 +49,8 @@ BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible::value), t BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible::value), true); 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), false); +BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible::value), true); BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible::value), true); BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible::value), false); @@ -60,7 +62,7 @@ BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible::value), true); BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible >::value), true); diff --git a/test/test.hpp b/test/test.hpp index 9c678fb..ddae8f2 100644 --- a/test/test.hpp +++ b/test/test.hpp @@ -180,6 +180,9 @@ union empty_POD_union_UDT{}; class Base { }; class Derived : public Base { }; +class Derived2 : public Base { }; +class MultiBase : public Derived, public Derived2 {}; +class PrivateBase : private Base {}; class NonDerived { };