From 2180399398816e2223a8b669c82685c3a66474a4 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Mon, 8 Jun 2015 00:39:05 +0300 Subject: [PATCH] Update documentation of common_type a bit. --- doc/common_type.qbk | 88 ++++++++++++++++++++------------------------- 1 file changed, 39 insertions(+), 49 deletions(-) diff --git a/doc/common_type.qbk b/doc/common_type.qbk index a34b9bb..801033f 100644 --- a/doc/common_type.qbk +++ b/doc/common_type.qbk @@ -11,83 +11,73 @@ [section:common_type common_type] [/===================================================================] -[def __declval [@../../../utility/doc/html/declval.html declval]] - - __header ` #include ` or ` #include ` namespace boost { - template struct __common_type; + 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 +`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 + template struct common_type; - template - struct common_type { - typedef typename __common_type::type, V...>::type type; + template + struct common_type { + typedef typename common_type::type, V...>::type type; + }; + + template <> + struct common_type<> { }; template struct common_type { - typedef T type; + typedef typename __decay::type type; }; template struct common_type { - typedef decltype(__declval() ? __declval() : __declval()) type; + typedef typename __decay< + decltype( __declval()? + __declval::type>(): + __declval::type>() ) + >::type 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. +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. +Note that when the compiler does not support variadic templates (and the macro `BOOST_NO_CXX11_VARIADIC_TEMPLATES` is defined) +then the maximum number of template arguments is 9. -[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 assertions - -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 +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. +and yet still want to interoperate with the `common_type` facility. [*Example:] template - complex::type> + complex::type> operator+(complex, complex); -In the above example, "mixed-mode" complex arithmetic is allowed. The return type is described by __common_type. +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 + typename common_type::type min(T... t); This is a very useful and broadly applicable utility. @@ -97,17 +87,17 @@ This is a very useful and broadly applicable utility. Another choice for the author of the preceding operator could be template - typename __common_type, complex >::type + 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. +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; + struct common_type, complex > { + typedef complex< common_type > type; }; -[h4 How important is the order of the common_type<> template arguments?] +[h4 How important is the order of the `common_type<>` template arguments?] The order of the template parameters is important. @@ -164,7 +154,7 @@ Clients wanting to ask `common_type` in any order and get the same resu 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?] +[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` @@ -183,7 +173,7 @@ to be well defined to define it themselves: Now this client can ask for `common_type`. -[h4 How common_type behaves with pointers?] +[h4 How does `common_type` behave with pointers?] Consider @@ -209,17 +199,17 @@ But in the absence of a motivating use cases, we prefer not to add more than the Of course the user can always make this specialization. -[h4 Can you explain the pros/cons of common_type against Boost.Typeof?] +[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 +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())` +you use `common_type` to set explicitly the type returned of a template +function. Both are complementary, and indeed `common_type` is approximately 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. +`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.