From 0977ea3b67582e730714b027e07db802c09b93e6 Mon Sep 17 00:00:00 2001 From: John Maddock Date: Fri, 1 Oct 2010 11:11:16 +0000 Subject: [PATCH] Merges changes from Trunk: refer to history.qbk for the details. [SVN r65708] --- doc/add_lvalue_reference.qbk | 47 +++ doc/add_reference.qbk | 6 + doc/add_rvalue_reference.qbk | 50 +++ doc/common_type.qbk | 219 +++++++++++ doc/conditional.qbk | 18 + doc/examples.qbk | 17 + doc/history.qbk | 5 + doc/html/boost_typetraits/background.html | 22 +- .../boost_typetraits/category/transform.html | 14 +- doc/html/boost_typetraits/examples.html | 2 + .../examples/improved_min.html | 64 ++++ .../boost_typetraits/examples/to_double.html | 6 +- doc/html/boost_typetraits/history.html | 20 +- doc/html/boost_typetraits/intrinsics.html | 2 +- doc/html/boost_typetraits/reference.html | 14 +- .../boost_typetraits/reference/add_const.html | 2 +- .../boost_typetraits/reference/add_cv.html | 8 +- .../reference/add_lvalue_reference.html | 174 +++++++++ .../reference/add_pointer.html | 8 +- .../reference/add_reference.html | 20 +- .../reference/add_rvalue_reference.html | 172 +++++++++ .../reference/add_volatile.html | 8 +- .../reference/alignment_of.html | 6 +- .../reference/common_type.html | 350 ++++++++++++++++++ .../reference/common_type_hpp.html | 117 ++++++ .../boost_typetraits/reference/decay.html | 8 +- .../reference/floating_point_promotion.html | 2 +- .../reference/function_traits.html | 4 +- .../reference/integral_promotion.html | 2 +- .../reference/make_signed.html | 2 +- .../reference/make_unsigned.html | 2 +- .../boost_typetraits/reference/promote.html | 2 +- .../reference/remove_all_extents.html | 2 +- .../reference/remove_const.html | 2 +- .../boost_typetraits/reference/remove_cv.html | 2 +- .../reference/remove_extent.html | 2 +- .../reference/remove_pointer.html | 2 +- .../reference/remove_reference.html | 2 +- .../reference/remove_volatile.html | 2 +- doc/html/index.html | 10 +- doc/transform_traits.qbk | 12 + doc/type_traits.qbk | 8 + include/boost/type_traits.hpp | 26 +- .../type_traits/add_lvalue_reference.hpp | 26 ++ .../type_traits/add_rvalue_reference.hpp | 67 ++++ include/boost/type_traits/common_type.hpp | 153 ++++++++ include/boost/type_traits/conditional.hpp | 25 ++ .../type_traits/detail/common_type_imp.hpp | 302 +++++++++++++++ include/boost/type_traits/is_signed.hpp | 11 +- include/boost/type_traits/is_unsigned.hpp | 11 +- .../boost/type_traits/is_virtual_base_of.hpp | 42 +-- test/Jamfile.v2 | 15 +- test/add_lvalue_reference_test.cpp | 63 ++++ test/add_rvalue_reference_test.cpp | 80 ++++ test/aligned_storage_empy_test.cpp | 2 +- test/aligned_storage_test.cpp | 6 +- ...f_test_a2.cpp => alignment_of_a2_test.cpp} | 15 +- test/alignment_of_test.cpp | 12 + test/common_type_fail.cpp | 28 ++ test/common_type_test.cpp | 107 ++++++ test/conditional_test.cpp | 31 ++ test/decay_test.cpp | 7 + test/has_operator_new_test.cpp | 7 + test/is_abstract_test.cpp | 96 ++--- test/is_convertible_test.cpp | 7 +- test/is_member_func_test.cpp | 3 + test/is_virtual_base_of_test.cpp | 15 + test/promote_enum_msvc_bug_test.cpp | 5 + test/promote_enum_test.cpp | 5 + test/test.hpp | 47 ++- test/type_traits_test.cpp | 103 ++++++ 71 files changed, 2584 insertions(+), 170 deletions(-) create mode 100644 doc/add_lvalue_reference.qbk create mode 100644 doc/add_rvalue_reference.qbk create mode 100644 doc/common_type.qbk create mode 100644 doc/conditional.qbk create mode 100644 doc/html/boost_typetraits/examples/improved_min.html create mode 100644 doc/html/boost_typetraits/reference/add_lvalue_reference.html create mode 100644 doc/html/boost_typetraits/reference/add_rvalue_reference.html create mode 100644 doc/html/boost_typetraits/reference/common_type.html create mode 100644 doc/html/boost_typetraits/reference/common_type_hpp.html create mode 100644 include/boost/type_traits/add_lvalue_reference.hpp create mode 100644 include/boost/type_traits/add_rvalue_reference.hpp create mode 100644 include/boost/type_traits/common_type.hpp create mode 100644 include/boost/type_traits/conditional.hpp create mode 100644 include/boost/type_traits/detail/common_type_imp.hpp create mode 100644 test/add_lvalue_reference_test.cpp create mode 100644 test/add_rvalue_reference_test.cpp rename test/{alignment_of_test_a2.cpp => alignment_of_a2_test.cpp} (88%) create mode 100644 test/common_type_fail.cpp create mode 100644 test/common_type_test.cpp create mode 100644 test/conditional_test.cpp mode change 100755 => 100644 test/promote_enum_test.cpp create mode 100644 test/type_traits_test.cpp diff --git a/doc/add_lvalue_reference.qbk b/doc/add_lvalue_reference.qbk new file mode 100644 index 0000000..4416816 --- /dev/null +++ b/doc/add_lvalue_reference.qbk @@ -0,0 +1,47 @@ +[/ + Copyright 2010 John Maddock. + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt). +] + +[section:add_lvalue_reference add_lvalue_reference] + + template + struct add_lvalue_reference + { + typedef __below type; + }; + +__type If `T` names an object or function type then the member typedef `type` +shall name `T&`; otherwise, if `T` names a type ['rvalue reference to U] then +the member typedef type shall name `U&`; otherwise, type shall name `T`. + +__std_ref 20.7.6.2. + +__compat If the compiler does not support partial specialization of class-templates +then this template will compile, but the member `type` will always be the same as +type `T` except where __transform_workaround have been applied. + +__header ` #include ` or ` #include ` + +[table Examples + +[ [Expression] [Result Type]] + +[[`add_lvalue_reference::type`][`int&`]] + +[[`add_lvalue_reference::type`] [`int const&`]] + +[[`add_lvalue_reference::type`] [`int*&`]] + +[[`add_lvalue_reference::type`] [`int*&`]] + +[[`add_lvalue_reference::type`][`int&`]] + +[[`add_lvalue_reference::type`][`void`]] + +] + +[endsect] + diff --git a/doc/add_reference.qbk b/doc/add_reference.qbk index fd37bd6..a36e59d 100644 --- a/doc/add_reference.qbk +++ b/doc/add_reference.qbk @@ -7,6 +7,12 @@ [section:add_reference add_reference] +[note This trait has been made obsolete by __add_lvalue_reference and __add_rvalue_reference, +and new code should use these new traits rather than __is_reference which is retained +for backwards compatibility only. +] + + template struct add_reference { diff --git a/doc/add_rvalue_reference.qbk b/doc/add_rvalue_reference.qbk new file mode 100644 index 0000000..e3f561b --- /dev/null +++ b/doc/add_rvalue_reference.qbk @@ -0,0 +1,50 @@ +[/ + Copyright 2010 John Maddock. + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt). +] + +[section:add_rvalue_reference add_rvalue_reference] + + template + struct add_rvalue_reference + { + typedef __below type; + }; + +__type If `T` names an object or function type then the member typedef type +shall name `T&&`; otherwise, type shall name `T`. ['\[Note: This rule reflects +the semantics of reference collapsing. For example, when a type `T` names +a type U&, the type `add_rvalue_reference::type` is not an rvalue +reference. -end note\]]. + +__std_ref 20.7.6.2. + +__compat If the compiler does not support partial specialization of class-templates +and rvalue references +then this template will compile, but the member `type` will always be the same as +type `T`. + +__header ` #include ` or ` #include ` + +[table Examples + +[ [Expression] [Result Type]] + +[[`add_rvalue_reference::type`][`int&&`]] + +[[`add_rvalue_reference::type`] [`int const&`]] + +[[`add_rvalue_reference::type`] [`int*&&`]] + +[[`add_rvalue_reference::type`] [`int*&`]] + +[[`add_rvalue_reference::type`][`int&&`]] + +[[`add_rvalue_reference::type`][`void`]] + +] + +[endsect] + diff --git a/doc/common_type.qbk b/doc/common_type.qbk new file mode 100644 index 0000000..71cfbf6 --- /dev/null +++ b/doc/common_type.qbk @@ -0,0 +1,219 @@ + +[/===================================================================] +[section:common_type common_type] +[/===================================================================] + +[def __declval [@../../../utility/doc/html/declval.html declval]] + + +`#include ` + + namespace boost { + template struct __common_type; + } + + +__common_type is a traits class used to deduce a type common to a several types, useful as the return type of functions +operating on multiple input types such as in mixed-mode arithmetic.. + +The nested typedef `::type` could be defined as follows: + + template + struct common_type; + + template + struct common_type { + typedef typename __common_type::type, V...>::type type; + }; + + template + struct common_type { + typedef T type; + }; + + template + struct common_type { + typedef decltype(__declval() ? __declval() : __declval()) type; + }; + +All parameter types must be complete. This trait is permitted to be specialized by a user if at least one +template parameter is a user-defined type. [*Note:] Such specializations are required when only explicit conversions +are desired among the __common_type arguments. + +Note that when the compiler does not support variadic templates (and the macro BOOST_NO_VARIADIC_TEMPLATES is defined) +then the maximum number of template arguments is 3. + + +[h4 Configuration macros] + +When the compiler does not support static assertions then the user can select the way static assertions are reported. Define + +* BOOST_COMMON_TYPE_USES_STATIC_ASSERT: define it if you want to use Boost.StaticAssert +* BOOST_COMMON_TYPE_USES_MPL_ASSERT: define it if you want to use Boost.MPL static asertions + +The default behavior is to use mpl assertions in this case, but setting BOOST_COMMON_TYPE_USES_STATIC_ASSERT may reduce +compile times and header dependencies somewhat. + +Depending on the static assertion used you will have an hint of the failing assertion either through the symbol or through the text. + +When possible common_type is implemented using `decltype`. Otherwise when BOOST_COMMON_TYPE_DONT_USE_TYPEOF is not defined +it uses Boost.TypeOf. + +[h4 Tutorial] + +In a nutshell, __common_type is a trait that takes 1 or more types, and returns a type which +all of the types will convert to. The default definition demands this conversion be implicit. +However the trait can be specialized for user-defined types which want to limit their inter-type conversions to explicit, +and yet still want to interoperate with the __common_type facility. + +[*Example:] + + template + complex::type> + operator+(complex, complex); + + +In the above example, "mixed-mode" complex arithmetic is allowed. The return type is described by __common_type. +For example the resulting type of adding a `complex` and `complex` might be a `complex`. + +Here is how someone might produce a variadic comparison function: + + template + typename __common_type::type + min(T... t); + +This is a very useful and broadly applicable utility. + +[h4 How to get the common type of types with explicit conversions?] + +Another choice for the author of the preceding operator could be + + template + typename __common_type, complex >::type + operator+(complex, complex); + +As the default definition of __common_type demands the conversion be implicit, we need to specialize the trait for complex types as follows. + + template + struct __common_type, complex > { + typedef complex< __common_type > type; + }; + +[h4 How important is the order of the common_type<> template arguments?] + +The order of the template parameters is important. + +`common_type::type` is not equivalent to `common_type::type`, but to `common_type::type, C>::type`. + +Consider + + struct A {}; + struct B {}; + struct C { + C() {} + C(A const&) {} + C(B const&) {} + C& operator=(C const&) { + return *this; + } + }; + +The following doesn't compile + + typedef boost::common_type::type ABC; // Does not compile + +while + + typedef boost::common_type::type ABC; + +compiles. + +Thus, as `common_type::type` is undefined, `common_type::type` is also undefined. + +It is intended that clients who wish for `common_type` to be well +defined to define it themselves: + + namespace boost + { + + template <> + struct common_type {typedef C type;}; + + } + +Now this client can ask for `common_type` (and get +the same answer). + +Clients wanting to ask `common_type` in any order and get the same result need to add in addition: + + namespace boost + { + + template <> struct common_type + : public common_type {}; + + } + +This is needed as the specialization of `common_type` is not be used implicitly for `common_type`. + +[h4 Can the common_type of two types be a third type?] + +Given the preceding example, one might expect `common_type::type` to be `C` without any intervention from the user. +But the default `common_type<>` implementation doesn't grant that. It is intended that clients who wish for `common_type` +to be well defined to define it themselves: + + namespace boost + { + + template <> + struct common_type {typedef C type;}; + + template <> struct common_type + : public common_type {}; + + } + +Now this client can ask for `common_type`. + +[h4 How common_type behaves with pointers?] + +Consider + + struct C { }: + struct B : C { }; + struct A : C { }; + + +Shouldn't `common_type::type` be `C*`? I would say yes, but the default implementation will make it ill-formed. + +The library could add a specialization for pointers, as + + namespace boost + { + + template + struct common_type { + typedef common_type* type; + }; + } + +But in the absence of a motivating use cases, we prefer not to add more than the standard specifies. + +Of course the user can always make this specialization. + +[h4 Can you explain the pros/cons of common_type against Boost.Typeof?] + +Even if they appear to be close, `__common_type` and `typeof` have +different purposes. You use `typeof` to get the type of an expression, while +you use __common_type to set explicitly the type returned of a template +function. Both are complementary, and indeed __common_type is equivalent to +`decltype(__declval() ? __declval() : __declval())` + +__common_type is also similar to promote_args in boost/math/tools/promotion.hpp, +though it is not exactly the same as promote_args either. __common_type::type simply represents the result of some +operation on T1 and T2, and defaults to the type obtained by putting T1 and T2 into a conditional statement. + +It is meant to be customizable (via specialization) if this default is not appropriate. + +[endsect] + diff --git a/doc/conditional.qbk b/doc/conditional.qbk new file mode 100644 index 0000000..317bf53 --- /dev/null +++ b/doc/conditional.qbk @@ -0,0 +1,18 @@ + +[/===================================================================] +[section:conditional conditional] +[/===================================================================] + + +`#include ` + + namespace boost { + template struct __conditional; + } + +If B is true, the member typedef type shall equal T. If B is false, the member typedef type shall equal F. + +This trait is really just an alias for `boost::mpl::if_c`. + +[endsect] + diff --git a/doc/examples.qbk b/doc/examples.qbk index ccab2ae..fdcfb74 100644 --- a/doc/examples.qbk +++ b/doc/examples.qbk @@ -216,5 +216,22 @@ and enum types to double: [endsect] +[section:improved_min Improving std::min with common_type] + +An improved `std::min` function could be written like this: + + template + typename __common_type::type min(T t, T u) + { + return t < u ? t : u; + } + +And now expressions such as: + + min(1, 2.0) + +will actually compile and return the correct type! + +[endsect] [endsect] diff --git a/doc/history.qbk b/doc/history.qbk index 6606188..43ff333 100644 --- a/doc/history.qbk +++ b/doc/history.qbk @@ -7,6 +7,11 @@ [section:history History] +[h4 Boost 1.45.0] + +* Added new traits __add_rvalue_reference, __add_lvalue_reference and __common_type. +* Minor fixes to __is_signed, __is_unsigned and __is_virtual_base_of. + [h4 Boost 1.44.0] * Added support for rvalue references throughout the library, plus two new traits classes diff --git a/doc/html/boost_typetraits/background.html b/doc/html/boost_typetraits/background.html index cb8e3e2..5565563 100644 --- a/doc/html/boost_typetraits/background.html +++ b/doc/html/boost_typetraits/background.html @@ -56,7 +56,7 @@ method available to them.

