diff --git a/include/boost/detail/compressed_pair.hpp b/include/boost/detail/compressed_pair.hpp index c2b9bef..621a677 100644 --- a/include/boost/detail/compressed_pair.hpp +++ b/include/boost/detail/compressed_pair.hpp @@ -19,8 +19,11 @@ #define BOOST_DETAIL_COMPRESSED_PAIR_HPP #include -#ifndef BOOST_TYPE_TRAITS_HPP -#include +#ifndef BOOST_OBJECT_TYPE_TRAITS_HPP +#include +#endif +#ifndef BOOST_SAME_TRAITS_HPP +#include #endif #ifndef BOOST_CALL_TRAITS_HPP #include @@ -422,3 +425,4 @@ swap(compressed_pair& x, compressed_pair& y) #endif // BOOST_DETAIL_COMPRESSED_PAIR_HPP + diff --git a/include/boost/detail/ob_call_traits.hpp b/include/boost/detail/ob_call_traits.hpp index a031f17..091eea3 100644 --- a/include/boost/detail/ob_call_traits.hpp +++ b/include/boost/detail/ob_call_traits.hpp @@ -24,8 +24,11 @@ #include #endif -#ifndef BOOST_TYPE_TRAITS_HPP -#include +#ifndef BOOST_ARITHMETIC_TYPE_TRAITS_HPP +#include +#endif +#ifndef BOOST_COMPOSITE_TYPE_TRAITS_HPP +#include #endif namespace boost{ diff --git a/iterator_traits_test.cpp b/iterator_traits_test.cpp index e5631a8..716a411 100644 --- a/iterator_traits_test.cpp +++ b/iterator_traits_test.cpp @@ -7,6 +7,16 @@ // See http://www.boost.org for most recent version including documentation. // Revision History +// 04 Mar 2001 Patches for Intel C++ (Dave Abrahams) +// 19 Feb 2001 Take advantage of improved iterator_traits to do more tests +// on MSVC. Reordered some #ifdefs for coherency. +// (David Abrahams) +// 13 Feb 2001 Test new VC6 workarounds (David Abrahams) +// 11 Feb 2001 Final fixes for Borland (David Abrahams) +// 11 Feb 2001 Some fixes for Borland get it closer on that compiler +// (David Abrahams) +// 07 Feb 2001 More comprehensive testing; factored out static tests for +// better reuse (David Abrahams) // 21 Jan 2001 Quick fix to my_iterator, which wasn't returning a // reference type from operator* (David Abrahams) // 19 Jan 2001 Initial version with iterator operators (David Abrahams) @@ -21,105 +31,162 @@ #include #include -struct my_iterator - : public boost::forward_iterator_helper +// An iterator for which we can get traits. +struct my_iterator1 + : boost::forward_iterator_helper { - my_iterator(const char* p) : m_p(p) {} + my_iterator1(const char* p) : m_p(p) {} - bool operator==(const my_iterator& rhs) const + bool operator==(const my_iterator1& rhs) const { return this->m_p == rhs.m_p; } - my_iterator& operator++() { ++this->m_p; return *this; } + my_iterator1& operator++() { ++this->m_p; return *this; } const char& operator*() { return *m_p; } private: const char* m_p; }; -// Test difference_type and iterator_category +// Used to prove that we don't require std::iterator<> in the hierarchy under +// MSVC6, and that we can compute all the traits for a standard-conforming UDT +// iterator. +struct my_iterator2 + : boost::equality_comparable > > +{ + typedef char value_type; + typedef long difference_type; + typedef const char* pointer; + typedef const char& reference; + typedef std::forward_iterator_tag iterator_category; + + my_iterator2(const char* p) : m_p(p) {} + + bool operator==(const my_iterator2& rhs) const + { return this->m_p == rhs.m_p; } -// istream_iterator (forward_iterator_tag, ptrdiff_t) -BOOST_STATIC_ASSERT(( - boost::is_same< - boost::detail::iterator_traits >::iterator_category, - std::input_iterator_tag - >::value)); + my_iterator2& operator++() { ++this->m_p; return *this; } + const char& operator*() { return *m_p; } + private: + const char* m_p; +}; -BOOST_STATIC_ASSERT(( - boost::is_same< - boost::detail::iterator_traits >::difference_type, - std::ptrdiff_t - >::value)); +// Used to prove that we're not overly confused by the existence of +// std::iterator<> in the hierarchy under MSVC6 - we should find that +// boost::detail::iterator_traits::difference_type is int. +struct my_iterator3 : my_iterator1 +{ + typedef int difference_type; + my_iterator3(const char* p) : my_iterator1(p) {} +}; -// ostream_iterator (output_iterator_tag, void) -BOOST_STATIC_ASSERT(( - boost::is_same< - boost::detail::iterator_traits >::iterator_category, - std::output_iterator_tag - >::value)); +template +struct non_portable_tests +{ + // Unfortunately, the VC6 standard library doesn't supply these :( + BOOST_STATIC_ASSERT(( + boost::is_same< + typename boost::detail::iterator_traits::pointer, + pointer + >::value)); + + BOOST_STATIC_ASSERT(( + boost::is_same< + typename boost::detail::iterator_traits::reference, + reference + >::value)); +}; -BOOST_STATIC_ASSERT(( - boost::is_same< - boost::detail::iterator_traits >::difference_type, - void - >::value)); +template +struct portable_tests +{ + BOOST_STATIC_ASSERT(( + boost::is_same< + typename boost::detail::iterator_traits::difference_type, + difference_type + >::value)); + + BOOST_STATIC_ASSERT(( + boost::is_same< + typename boost::detail::iterator_traits::iterator_category, + category + >::value)); +}; + +// Test iterator_traits +template +struct input_iterator_test + : portable_tests +{ + BOOST_STATIC_ASSERT(( + boost::is_same< + typename boost::detail::iterator_traits::value_type, + value_type + >::value)); +}; + +template +struct non_pointer_test + : input_iterator_test + , non_portable_tests +{ +}; + +template +struct maybe_pointer_test + : portable_tests +#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + , non_portable_tests +#endif +{ +}; + +input_iterator_test, int, std::ptrdiff_t, int*, int&, std::input_iterator_tag> + istream_iterator_test; + +// +#if defined(__BORLANDC__) && !defined(__SGI_STL_PORT) +typedef ::std::char_traits::off_type distance; +non_pointer_test,int, + distance,int*,int&,std::output_iterator_tag> ostream_iterator_test; +#elif defined(BOOST_MSVC_STD_ITERATOR) +non_pointer_test, + int, void, void, void, std::output_iterator_tag> + ostream_iterator_test; +#else +non_pointer_test, + void, void, void, void, std::output_iterator_tag> + ostream_iterator_test; +#endif -// list::iterator (bidirectional_iterator_tag, ptrdiff_t) -BOOST_STATIC_ASSERT(( - boost::is_same< - boost::detail::iterator_traits::iterator>::iterator_category, - std::bidirectional_iterator_tag - >::value)); #ifdef __KCC typedef long std_list_diff_type; #else typedef std::ptrdiff_t std_list_diff_type; #endif +non_pointer_test::iterator, int, std_list_diff_type, int*, int&, std::bidirectional_iterator_tag> + list_iterator_test; -BOOST_STATIC_ASSERT(( - boost::is_same< - boost::detail::iterator_traits::iterator>::difference_type, - std_list_diff_type - >::value)); +maybe_pointer_test::iterator, int, std::ptrdiff_t, int*, int&, std::random_access_iterator_tag> + vector_iterator_test; -// vector::iterator (random_access_iterator_tag, ptrdiff_t) -BOOST_STATIC_ASSERT(( - boost::is_same< - boost::detail::iterator_traits::iterator>::iterator_category, - std::random_access_iterator_tag - >::value)); +maybe_pointer_test + int_pointer_test; + +non_pointer_test + my_iterator1_test; -BOOST_STATIC_ASSERT(( - boost::is_same< - boost::detail::iterator_traits::iterator>::difference_type, - std::ptrdiff_t - >::value)); +non_pointer_test + my_iterator2_test; -// int* (random_access_iterator_tag, ptrdiff_t) -BOOST_STATIC_ASSERT(( - boost::is_same< - boost::detail::iterator_traits::iterator_category, - std::random_access_iterator_tag - >::value)); - -BOOST_STATIC_ASSERT(( - boost::is_same< - boost::detail::iterator_traits::difference_type, - std::ptrdiff_t - >::value)); - -// my_iterator (forward_iterator_tag, long) -BOOST_STATIC_ASSERT(( - boost::is_same< - boost::detail::iterator_traits::iterator_category, - std::forward_iterator_tag - >::value)); - -BOOST_STATIC_ASSERT(( - boost::is_same< - boost::detail::iterator_traits::difference_type, - long - >::value)); +non_pointer_test + my_iterator3_test; int main() { @@ -135,7 +202,9 @@ int main() assert(boost::detail::distance(v.begin(), v.end()) == length); assert(boost::detail::distance(&ints[0], ints + length) == length); - assert(boost::detail::distance(my_iterator(chars), my_iterator(chars + length)) == length); + assert(boost::detail::distance(my_iterator1(chars), my_iterator1(chars + length)) == length); + assert(boost::detail::distance(my_iterator2(chars), my_iterator2(chars + length)) == length); + assert(boost::detail::distance(my_iterator3(chars), my_iterator3(chars + length)) == length); } return 0; } diff --git a/type_traits.htm b/type_traits.htm deleted file mode 100644 index 7564443..0000000 --- a/type_traits.htm +++ /dev/null @@ -1,620 +0,0 @@ - - - - - - -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. This documentation is -divided up into the following sections:

