forked from boostorg/type_traits
Merge pull request #14 from boostorg/feature/copy_cv_doc
Add copy_cv documentation.
This commit is contained in:
@ -11,83 +11,73 @@
|
||||
[section:common_type common_type]
|
||||
[/===================================================================]
|
||||
|
||||
[def __declval [@../../../utility/doc/html/declval.html declval]]
|
||||
|
||||
|
||||
__header ` #include <boost/type_traits/common_type.hpp>` or ` #include <boost/type_traits.hpp>`
|
||||
|
||||
namespace boost {
|
||||
template <class ...T> struct __common_type;
|
||||
template <class... T> 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 <class ...T>
|
||||
template <class... T>
|
||||
struct common_type;
|
||||
|
||||
template <class T, class U, class ...V>
|
||||
struct common_type<T,U,...V> {
|
||||
typedef typename __common_type<typename __common_type<T, U>::type, V...>::type type;
|
||||
template <class T, class U, class... V>
|
||||
struct common_type<T, U, V...> {
|
||||
typedef typename common_type<typename common_type<T, U>::type, V...>::type type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct common_type<> {
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct common_type<T> {
|
||||
typedef T type;
|
||||
typedef typename __decay<T>::type type;
|
||||
};
|
||||
|
||||
template <class T, class U>
|
||||
struct common_type<T, U> {
|
||||
typedef decltype(__declval<bool>() ? __declval<T>() : __declval<U>()) type;
|
||||
typedef typename __decay<
|
||||
decltype( __declval<bool>()?
|
||||
__declval<typename __decay<T>::type>():
|
||||
__declval<typename __decay<U>::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 <class T, class U>
|
||||
complex<typename __common_type<T, U>::type>
|
||||
complex<typename common_type<T, U>::type>
|
||||
operator+(complex<T>, complex<U>);
|
||||
|
||||
|
||||
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<float>` and `complex<double>` might be a `complex<double>`.
|
||||
|
||||
Here is how someone might produce a variadic comparison function:
|
||||
|
||||
template <class ...T>
|
||||
typename __common_type<T...>::type
|
||||
typename common_type<T...>::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 <class T, class U>
|
||||
typename __common_type<complex<T>, complex<U> >::type
|
||||
typename common_type<complex<T>, complex<U> >::type
|
||||
operator+(complex<T>, complex<U>);
|
||||
|
||||
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 <class T, class U>
|
||||
struct __common_type<complex<T>, complex<U> > {
|
||||
typedef complex< __common_type<T, U> > type;
|
||||
struct common_type<complex<T>, complex<U> > {
|
||||
typedef complex< common_type<T, U> > 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<A, B, C>` in any order and get the same resu
|
||||
|
||||
This is needed as the specialization of `common_type<A, B>` is not be used implicitly for `common_type<B, A>`.
|
||||
|
||||
[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<A,B>::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<A, B>`
|
||||
@ -183,7 +173,7 @@ to be well defined to define it themselves:
|
||||
|
||||
Now this client can ask for `common_type<A, B>`.
|
||||
|
||||
[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<bool>() ? __declval<T>() : __declval<U>())`
|
||||
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<bool>() ? __declval<T>() : __declval<U>())`.
|
||||
|
||||
__common_type is also similar to promote_args<class ...T> in boost/math/tools/promotion.hpp,
|
||||
though it is not exactly the same as promote_args either. __common_type<T1, T2>::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<class ...T>` in `boost/math/tools/promotion.hpp`,
|
||||
though it is not exactly the same as `promote_args` either. `common_type<T1, T2>::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.
|
||||
|
||||
|
39
doc/copy_cv.qbk
Normal file
39
doc/copy_cv.qbk
Normal file
@ -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 <class T, class U>
|
||||
struct copy_cv
|
||||
{
|
||||
typedef __below type;
|
||||
};
|
||||
|
||||
__type [^T /cv/], where /cv/ are the cv-qualifiers of `U`.
|
||||
|
||||
__header ` #include <boost/type_traits/copy_cv.hpp>` or ` #include <boost/type_traits.hpp>`
|
||||
|
||||
[table Examples
|
||||
|
||||
[ [Expression] [Result Type]]
|
||||
|
||||
[[`copy_cv<int, void>::type`][`int`]]
|
||||
|
||||
[[`copy_cv<int const, void>::type`][`int const`]]
|
||||
|
||||
[[`copy_cv<int, void const>::type`][`int const`]]
|
||||
|
||||
[[`copy_cv<int volatile, void const>::type`][`int const volatile`]]
|
||||
|
||||
[[`copy_cv<int&, void const>::type`] [`int&`]]
|
||||
|
||||
[[`copy_cv<int*, void volatile>::type`] [`int* volatile`]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
120
doc/declval.qbk
120
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 <class T>
|
||||
typename add_rvalue_reference<T>::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<class T>
|
||||
T&& declval(); // not used
|
||||
|
||||
as part of the function template declaration
|
||||
__header ` #include <boost/type_traits/declval.hpp>` or ` #include <boost/type_traits.hpp>`
|
||||
|
||||
template<class To, class From>
|
||||
decltype(static_cast<To>(declval<From>())) convert(From&&);
|
||||
|
||||
or as part of a class template definition
|
||||
|
||||
template<class> class result_of;
|
||||
|
||||
template<class Fn, class... ArgTypes>
|
||||
struct result_of<Fn(ArgTypes...)>
|
||||
{
|
||||
typedef decltype(declval<Fn>()(declval<ArgTypes>()...)) 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<T>()` 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<class T>
|
||||
typename std::add_rvalue_reference<T>::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<int>() + declval<float>() )`.
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
[/=================]
|
||||
[section:reference Reference ]
|
||||
[/=================]
|
||||
|
||||
`#include <boost/utility/declval.hpp>`
|
||||
|
||||
namespace boost {
|
||||
|
||||
template <typename T>
|
||||
typename add_rvalue_reference<T>::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 T>
|
||||
typename add_rvalue_reference<T>::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 <class To, class From>
|
||||
decltype(static_cast<To>(declval<From>())) 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]
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -41,6 +41,9 @@ result of applying the transformation to the template argument `T`.
|
||||
template <class... T>
|
||||
struct __common_type;
|
||||
|
||||
template <class T, class U>
|
||||
struct __copy_cv;
|
||||
|
||||
template <class T>
|
||||
struct __decay;
|
||||
|
||||
@ -80,6 +83,9 @@ result of applying the transformation to the template argument `T`.
|
||||
template <class T>
|
||||
struct __remove_volatile;
|
||||
|
||||
template <class T>
|
||||
struct __type_identity;
|
||||
|
||||
[h4 Broken Compiler Workarounds:]
|
||||
|
||||
For all of these templates support for partial specialization of class templates is
|
||||
|
31
doc/type_identity.qbk
Normal file
31
doc/type_identity.qbk
Normal file
@ -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 <class T>
|
||||
struct type_identity
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
__header ` #include <boost/type_traits/type_identity.hpp>` or ` #include <boost/type_traits.hpp>`
|
||||
|
||||
[table Examples
|
||||
|
||||
[ [Expression] [Result Type]]
|
||||
|
||||
[[`type_identity<int>::type`][`int`]]
|
||||
|
||||
[[`type_identity<int&>::type`] [`int&`]]
|
||||
|
||||
[[`type_identity<int* const&>::type`] [`int* const&`]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
@ -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]
|
||||
|
Reference in New Issue
Block a user