- + Type Traits

@@ -84,7 +84,7 @@ given.

- + Implementation

@@ -174,7 +174,7 @@ in the default template.

- + Optimized copy

@@ -247,7 +247,7 @@ otherwise it will call the "slow but safe version".

- + Was it worth it?

@@ -280,7 +280,7 @@

-

Table 1.1. Time taken to copy 1000 elements using `copy<const T*, T*>` (times +

Table 1.1. Time taken to copy 1000 elements using `copy<const T*, T*>` (times in micro-seconds)

@@ -379,7 +379,7 @@

- + Pair of References

@@ -416,7 +416,7 @@ to hold non-reference types, references, and constant references:

-

Table 1.2. Required Constructor Argument Types

+

Table 1.2. Required Constructor Argument Types

@@ -481,7 +481,7 @@ adds a reference to its type, unless it is already a reference.

-

Table 1.3. Using add_reference to synthesize the correct constructor type

+

Table 1.3. Using add_reference to synthesize the correct constructor type

@@ -597,7 +597,7 @@ easier to maintain and easier to understand.

- + Conclusion

@@ -610,7 +610,7 @@ can be optimal as well as generic.

- + Acknowledgements

@@ -618,7 +618,7 @@ comments when preparing this article.

- + References
    diff --git a/doc/html/boost_typetraits/category/transform.html b/doc/html/boost_typetraits/category/transform.html index eb81b03..beec807 100644 --- a/doc/html/boost_typetraits/category/transform.html +++ b/doc/html/boost_typetraits/category/transform.html @@ -42,15 +42,27 @@ template <class T> struct add_cv; +template <class T> +struct add_lvalue_reference; + template <class T> struct add_pointer; template <class T> struct add_reference; +template <class T> +struct add_rvalue_reference; + template <class T> struct add_volatile; +template <bool B, class T, class U> +struct conditional; + +template <class... T> +struct common_type; + template <class T> struct decay; @@ -91,7 +103,7 @@ struct remove_volatile;
    - + Broken Compiler Workarounds:
    diff --git a/doc/html/boost_typetraits/examples.html b/doc/html/boost_typetraits/examples.html index 71ac2ef..938122c 100644 --- a/doc/html/boost_typetraits/examples.html +++ b/doc/html/boost_typetraits/examples.html @@ -37,6 +37,8 @@ of std::iter_swap
    Convert Numeric Types and Enums to double
    +
    Improving std::min + with common_type
diff --git a/doc/html/boost_typetraits/examples/improved_min.html b/doc/html/boost_typetraits/examples/improved_min.html new file mode 100644 index 0000000..c5451f6 --- /dev/null +++ b/doc/html/boost_typetraits/examples/improved_min.html @@ -0,0 +1,64 @@ + + + +Improving std::min with common_type + + + + + + + + +
+ + + + + + +
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ +

+ An improved std::min function could be written like this: +

+
template <class T, class U>
+typename common_type<T, U>::type min(T t, T u)
+{
+   return t < u ? t : u;
+}
+
+

+ And now expressions such as: +

+
min(1, 2.0)
+
+

+ will actually compile and return the correct type! +

+
+ + + +
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/boost_typetraits/examples/to_double.html b/doc/html/boost_typetraits/examples/to_double.html index 9aaa1d1..2365cc2 100644 --- a/doc/html/boost_typetraits/examples/to_double.html +++ b/doc/html/boost_typetraits/examples/to_double.html @@ -7,7 +7,7 @@ - + @@ -20,7 +20,7 @@

-PrevUpHomeNext +PrevUpHomeNext

@@ -52,7 +52,7 @@
-PrevUpHomeNext +PrevUpHomeNext
diff --git a/doc/html/boost_typetraits/history.html b/doc/html/boost_typetraits/history.html index d1923ff..de165fb 100644 --- a/doc/html/boost_typetraits/history.html +++ b/doc/html/boost_typetraits/history.html @@ -26,8 +26,24 @@ +

+ + Boost 1.45.0 +
+
- + Boost 1.44.0
    @@ -43,7 +59,7 @@
- + Boost 1.42.0