diff --git a/index.htm b/index.htm index ca3c307..873dc8b 100644 --- a/index.htm +++ b/index.htm @@ -1,14 +1,22 @@ -
-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:
--
-- - The properties of a specific type. -
- - The relationship between two types. -
- - A transformation from one type to another.
-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
- andis_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>::value |
- Evaluates to true only if T is a - cv-qualified void type. | -3.9.1p9 - |
- - | - |
- | ::boost::is_integral<T>::value |
- Evaluates to true only if T is an - cv-qualified integral type. | -3.9.1p7 - |
- - | - |
- | ::boost::is_float<T>::value |
- Evaluates to true only if T is a - cv-qualified floating point type. | -3.9.1p8 - |
- - | - |
- | ::boost::is_pointer<T>::value |
- Evaluates 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>::value |
- Evaluates 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>::value |
- Evaluates 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>::value |
- Evaluates 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>::value |
- Evaluates 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>::value |
- Evaluates 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>::value |
- Evaluates 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>::value |
- Evaluates 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. | -- |
-
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>::value |
- Evaluates 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>::value |
- Evaluates 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>::value |
- Evaluates 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>::value |
- Evaluates 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>::value |
- Evaluates 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>::value |
- Evaluates 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 - |
- - | - |
-
The following templates identify the properties that a type has.
-- | Expression - |
- Description - |
- Reference - |
- Compiler - requirements - |
- - | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
- | ::boost::alignment_of<T>::value |
- Identifies 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>::value |
- True 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>::value |
- Evaluates to true only if T is - top-level const-qualified. | -3.9.3 - |
- - | - | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
- | ::boost::is_volatile<T>::value |
- Evaluates to true only if T is - volatile-qualified. | -3.9.3 - |
- - | - | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
- | ::boost::is_polymorphic<T>::value | -Evaluates to true only if T is a - polymorphic type. | -10.3 | -Requires knowledge of the compilers - ABI, does actually seem to work with the magority of compilers though. | -- | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
- | ::boost::is_POD<T>::value |
- Evaluates 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>::value |
- True if T has a trivial default - constructor. | -12.1p5 | -Without some (as yet
- unspecified) help from the compiler, 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>::value |
- True if T has a trivial copy - constructor. | -12.8p6 | -Without some (as yet
- unspecified) help from the compiler, 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>::value |
- True if T has a trivial assignment - operator. | -12.8p11 | -Without some (as yet
- unspecified) help from the compiler, 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>::value |
- True if T has a trivial destructor. | -12.4p3 | -Without some (as yet
- unspecified) help from the compiler, 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>::value |
- True 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, Will report true only if all of the following also report true: -::boost::has_trivial_constructor<T>::value, + +
+ + 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. + +
+ + Type Properties+ +The following templates identify the properties that a type +has. + +
- Relationships Between Types-The following templates determine the whether there is a relationship between - two types: -
Note that both 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>::value |
+ True if T has a non-throwing + default constructor. | ++ | Without
+ some (as yet unspecified) help from the compiler, 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>::value |
+ True if T has a non-throwing + copy constructor. | ++ | Without
+ some (as yet unspecified) help from the compiler, 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>::value |
+ True if T has a non-throwing + assignment operator. | ++ | Without
+ some (as yet unspecified) help from the compiler, If the compiler does not support partial-specialization + of class templates, then this template can not be used + with function types. + |
+ + |
+ +
The following templates determine the whether there is a +relationship between two types:
+ ++ | Expression + |
+ Description + |
+ Reference + |
+ Compiler requirements + |
+ + |
+ |
+ |
+ 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>::value |
+ Evaluates
+ 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>::value |
+ Evaluates 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-
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>::type |
- Creates 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>::type |
- Creates 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>::type |
- Creates 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>::type |
- If 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>::type |
- If 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>::type |
- If 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>::type |
- If 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>::type |
- If "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>::type |
- The same as "T const" for all T. | -3.9.3 | -- | - |
- | ::boost::add_volatile<T>::type |
- The same as "T volatile" for all T. | -3.9.3 | -- | - |
- | ::boost::add_cv<T>::type |
- The 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
-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.
-The following template synthesizes a type with the desired properties. -
-- | Expression - |
- Description - |
- Reference - |
- Compiler - requirements - |
- - |
- | ::boost::type_with_alignment<Align>::type |
- Attempts to find a built-in or POD - type with an alignment that is a multiple of Align. - | -- | - | - |
The ::boost::function_traits
class template extracts information
- from function types.
-
- | Expression - |
- Description - |
- Reference - |
- Compiler - requirements - |
- - |
- | ::boost::function_traits<F>::arity |
- Determine the arity of the function
- type F .
- |
- - | Without partial specialisation support, this - template does not compile for reference types. | -- |
- | ::boost::function_traits<F>::result_type |
- The type returned by function type
- F .
- |
- - | Does not compile without support for partial - specialization of class templates. | -- |
- | ::boost::function_traits<F>::arg N _type |
- The N th
- argument type of function type F , where 1<= N <= arity
- of F . |
- - | Does not compile without support for partial - specialization of class templates. | -- |
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>-
Type-traits comes with four example programs that illustrate some of the ways - in which the type traits templates may be used:
-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>::type |
+ Creates 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>::type |
+ Creates 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>::type |
+ Creates 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>::type |
+ If 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>::type |
+ If 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>::type |
+ If 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>::type |
+ If 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>::type |
+ If "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>::type |
+ The same as "T + const" for all T. | +3.9.3 | ++ | + |
+ | ::boost::add_volatile<T>::type |
+ The same as "T + volatile" for all T. | +3.9.3 | ++ | + |
+ | ::boost::add_cv<T>::type |
+ The 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
+ +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.
+ +The following template synthesizes a type with the desired +properties.
+ ++ | Expression + |
+ Description + |
+ Reference + |
+ Compiler requirements + |
+ + |
+ | ::boost::type_with_alignment<Align>::type |
+ Attempts + to find a built-in or POD type with an alignment that is + a multiple of Align. | ++ | + | + |
The ::boost::function_traits
class template
+extracts information from function types.
+ | Expression + |
+ Description + |
+ Reference + |
+ Compiler requirements + |
+ + |
+ | ::boost::function_traits<F>::arity |
+ Determine
+ the arity of the function type F . |
+ + | Without partial + specialisation support, this template does not compile + for reference types. | ++ |
+ | ::boost::function_traits<F>::result_type |
+ The type
+ returned by function type F . |
+ + | Does not compile + without support for partial specialization of class + templates. | ++ |
+ | ::boost::function_traits<F>::arg N _type |
+ The N th
+ argument type of function type F , where 1<= N <= arity
+ of F . |
+ + | Does not compile + without support for partial specialization of class + templates. | ++ |
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>+ +
Type-traits comes with four example programs that illustrate +some of the ways in which the type traits templates may be used:
+ +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); }-
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 { };