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. diff --git a/doc/copy_cv.qbk b/doc/copy_cv.qbk new file mode 100644 index 0000000..9f733a0 --- /dev/null +++ b/doc/copy_cv.qbk @@ -0,0 +1,39 @@ +[/ + Copyright 2015 Peter Dimov. + 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:copy_cv copy_cv] + + template + struct copy_cv + { + typedef __below type; + }; + +__type [^T /cv/], where /cv/ are the cv-qualifiers of `U`. + +__header ` #include ` or ` #include ` + +[table Examples + +[ [Expression] [Result Type]] + +[[`copy_cv::type`][`int`]] + +[[`copy_cv::type`][`int const`]] + +[[`copy_cv::type`][`int const`]] + +[[`copy_cv::type`][`int const volatile`]] + +[[`copy_cv::type`] [`int&`]] + +[[`copy_cv::type`] [`int* volatile`]] + +] + +[endsect] + diff --git a/doc/declval.qbk b/doc/declval.qbk index 7bf5cb5..7b151ae 100644 --- a/doc/declval.qbk +++ b/doc/declval.qbk @@ -1,115 +1,21 @@ -[/ - / Copyright (c) 2008 Howard Hinnant - / Copyright (c) 2009-20012 Vicente J. Botet Escriba - / - / 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) - /] - -[article Declval - [quickbook 1.5] - [authors [Hinnant, Howard]] - [authors [Botet Escriba, Vicente J.]] - [copyright 2008 Howard Hinnant] - [copyright 2009-2012 Vicente J. Botet Escriba] - [license - 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]) - ] +[/ + Copyright 2015 Peter Dimov. + 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 Overview] -[/===============] +[section:declval declval] -The motivation for `declval` was introduced in [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2958.html#Value N2958: -Moving Swap Forward]. Here follows a rewording of this chapter. + template + typename add_rvalue_reference::type declval() noexcept; // as unevaluated operand -With the provision of decltype, late-specified return types, and default template-arguments for function templates a -new generation of SFINAE patterns will emerge to at least partially compensate the lack of concepts on the C++0x timescale. -Using this technique, it is sometimes necessary to obtain an object of a known type in a non-using context, e.g. given the declaration +__std_ref C++11 20.2.4 [declval]. - template - T&& declval(); // not used - -as part of the function template declaration +__header ` #include ` or ` #include ` - template - decltype(static_cast(declval())) convert(From&&); - -or as part of a class template definition - - template class result_of; - - template - struct result_of - { - typedef decltype(declval()(declval()...)) type; - }; - -The role of the function template declval() is a transformation of a type T into a value without using or evaluating this function. -The name is supposed to direct the reader's attention to the fact that the expression `declval()` is an lvalue if and only if -T is an lvalue-reference, otherwise an rvalue. To extend the domain of this function we can do a bit better by changing its declaration to - - template - typename std::add_rvalue_reference::type declval(); // not used - -which ensures that we can also use cv void as template parameter. The careful reader might have noticed that `declval()` -already exists under the name create() as part of the definition of the semantics of the type trait is_convertible in the C++0x standard. - -The provision of a new library component that allows the production of values in unevaluated expressions is considered -important to realize constrained templates in C++0x where concepts are not available. -This extremely light-weight function is expected to be part of the daily tool-box of the C++0x programmer. +The function template `declval` is used when a value of a certain type is required in +a type computation context. For example, the type of the result of adding an `int` and +a `float` can be obtained with the expression `decltype( declval() + declval() )`. [endsect] - - -[/=================] -[section:reference Reference ] -[/=================] - -`#include ` - - namespace boost { - - template - typename add_rvalue_reference::type declval() noexcept; // as unevaluated operand - - } // namespace boost - - -The library provides the function template declval to simplify the definition of expressions which occur as unevaluated operands. - - template - typename add_rvalue_reference::type declval(); - -[*Remarks:] If this function is used, the program is ill-formed. - -[*Remarks:] The template parameter T of declval may be an incomplete type. - -[*Example:] - - template - decltype(static_cast(declval())) convert(From&&); - -Declares a function template convert which only participates in overloading if the type From can be explicitly converted to type To. - -[endsect] - -[/===============] -[section History] -[/===============] - -[heading boost 1.50] - -Fixes: - -* [@http://svn.boost.org/trac/boost/ticket/6570 #6570] Adding noexcept to boost::declval. - - -[endsect] - - - - diff --git a/doc/transform_traits.qbk b/doc/transform_traits.qbk index 980ebe4..321a06a 100644 --- a/doc/transform_traits.qbk +++ b/doc/transform_traits.qbk @@ -41,6 +41,9 @@ result of applying the transformation to the template argument `T`. template struct __common_type; + template + struct __copy_cv; + template struct __decay; @@ -80,6 +83,9 @@ result of applying the transformation to the template argument `T`. template struct __remove_volatile; + template + struct __type_identity; + [h4 Broken Compiler Workarounds:] For all of these templates support for partial specialization of class templates is diff --git a/doc/type_identity.qbk b/doc/type_identity.qbk new file mode 100644 index 0000000..975653d --- /dev/null +++ b/doc/type_identity.qbk @@ -0,0 +1,31 @@ +[/ + Copyright 2015 Peter Dimov. + 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:type_identity type_identity] + + template + struct type_identity + { + typedef T type; + }; + +__header ` #include ` or ` #include ` + +[table Examples + +[ [Expression] [Result Type]] + +[[`type_identity::type`][`int`]] + +[[`type_identity::type`] [`int&`]] + +[[`type_identity::type`] [`int* const&`]] + +] + +[endsect] + diff --git a/doc/type_traits.qbk b/doc/type_traits.qbk index 3965809..c0046a1 100644 --- a/doc/type_traits.qbk +++ b/doc/type_traits.qbk @@ -132,6 +132,10 @@ [def __decay [link boost_typetraits.reference.decay decay]] [def __is_complex [link boost_typetraits.reference.is_complex is_complex]] +[def __copy_cv [link boost_typetraits.reference.copy_cv copy_cv]] +[def __type_identity [link boost_typetraits.reference.type_identity type_identity]] +[def __declval [link boost_typetraits.reference.declval declval]] + A printer-friendly [@http://sourceforge.net/projects/boost/files/boost-docs/ PDF version of this manual is also available]. @@ -183,7 +187,9 @@ that is the result of the transformation. [include alignment_of.qbk] [include conditional.qbk] [include common_type.qbk] +[include copy_cv.qbk] [include decay.qbk] +[include declval.qbk] [include extent.qbk] [include floating_point_promotion.qbk] [include function_traits.qbk] @@ -306,6 +312,7 @@ See __has_trivial_constructor. [include remove_pointer.qbk] [include remove_reference.qbk] [include remove_volatile.qbk] +[include type_identity.qbk] [include type_with_alignment.qbk] [endsect]