- -
Fundamental type operations
-Fundamental type properties
-   Miscellaneous
-   cv-Qualifiers
-   Fundamental Types
-   Compound Types
-   Object/Scalar Types
-Compiler Support Information
-Example Code
- -

Fundamental type operations

- -

Usage: "class_name<T>::type" performs -indicated transformation on type T.

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

Expression.

-

Description.

-

Compiler.

-
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".

P

-
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".

P

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

P

-
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.

P

-
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&".

P

-
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]".

P

-
- -

 

- -

Fundamental type properties

- -

Usage: "class_name<T>::value" is true if -indicated property is true, false otherwise. (Note that class_name<T>::value -is always defined as a compile time constant).

- -

Miscellaneous

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

Expression

-

Description

-

Compiler

-
is_same<T,U>::value
-

True if T and U are the - same type.

-
 
is_convertible<T,U>::value
-

True if type T is - convertible to type U.

-
 
alignment_of<T>::value
-

An integral value - representing the minimum alignment requirements of type T - (strictly speaking defines a multiple of the type's - alignment requirement; for all compilers tested so far - however it does return the actual alignment).

-
 
- -

 

- -

cv-Qualifiers

- -

The following classes determine what cv-qualifiers are present -on a type (see 3.93).

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

Expression.

-

Description.

-

Compiler.

-
is_const<T>::valueTrue if type T is top-level - const qualified. 
is_volatile<T>::valueTrue if type T is top-level - volatile qualified. 
- -

 

- -

Fundamental Types

- -

The following will only ever be true for cv-unqualified types; -these are closely based on the section 3.9 of the C++ Standard.

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

Expression.

-

Description.

-

Compiler.

-
is_void<T>::valueTrue only if T is void. 
is_standard_unsigned_integral<T>::valueTrue only if T is one of the - standard unsigned integral types (3.9.1 p3) - unsigned - char, unsigned short, unsigned int, and unsigned long. 
is_standard_signed_integral<T>::valueTrue only if T is one of the - standard signed integral types (3.9.1 p2) - signed char, - short, int, and long. 
is_standard_integral<T>::valueTrue if T is a standard - integral type(3.9.1 p7) - T is either char, wchar_t, bool - or either is_standard_signed_integral<T>::value or - is_standard_integral<T>::value is true. 
is_standard_float<T>::valueTrue if T is one of the - standard floating point types(3.9.1 p8) - float, double - or long double. 
is_standard_arithmetic<T>::valueTrue if T is a standard - arithmetic type(3.9.1 p8) - implies is_standard_integral - or is_standard_float is true. 
is_standard_fundamental<T>::valueTrue if T is a standard - arithmetic type or if T is void. 
is_extension_unsigned_integral<T>::valueTrue for compiler specific - unsigned integral types. 
is_extension_signed_integral<T>>:valueTrue for compiler specific - signed integral types. 
is_extension_integral<T>::valueTrue if either is_extension_unsigned_integral<T>::value - or is_extension_signed_integral<T>::value is true. 
is_extension_float<T>::valueTrue for compiler specific - floating point types. 
is_extension_arithmetic<T>::valueTrue if either is_extension_integral<T>::value - or is_extension_float<T>::value are true. 
 is_extension_fundamental<T>::valueTrue if either is_extension_arithmetic<T>::value - or is_void<T>::value are true. 
 is_unsigned_integral<T>::valueTrue if either is_standard_unsigned_integral<T>::value - or is_extention_unsigned_integral<T>::value are - true. 
is_signed_integral<T>::valueTrue if either is_standard_signed_integral<T>::value - or is_extention_signed_integral<T>>::value are - true. 
is_integral<T>::valueTrue if either is_standard_integral<T>::value - or is_extention_integral<T>::value are true. 
is_float<T>::valueTrue if either is_standard_float<T>::value - or is_extention_float<T>::value are true. 
is_arithmetic<T>::valueTrue if either is_integral<T>::value - or is_float<T>::value are true. 
is_fundamental<T>::valueTrue if either is_arithmetic<T>::value - or is_void<T>::value are true. 
- -

 

- -

Compound Types

- -

The following will only ever be true for cv-unqualified types, -as defined by the Standard. 

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

Expression

-

Description

-

Compiler

-
is_array<T>::valueTrue if T is an array type.

P

-
is_pointer<T>::valueTrue if T is a regular - pointer type - including function pointers - but - excluding pointers to member functions (3.9.2 p1 and 8.3.1). 
is_member_pointer<T>::valueTrue if T is a pointer to a - non-static class member (3.9.2 p1 and 8.3.1). 
is_reference<T>::valueTrue if T is a reference - type (3.9.2 p1 and 8.3.2). 
is_class<T>::valueTrue if T is a class or - struct type.

PD

-
is_union<T>::valueTrue if T is a union type.

C

-
is_enum<T>::valueTrue if T is an enumerator - type.

C

-
is_compound<T>::valueTrue if T is any of the - above compound types.

PD

-
- -

 

- -

Object/Scalar Types

- -

The following ignore any top level cv-qualifiers: if class_name<T>::value -is true then class_name<cv-qualified-T>::value -will also be true.

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

Expression

-

Description

-

Compiler

-
is_object<T>::valueTrue if T is not a reference - type, or a (possibly cv-qualified) void type.

P

-
is_standard_scalar<T>::valueTrue if T is a standard - arithmetic type, an enumerated type, a pointer or a - member pointer.

PD

-
is_extension_scalar<T>::valueTrue if T is an extentions - arithmetic type, an enumerated type, a pointer or a - member pointer.

PD

-
is_scalar<T>::valueTrue if T is an arithmetic - type, an enumerated type, a pointer or a member pointer.

PD

-
is_POD<T>::valueTrue if T is a "Plain - Old Data" type (see 3.9 p2&p3). Note that - although this requires compiler support to be correct in - all cases, if T is a scalar or an array of scalars then - we can correctly define T as a POD.

PC

-
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. Screens out enum - types by using is_convertible<T,int>, this means - that empty classes that overload operator int(), will not - be classified as empty.

PCD

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

PC

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

PC

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

PC

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

PC

-
- -

 

- -

Compiler Support Information

- -

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

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

P

-
Denotes that the class - requires support for partial specialisation 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, T is an enum, 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_enum' -for each user-defined enumeration type, '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.

- -

Example code

- -

Type-traits comes with two sample programs: type_traits_test.cpp tests the -type traits classes - mostly this is a test of your compiler's -support for the concepts used in the type traits implementation, -while algo_opt_examples.cpp -uses the type traits classes to "optimise" some -familiar standard library algorithms.

- -

There are four algorithm examples in algo_opt_examples.cpp:

- - - - - - - - - - - - - - - - - - -
opt::copy
-
If the copy operation can be - performed using memcpy then does so, otherwise uses a - regular element by element copy (c.f. std::copy).
opt::fill
-
If the fill operation can be - performed by memset, then does so, otherwise uses a - regular element by element assign. Also uses call_traits - to optimise how the parameters can be passed (c.f. - std::fill).
opt::destroy_array
-
If the type in the array has - a trivial destructor then does nothing, otherwise calls - destructors for all elements in the array - this - algorithm is the reverse of std::uninitialized_copy / std::uninitialized_fill.
opt::iter_swap
-
Determines whether the - iterator is a proxy-iterator: if it is then does a "slow - and safe" swap, otherwise calls std::swap on the - assumption that std::swap may be specialised for the - iterated type.
- -

 

- -
- -

Revised 01 September 2000

- -

© Copyright boost.org 2000. 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.

- -

Based on contributions by Steve Cleary, Beman Dawes, Howard -Hinnant and John Maddock.

- -

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

- -