forked from boostorg/type_traits
Merge branch 'develop' of https://github.com/boostorg/type_traits into develop
Resolved Conflicts: doc/transform_traits.qbk doc/type_traits.qbk
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,5 +83,8 @@ result of applying the transformation to the template argument `T`.
|
||||
template <class T>
|
||||
struct __remove_volatile;
|
||||
|
||||
template <class T>
|
||||
struct __type_identity;
|
||||
|
||||
[endsect]
|
||||
|
||||
|
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]]
|
||||
|
||||
[def __compat [*Compiler Compatibility:]]
|
||||
[template all_compilers[] __compat All current compilers are supported by this trait.]
|
||||
[template has_binary_operator_compat[] __compat Requires working SFINAE (i.e. BOOST_NO_SFINAE is not set). Only a minority of rather old compilers do not support this.]
|
||||
@ -188,7 +192,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]
|
||||
@ -311,6 +317,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]
|
||||
|
@ -21,7 +21,9 @@
|
||||
#include "boost/type_traits/alignment_of.hpp"
|
||||
#include "boost/type_traits/common_type.hpp"
|
||||
#include "boost/type_traits/conditional.hpp"
|
||||
#include "boost/type_traits/copy_cv.hpp"
|
||||
#include "boost/type_traits/decay.hpp"
|
||||
#include "boost/type_traits/declval.hpp"
|
||||
#include "boost/type_traits/extent.hpp"
|
||||
#include "boost/type_traits/floating_point_promotion.hpp"
|
||||
#include "boost/type_traits/function_traits.hpp"
|
||||
@ -93,6 +95,7 @@
|
||||
#include "boost/type_traits/remove_pointer.hpp"
|
||||
#include "boost/type_traits/remove_reference.hpp"
|
||||
#include "boost/type_traits/remove_volatile.hpp"
|
||||
#include "boost/type_traits/type_identity.hpp"
|
||||
#include "boost/type_traits/type_with_alignment.hpp"
|
||||
#if !(defined(__sgi) && defined(__EDG_VERSION__) && (__EDG_VERSION__ == 238))
|
||||
#include "boost/type_traits/integral_promotion.hpp"
|
||||
|
@ -1,163 +1,88 @@
|
||||
// common_type.hpp ---------------------------------------------------------//
|
||||
|
||||
// Copyright 2008 Howard Hinnant
|
||||
// Copyright 2008 Beman Dawes
|
||||
#ifndef BOOST_TYPE_TRAITS_COMMON_TYPE_HPP_INCLUDED
|
||||
#define BOOST_TYPE_TRAITS_COMMON_TYPE_HPP_INCLUDED
|
||||
|
||||
//
|
||||
// Copyright 2015 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#ifndef BOOST_TYPE_TRAITS_COMMON_TYPE_HPP
|
||||
#define BOOST_TYPE_TRAITS_COMMON_TYPE_HPP
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
//
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
#if defined(__SUNPRO_CC) && !defined(BOOST_COMMON_TYPE_DONT_USE_TYPEOF)
|
||||
# define BOOST_COMMON_TYPE_DONT_USE_TYPEOF
|
||||
#endif
|
||||
#if defined(__IBMCPP__) && !defined(BOOST_COMMON_TYPE_DONT_USE_TYPEOF)
|
||||
# define BOOST_COMMON_TYPE_DONT_USE_TYPEOF
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) && !defined(BOOST_COMMON_TYPE_DONT_USE_TYPEOF)
|
||||
// All supported GCC versions (and emulations thereof) support __typeof__
|
||||
#define BOOST_COMMON_TYPE_USE_TYPEOF
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_COMMON_TYPE_ARITY)
|
||||
#define BOOST_COMMON_TYPE_ARITY 3
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
#if !defined(BOOST_NO_CXX11_DECLTYPE)
|
||||
#include <boost/utility/declval.hpp>
|
||||
#elif defined(BOOST_COMMON_TYPE_USE_TYPEOF)
|
||||
#include <boost/type_traits/add_rvalue_reference.hpp>
|
||||
#elif defined(BOOST_COMMON_TYPE_DONT_USE_TYPEOF)
|
||||
#include <boost/type_traits/remove_cv.hpp>
|
||||
#include <boost/type_traits/detail/common_type_imp.hpp>
|
||||
#else
|
||||
#include <boost/typeof/typeof.hpp> // boost wonders never cease!
|
||||
#include <boost/type_traits/detail/common_type_imp.hpp>
|
||||
#include <boost/type_traits/add_rvalue_reference.hpp>
|
||||
#endif
|
||||
|
||||
#include <boost/type_traits/remove_cv.hpp>
|
||||
#include <boost/type_traits/decay.hpp>
|
||||
#include <boost/type_traits/declval.hpp>
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
// //
|
||||
// C++03 implementation of //
|
||||
// 20.9.7.6 Other transformations [meta.trans.other] //
|
||||
// Written by Howard Hinnant //
|
||||
// Adapted for Boost by Beman Dawes, Vicente Botet and Jeffrey Hellrung //
|
||||
// //
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace type_traits_detail {
|
||||
|
||||
template <class T>
|
||||
struct std_decay: boost::remove_cv<
|
||||
typename boost::decay<T>::type> {};
|
||||
|
||||
}
|
||||
|
||||
// prototype
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
template<typename... T>
|
||||
struct common_type;
|
||||
#else // or no specialization
|
||||
template <class T, class U = void, class V = void>
|
||||
struct common_type
|
||||
{
|
||||
public:
|
||||
typedef typename common_type<typename common_type<T, U>::type, V>::type type;
|
||||
};
|
||||
#if defined(BOOST_NO_CXX11_DECLTYPE)
|
||||
#include <boost/type_traits/detail/common_type_impl.hpp>
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
// variadic common_type
|
||||
|
||||
// 1 arg
|
||||
template<typename T>
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
struct common_type<T>
|
||||
|
||||
template<class... T> struct common_type
|
||||
{
|
||||
};
|
||||
|
||||
template<class T1, class T2, class... T>
|
||||
struct common_type<T1, T2, T...>: common_type<typename common_type<T1, T2>::type, T...>
|
||||
{
|
||||
};
|
||||
|
||||
#else
|
||||
struct common_type<T, void, void>
|
||||
|
||||
#endif
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(sizeof(T) > 0, "The template arguments to common_type must be complete types");
|
||||
public:
|
||||
typedef typename type_traits_detail::std_decay<T>::type type;
|
||||
};
|
||||
template<
|
||||
class T1 = void, class T2 = void, class T3 = void,
|
||||
class T4 = void, class T5 = void, class T6 = void,
|
||||
class T7 = void, class T8 = void, class T9 = void
|
||||
>
|
||||
struct common_type: common_type<typename common_type<T1, T2>::type, T3, T4, T5, T6, T7, T8, T9>
|
||||
{
|
||||
};
|
||||
|
||||
// 2 args
|
||||
namespace type_traits_detail {
|
||||
#endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
template <class T, class U>
|
||||
struct common_type_2
|
||||
{
|
||||
private:
|
||||
BOOST_STATIC_ASSERT_MSG(sizeof(T) > 0, "The template arguments to common_type must be complete types");
|
||||
BOOST_STATIC_ASSERT_MSG(sizeof(U) > 0, "The template arguments to common_type must be complete types");
|
||||
// one argument
|
||||
|
||||
template<class T> struct common_type<T>: boost::decay<T>
|
||||
{
|
||||
};
|
||||
|
||||
// two arguments
|
||||
|
||||
namespace type_traits_detail
|
||||
{
|
||||
|
||||
// binary common_type
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_DECLTYPE)
|
||||
public:
|
||||
typedef typename std_decay<decltype(declval<bool>() ? declval<T>() : declval<U>())>::type type;
|
||||
#elif defined(BOOST_COMMON_TYPE_USE_TYPEOF)
|
||||
static typename add_rvalue_reference<T>::type declval_T(); // workaround gcc bug; not required by std
|
||||
static typename add_rvalue_reference<U>::type declval_U(); // workaround gcc bug; not required by std
|
||||
static typename add_rvalue_reference<bool>::type declval_b();
|
||||
public:
|
||||
typedef typename std_decay<__typeof__(declval_b() ? declval_T() : declval_U())>::type type;
|
||||
#elif defined(BOOST_COMMON_TYPE_DONT_USE_TYPEOF)
|
||||
public:
|
||||
typedef typename detail_type_traits_common_type::common_type_impl<
|
||||
typename remove_cv<T>::type,
|
||||
typename remove_cv<U>::type
|
||||
>::type type;
|
||||
#else
|
||||
static typename add_rvalue_reference<T>::type declval_T(); // workaround gcc bug; not required by std
|
||||
static typename add_rvalue_reference<U>::type declval_U(); // workaround gcc bug; not required by std
|
||||
static typename add_rvalue_reference<bool>::type declval_b();
|
||||
public:
|
||||
typedef typename std_decay<BOOST_TYPEOF_TPL(declval_b() ? declval_T() : declval_U())>::type type;
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) && __GNUC__ == 3 && __GNUC_MINOR__ == 3
|
||||
public:
|
||||
void public_dummy_function_just_to_silence_warning();
|
||||
#endif
|
||||
};
|
||||
template<class T1, class T2> struct common_type_impl: boost::decay<decltype( boost::declval<bool>()? boost::declval<T1>(): boost::declval<T2>() )>
|
||||
{
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct common_type_2<T, T>
|
||||
{
|
||||
typedef typename type_traits_detail::std_decay<T>::type type;
|
||||
};
|
||||
}
|
||||
#endif // #if !defined(BOOST_NO_CXX11_DECLTYPE)
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
template <class T, class U>
|
||||
struct common_type<T, U>
|
||||
#else
|
||||
template <class T, class U>
|
||||
struct common_type<T, U, void>
|
||||
#endif
|
||||
: public type_traits_detail::common_type_2<T,U>
|
||||
{ };
|
||||
// decay helper
|
||||
|
||||
template<class T1, class T2, class T1d = typename boost::decay<T1>::type, class T2d = typename boost::decay<T2>::type> struct common_type_decay_helper: boost::common_type<T1d, T2d>
|
||||
{
|
||||
};
|
||||
|
||||
// 3 or more args
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
template<typename T, typename U, typename... V>
|
||||
struct common_type<T, U, V...> {
|
||||
public:
|
||||
typedef typename common_type<typename common_type<T, U>::type, V...>::type type;
|
||||
};
|
||||
#endif
|
||||
} // namespace boost
|
||||
template<class T1, class T2> struct common_type_decay_helper<T1, T2, T1, T2>: common_type_impl<T1, T2>
|
||||
{
|
||||
};
|
||||
|
||||
#endif // BOOST_TYPE_TRAITS_COMMON_TYPE_HPP
|
||||
} // type_traits_detail
|
||||
|
||||
template<class T1, class T2> struct common_type<T1, T2>: type_traits_detail::common_type_decay_helper<T1, T2>
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_TYPE_TRAITS_COMMON_TYPE_HPP_INCLUDED
|
||||
|
34
include/boost/type_traits/copy_cv.hpp
Normal file
34
include/boost/type_traits/copy_cv.hpp
Normal file
@ -0,0 +1,34 @@
|
||||
#ifndef BOOST_TYPE_TRAITS_COPY_CV_HPP_INCLUDED
|
||||
#define BOOST_TYPE_TRAITS_COPY_CV_HPP_INCLUDED
|
||||
|
||||
//
|
||||
// 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
|
||||
//
|
||||
|
||||
#include <boost/type_traits/is_const.hpp>
|
||||
#include <boost/type_traits/is_volatile.hpp>
|
||||
#include <boost/type_traits/add_const.hpp>
|
||||
#include <boost/type_traits/add_volatile.hpp>
|
||||
#include <boost/type_traits/conditional.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
template<class T, class U> struct copy_cv
|
||||
{
|
||||
private:
|
||||
|
||||
typedef typename boost::conditional<boost::is_const<U>::value, typename boost::add_const<T>::type, T>::type CT;
|
||||
|
||||
public:
|
||||
|
||||
typedef typename boost::conditional<boost::is_volatile<U>::value, typename boost::add_volatile<CT>::type, CT>::type type;
|
||||
};
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_TYPE_TRAITS_COPY_CV_HPP_INCLUDED
|
44
include/boost/type_traits/declval.hpp
Normal file
44
include/boost/type_traits/declval.hpp
Normal file
@ -0,0 +1,44 @@
|
||||
// declval.hpp -------------------------------------------------------------//
|
||||
|
||||
// Copyright 2010 Vicente J. Botet Escriba
|
||||
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#ifndef BOOST_TYPE_TRAITS_DECLVAL_HPP_INCLUDED
|
||||
#define BOOST_TYPE_TRAITS_DECLVAL_HPP_INCLUDED
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
#include <boost/type_traits/add_rvalue_reference.hpp>
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
// //
|
||||
// C++03 implementation of //
|
||||
// 20.2.4 Function template declval [declval] //
|
||||
// Written by Vicente J. Botet Escriba //
|
||||
// //
|
||||
// 1 The library provides the function template declval to simplify the
|
||||
// definition of expressions which occur as unevaluated operands.
|
||||
// 2 Remarks: If this function is used, the program is ill-formed.
|
||||
// 3 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. For another example
|
||||
// see class template common_type (20.9.7.6). -end example ]
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
namespace boost {
|
||||
|
||||
template <typename T>
|
||||
typename add_rvalue_reference<T>::type declval() BOOST_NOEXCEPT; // as unevaluated operand
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_TYPE_TRAITS_DECLVAL_HPP_INCLUDED
|
212
include/boost/type_traits/detail/common_arithmetic_type.hpp
Normal file
212
include/boost/type_traits/detail/common_arithmetic_type.hpp
Normal file
@ -0,0 +1,212 @@
|
||||
#ifndef BOOST_TYPE_TRAITS_DETAIL_COMMON_ARITHMETIC_TYPE_HPP_INCLUDED
|
||||
#define BOOST_TYPE_TRAITS_DETAIL_COMMON_ARITHMETIC_TYPE_HPP_INCLUDED
|
||||
|
||||
//
|
||||
// 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
|
||||
//
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace type_traits_detail
|
||||
{
|
||||
|
||||
template<int I> struct arithmetic_type;
|
||||
|
||||
// Types bool, char, char16_t, char32_t, wchar_t,
|
||||
// and the signed and unsigned integer types are
|
||||
// collectively called integral types
|
||||
|
||||
template<> struct arithmetic_type<1>
|
||||
{
|
||||
typedef bool type;
|
||||
typedef char (&result_type) [1];
|
||||
};
|
||||
|
||||
template<> struct arithmetic_type<2>
|
||||
{
|
||||
typedef char type;
|
||||
typedef char (&result_type) [2];
|
||||
};
|
||||
|
||||
template<> struct arithmetic_type<3>
|
||||
{
|
||||
typedef wchar_t type;
|
||||
typedef char (&result_type) [3];
|
||||
};
|
||||
|
||||
// There are five standard signed integer types:
|
||||
// “signed char”, “short int”, “int”, “long int”, and “long long int”.
|
||||
|
||||
template<> struct arithmetic_type<4>
|
||||
{
|
||||
typedef signed char type;
|
||||
typedef char (&result_type) [4];
|
||||
};
|
||||
|
||||
template<> struct arithmetic_type<5>
|
||||
{
|
||||
typedef short type;
|
||||
typedef char (&result_type) [5];
|
||||
};
|
||||
|
||||
template<> struct arithmetic_type<6>
|
||||
{
|
||||
typedef int type;
|
||||
typedef char (&result_type) [6];
|
||||
};
|
||||
|
||||
template<> struct arithmetic_type<7>
|
||||
{
|
||||
typedef long type;
|
||||
typedef char (&result_type) [7];
|
||||
};
|
||||
|
||||
template<> struct arithmetic_type<8>
|
||||
{
|
||||
typedef boost::long_long_type type;
|
||||
typedef char (&result_type) [8];
|
||||
};
|
||||
|
||||
// For each of the standard signed integer types, there exists a corresponding
|
||||
// (but different) standard unsigned integer type: “unsigned char”, “unsigned short int”,
|
||||
// “unsigned int”, “unsigned long int”, and “unsigned long long int”
|
||||
|
||||
template<> struct arithmetic_type<9>
|
||||
{
|
||||
typedef unsigned char type;
|
||||
typedef char (&result_type) [9];
|
||||
};
|
||||
|
||||
template<> struct arithmetic_type<10>
|
||||
{
|
||||
typedef unsigned short type;
|
||||
typedef char (&result_type) [10];
|
||||
};
|
||||
|
||||
template<> struct arithmetic_type<11>
|
||||
{
|
||||
typedef unsigned int type;
|
||||
typedef char (&result_type) [11];
|
||||
};
|
||||
|
||||
template<> struct arithmetic_type<12>
|
||||
{
|
||||
typedef unsigned long type;
|
||||
typedef char (&result_type) [12];
|
||||
};
|
||||
|
||||
template<> struct arithmetic_type<13>
|
||||
{
|
||||
typedef boost::ulong_long_type type;
|
||||
typedef char (&result_type) [13];
|
||||
};
|
||||
|
||||
// There are three floating point types: float, double, and long double.
|
||||
|
||||
template<> struct arithmetic_type<14>
|
||||
{
|
||||
typedef float type;
|
||||
typedef char (&result_type) [14];
|
||||
};
|
||||
|
||||
template<> struct arithmetic_type<15>
|
||||
{
|
||||
typedef double type;
|
||||
typedef char (&result_type) [15];
|
||||
};
|
||||
|
||||
template<> struct arithmetic_type<16>
|
||||
{
|
||||
typedef long double type;
|
||||
typedef char (&result_type) [16];
|
||||
};
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_CHAR16_T )
|
||||
|
||||
template<> struct arithmetic_type<17>
|
||||
{
|
||||
typedef char16_t type;
|
||||
typedef char (&result_type) [17];
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_CHAR32_T )
|
||||
|
||||
template<> struct arithmetic_type<18>
|
||||
{
|
||||
typedef char32_t type;
|
||||
typedef char (&result_type) [18];
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#if defined( BOOST_HAS_INT128 )
|
||||
|
||||
template<> struct arithmetic_type<19>
|
||||
{
|
||||
typedef boost::int128_type type;
|
||||
typedef char (&result_type) [19];
|
||||
};
|
||||
|
||||
template<> struct arithmetic_type<20>
|
||||
{
|
||||
typedef boost::uint128_type type;
|
||||
typedef char (&result_type) [20];
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
template<class T, class U> class common_arithmetic_type
|
||||
{
|
||||
private:
|
||||
|
||||
static arithmetic_type<1>::result_type select( arithmetic_type<1>::type );
|
||||
static arithmetic_type<2>::result_type select( arithmetic_type<2>::type );
|
||||
static arithmetic_type<3>::result_type select( arithmetic_type<3>::type );
|
||||
static arithmetic_type<4>::result_type select( arithmetic_type<4>::type );
|
||||
static arithmetic_type<5>::result_type select( arithmetic_type<5>::type );
|
||||
static arithmetic_type<6>::result_type select( arithmetic_type<6>::type );
|
||||
static arithmetic_type<7>::result_type select( arithmetic_type<7>::type );
|
||||
static arithmetic_type<8>::result_type select( arithmetic_type<8>::type );
|
||||
static arithmetic_type<9>::result_type select( arithmetic_type<9>::type );
|
||||
static arithmetic_type<10>::result_type select( arithmetic_type<10>::type );
|
||||
static arithmetic_type<11>::result_type select( arithmetic_type<11>::type );
|
||||
static arithmetic_type<12>::result_type select( arithmetic_type<12>::type );
|
||||
static arithmetic_type<13>::result_type select( arithmetic_type<13>::type );
|
||||
static arithmetic_type<14>::result_type select( arithmetic_type<14>::type );
|
||||
static arithmetic_type<15>::result_type select( arithmetic_type<15>::type );
|
||||
static arithmetic_type<16>::result_type select( arithmetic_type<16>::type );
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_CHAR16_T )
|
||||
static arithmetic_type<17>::result_type select( arithmetic_type<17>::type );
|
||||
#endif
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_CHAR32_T )
|
||||
static arithmetic_type<18>::result_type select( arithmetic_type<18>::type );
|
||||
#endif
|
||||
|
||||
#if defined( BOOST_HAS_INT128 )
|
||||
static arithmetic_type<19>::result_type select( arithmetic_type<19>::type );
|
||||
static arithmetic_type<20>::result_type select( arithmetic_type<20>::type );
|
||||
#endif
|
||||
|
||||
static bool cond();
|
||||
|
||||
public:
|
||||
|
||||
typedef typename arithmetic_type< sizeof(select( cond()? T(): U() )) >::type type;
|
||||
};
|
||||
|
||||
} // namespace type_traits_detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_TYPE_TRAITS_DETAIL_COMMON_ARITHMETIC_TYPE_HPP_INCLUDED
|
@ -1,333 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* boost/type_traits/detail/common_type_imp.hpp
|
||||
*
|
||||
* Copyright 2010, Jeffrey Hellrung.
|
||||
* 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)
|
||||
*
|
||||
* struct boost::common_type<T,U>
|
||||
*
|
||||
* common_type<T,U>::type is the type of the expression
|
||||
* b() ? x() : y()
|
||||
* where b() returns a bool, x() has return type T, and y() has return type U.
|
||||
* See
|
||||
* http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2661.htm#common_type
|
||||
*
|
||||
* Note that this evaluates to void if one or both of T and U is void.
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef BOOST_TYPE_TRAITS_DETAIL_COMMON_TYPE_IMP_HPP
|
||||
#define BOOST_TYPE_TRAITS_DETAIL_COMMON_TYPE_IMP_HPP
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/mpl/at.hpp>
|
||||
#include <boost/mpl/begin_end.hpp>
|
||||
#include <boost/mpl/contains.hpp>
|
||||
#include <boost/mpl/copy.hpp>
|
||||
#include <boost/mpl/deref.hpp>
|
||||
#include <boost/mpl/eval_if.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/mpl/inserter.hpp>
|
||||
#include <boost/mpl/next.hpp>
|
||||
#include <boost/mpl/or.hpp>
|
||||
#include <boost/mpl/placeholders.hpp>
|
||||
#include <boost/mpl/push_back.hpp>
|
||||
#include <boost/mpl/size.hpp>
|
||||
#include <boost/mpl/vector/vector0.hpp>
|
||||
#include <boost/mpl/vector/vector10.hpp>
|
||||
#include <boost/type_traits/integral_constant.hpp>
|
||||
#include <boost/type_traits/is_enum.hpp>
|
||||
#include <boost/type_traits/is_integral.hpp>
|
||||
#include <boost/type_traits/make_signed.hpp>
|
||||
#include <boost/type_traits/make_unsigned.hpp>
|
||||
#include <boost/type_traits/remove_cv.hpp>
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
#include <boost/utility/declval.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail_type_traits_common_type
|
||||
{
|
||||
|
||||
/*******************************************************************************
|
||||
* struct propagate_cv< From, To >
|
||||
*
|
||||
* This metafunction propagates cv-qualifiers on type From to type To.
|
||||
******************************************************************************/
|
||||
|
||||
template< class From, class To >
|
||||
struct propagate_cv
|
||||
{ typedef To type; };
|
||||
template< class From, class To >
|
||||
struct propagate_cv< const From, To >
|
||||
{ typedef To const type; };
|
||||
template< class From, class To >
|
||||
struct propagate_cv< volatile From, To >
|
||||
{ typedef To volatile type; };
|
||||
template< class From, class To >
|
||||
struct propagate_cv< const volatile From, To >
|
||||
{ typedef To const volatile type; };
|
||||
|
||||
/*******************************************************************************
|
||||
* struct is_integral_or_enum<T>
|
||||
*
|
||||
* This metafunction determines if T is an integral type which can be made
|
||||
* signed or unsigned.
|
||||
******************************************************************************/
|
||||
|
||||
template< class T >
|
||||
struct is_integral_or_enum
|
||||
: public mpl::or_< is_integral<T>, is_enum<T> >
|
||||
{ };
|
||||
template<>
|
||||
struct is_integral_or_enum< bool >
|
||||
: public false_type
|
||||
{ };
|
||||
|
||||
/*******************************************************************************
|
||||
* struct make_unsigned_soft<T>
|
||||
* struct make_signed_soft<T>
|
||||
*
|
||||
* These metafunction are identical to make_unsigned and make_signed,
|
||||
* respectively, except for special-casing bool.
|
||||
******************************************************************************/
|
||||
|
||||
template< class T >
|
||||
struct make_unsigned_soft
|
||||
: public make_unsigned<T>
|
||||
{ };
|
||||
template<>
|
||||
struct make_unsigned_soft< bool >
|
||||
{ typedef bool type; };
|
||||
|
||||
template< class T >
|
||||
struct make_signed_soft
|
||||
: public make_signed<T>
|
||||
{ };
|
||||
template<>
|
||||
struct make_signed_soft< bool >
|
||||
{ typedef bool type; };
|
||||
|
||||
/*******************************************************************************
|
||||
* struct sizeof_t<N>
|
||||
* typedef ... yes_type
|
||||
* typedef ... no_type
|
||||
*
|
||||
* These types are integral players in the use of the "sizeof trick", i.e., we
|
||||
* can distinguish overload selection by inspecting the size of the return type
|
||||
* of the overload.
|
||||
******************************************************************************/
|
||||
|
||||
template< std::size_t N > struct sizeof_t { char _dummy[N]; };
|
||||
typedef sizeof_t<1> yes_type;
|
||||
typedef sizeof_t<2> no_type;
|
||||
BOOST_MPL_ASSERT_RELATION( sizeof( yes_type ), ==, 1 );
|
||||
BOOST_MPL_ASSERT_RELATION( sizeof( no_type ), ==, 2 );
|
||||
|
||||
/*******************************************************************************
|
||||
* rvalue_test(T&) -> no_type
|
||||
* rvalue_test(...) -> yes_type
|
||||
*
|
||||
* These overloads are used to determine the rvalue-ness of an expression.
|
||||
******************************************************************************/
|
||||
|
||||
template< class T > no_type rvalue_test(T&);
|
||||
yes_type rvalue_test(...);
|
||||
|
||||
/*******************************************************************************
|
||||
* struct conversion_test_overloads< Sequence >
|
||||
*
|
||||
* This struct has multiple overloads of the static member function apply, each
|
||||
* one taking a single parameter of a type within the Boost.MPL sequence
|
||||
* Sequence. Each such apply overload has a return type with sizeof equal to
|
||||
* one plus the index of the parameter type within Sequence. Thus, we can
|
||||
* deduce the type T of an expression as long as we can generate a finite set of
|
||||
* candidate types containing T via these apply overloads and the "sizeof
|
||||
* trick".
|
||||
******************************************************************************/
|
||||
|
||||
template< class First, class Last, std::size_t Index >
|
||||
struct conversion_test_overloads_iterate
|
||||
: public conversion_test_overloads_iterate<
|
||||
typename mpl::next< First >::type, Last, Index + 1
|
||||
>
|
||||
{
|
||||
using conversion_test_overloads_iterate<
|
||||
typename mpl::next< First >::type, Last, Index + 1
|
||||
>::apply;
|
||||
static sizeof_t< Index + 1 >
|
||||
apply(typename mpl::deref< First >::type);
|
||||
};
|
||||
|
||||
template< class Last, std::size_t Index >
|
||||
struct conversion_test_overloads_iterate< Last, Last, Index >
|
||||
{ static sizeof_t< Index + 1 > apply(...); };
|
||||
|
||||
template< class Sequence >
|
||||
struct conversion_test_overloads
|
||||
: public conversion_test_overloads_iterate<
|
||||
typename mpl::begin< Sequence >::type,
|
||||
typename mpl::end< Sequence >::type,
|
||||
0
|
||||
>
|
||||
{ };
|
||||
|
||||
/*******************************************************************************
|
||||
* struct select< Sequence, Index >
|
||||
*
|
||||
* select is synonymous with mpl::at_c unless Index equals the size of the
|
||||
* Boost.MPL Sequence, in which case this evaluates to void.
|
||||
******************************************************************************/
|
||||
|
||||
template<
|
||||
class Sequence, int Index,
|
||||
int N = mpl::size< Sequence >::value
|
||||
>
|
||||
struct select
|
||||
: public mpl::at_c< Sequence, Index >
|
||||
{ };
|
||||
template< class Sequence, int N >
|
||||
struct select< Sequence, N, N >
|
||||
{ typedef void type; };
|
||||
|
||||
/*******************************************************************************
|
||||
* class deduce_common_type< T, U, NominalCandidates >
|
||||
* struct nominal_candidates<T,U>
|
||||
* struct common_type_dispatch_on_rvalueness<T,U>
|
||||
* struct common_type_impl<T,U>
|
||||
*
|
||||
* These classes and structs implement the logic behind common_type, which goes
|
||||
* roughly as follows. Let C be the type of the conditional expression
|
||||
* declval< bool >() ? declval<T>() : declval<U>()
|
||||
* if C is an rvalue, then:
|
||||
* let T' and U' be T and U stripped of reference- and cv-qualifiers
|
||||
* if T' and U' are pointer types, say, T' = V* and U' = W*, then:
|
||||
* define the set of NominalCandidates to be
|
||||
* { V*, W*, V'*, W'* }
|
||||
* where V' is V with whatever cv-qualifiers are on W, and W' is W
|
||||
* with whatever cv-qualifiers are on V
|
||||
* else if T' and U' are both integral or enum types, then:
|
||||
* define the set of NominalCandidates to be
|
||||
* {
|
||||
* unsigned_soft(T'),
|
||||
* unsigned_soft(U'),
|
||||
* signed_soft(T'),
|
||||
* signed_soft(U'),
|
||||
* T',
|
||||
* U',
|
||||
* unsigned int,
|
||||
* int
|
||||
* }
|
||||
* where unsigned_soft(X) is make_unsigned_soft<X>::type and
|
||||
* signed_soft(X) is make_signed_soft<X>::type (these are all
|
||||
* generally necessary to cover the various integral promotion cases)
|
||||
* else
|
||||
* define the set of NominalCandidates to be
|
||||
* { T', U' }
|
||||
* else
|
||||
* let V and W be T and U stripped of reference-qualifiers
|
||||
* define the set of NominalCandidates to be
|
||||
* { V&, W&, V'&, W'& }
|
||||
* where V' is V with whatever cv-qualifiers are on W, and W' is W with
|
||||
* whatever cv-qualifiers are on V
|
||||
* define the set of Candidates to be equal to the set of NominalCandidates with
|
||||
* duplicates removed, and use this set of Candidates to determine C using the
|
||||
* conversion_test_overloads struct
|
||||
******************************************************************************/
|
||||
|
||||
template< class T, class U, class NominalCandidates >
|
||||
class deduce_common_type
|
||||
{
|
||||
typedef typename mpl::copy<
|
||||
NominalCandidates,
|
||||
mpl::inserter<
|
||||
mpl::vector0<>,
|
||||
mpl::if_<
|
||||
mpl::contains< mpl::_1, mpl::_2 >,
|
||||
mpl::_1,
|
||||
mpl::push_back< mpl::_1, mpl::_2 >
|
||||
>
|
||||
>
|
||||
>::type candidate_types;
|
||||
static const int best_candidate_index =
|
||||
sizeof( conversion_test_overloads< candidate_types >::apply(
|
||||
declval< bool >() ? declval<T>() : declval<U>()
|
||||
) ) - 1;
|
||||
public:
|
||||
typedef typename select< candidate_types, best_candidate_index >::type type;
|
||||
};
|
||||
|
||||
template<
|
||||
class T, class U,
|
||||
class V = typename remove_cv< typename remove_reference<T>::type >::type,
|
||||
class W = typename remove_cv< typename remove_reference<U>::type >::type,
|
||||
bool = is_integral_or_enum<V>::value && is_integral_or_enum<W>::value
|
||||
>
|
||||
struct nominal_candidates
|
||||
{ typedef mpl::vector2<V,W> type; };
|
||||
|
||||
template< class T, class U, class V, class W >
|
||||
struct nominal_candidates< T, U, V, W, true >
|
||||
{
|
||||
typedef boost::mpl::vector8<
|
||||
typename make_unsigned_soft<V>::type,
|
||||
typename make_unsigned_soft<W>::type,
|
||||
typename make_signed_soft<V>::type,
|
||||
typename make_signed_soft<W>::type,
|
||||
V, W, unsigned int, int
|
||||
> type;
|
||||
};
|
||||
|
||||
template< class T, class U, class V, class W >
|
||||
struct nominal_candidates< T, U, V*, W*, false >
|
||||
{
|
||||
typedef mpl::vector4<
|
||||
V*, W*,
|
||||
typename propagate_cv<W,V>::type *,
|
||||
typename propagate_cv<V,W>::type *
|
||||
> type;
|
||||
};
|
||||
|
||||
template<class T, class U, bool b>
|
||||
struct common_type_dispatch_on_rvalueness
|
||||
: public deduce_common_type< T, U, typename nominal_candidates<T,U>::type >
|
||||
{ };
|
||||
|
||||
template< class T, class U >
|
||||
struct common_type_dispatch_on_rvalueness< T, U, false >
|
||||
{
|
||||
private:
|
||||
typedef typename remove_reference<T>::type unrefed_T_type;
|
||||
typedef typename remove_reference<U>::type unrefed_U_type;
|
||||
public:
|
||||
typedef typename deduce_common_type<
|
||||
T, U,
|
||||
mpl::vector4<
|
||||
unrefed_T_type &,
|
||||
unrefed_U_type &,
|
||||
typename propagate_cv< unrefed_U_type, unrefed_T_type >::type &,
|
||||
typename propagate_cv< unrefed_T_type, unrefed_U_type >::type &
|
||||
>
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template< class T, class U >
|
||||
struct common_type_impl
|
||||
: public common_type_dispatch_on_rvalueness<T,U, sizeof( ::boost::detail_type_traits_common_type::rvalue_test(
|
||||
declval< bool >() ? declval<T>() : declval<U>() ) ) == sizeof( yes_type ) >
|
||||
{ };
|
||||
|
||||
template< class T > struct common_type_impl< T, void > { typedef void type; };
|
||||
template< class T > struct common_type_impl< void, T > { typedef void type; };
|
||||
template<> struct common_type_impl< void, void > { typedef void type; };
|
||||
|
||||
} // namespace detail_type_traits_common_type
|
||||
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_TYPE_TRAITS_DETAIL_COMMON_TYPE_HPP
|
||||
|
107
include/boost/type_traits/detail/common_type_impl.hpp
Normal file
107
include/boost/type_traits/detail/common_type_impl.hpp
Normal file
@ -0,0 +1,107 @@
|
||||
#ifndef BOOST_TYPE_TRAITS_DETAIL_COMMON_TYPE_IMPL_HPP_INCLUDED
|
||||
#define BOOST_TYPE_TRAITS_DETAIL_COMMON_TYPE_IMPL_HPP_INCLUDED
|
||||
|
||||
//
|
||||
// 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
|
||||
//
|
||||
|
||||
#include <boost/type_traits/detail/common_arithmetic_type.hpp>
|
||||
#include <boost/type_traits/detail/composite_pointer_type.hpp>
|
||||
#include <boost/type_traits/detail/composite_member_pointer_type.hpp>
|
||||
#include <boost/type_traits/type_identity.hpp>
|
||||
#include <boost/type_traits/is_class.hpp>
|
||||
#include <boost/type_traits/is_union.hpp>
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
#include <boost/type_traits/is_pointer.hpp>
|
||||
#include <boost/type_traits/is_member_pointer.hpp>
|
||||
#include <boost/type_traits/conditional.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace type_traits_detail
|
||||
{
|
||||
|
||||
// the arguments to common_type_impl have already been passed through decay<>
|
||||
|
||||
template<class T, class U> struct common_type_impl;
|
||||
|
||||
// same type
|
||||
|
||||
template<class T> struct common_type_impl<T, T>
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
// one of the operands is a class type, try conversions in both directions
|
||||
|
||||
template<class T, class U> struct ct_class
|
||||
{
|
||||
BOOST_STATIC_CONSTANT( bool, ct = boost::is_class<T>::value || boost::is_union<T>::value );
|
||||
BOOST_STATIC_CONSTANT( bool, cu = boost::is_class<U>::value || boost::is_union<U>::value );
|
||||
|
||||
BOOST_STATIC_CONSTANT( bool, value = ct || cu );
|
||||
};
|
||||
|
||||
template<class T, class U> struct common_type_impl3;
|
||||
|
||||
template<class T, class U> struct common_type_class: public boost::conditional<
|
||||
|
||||
boost::is_convertible<T, U>::value && !boost::is_convertible<U, T>::value,
|
||||
boost::type_identity<U>,
|
||||
|
||||
typename boost::conditional<
|
||||
|
||||
boost::is_convertible<U, T>::value && !boost::is_convertible<T, U>::value,
|
||||
boost::type_identity<T>,
|
||||
|
||||
common_type_impl3<T, U>
|
||||
>::type
|
||||
>::type
|
||||
{
|
||||
};
|
||||
|
||||
template<class T, class U> struct common_type_impl: public boost::conditional<
|
||||
ct_class<T, U>::value,
|
||||
common_type_class<T, U>,
|
||||
common_type_impl3<T, U> >::type
|
||||
{
|
||||
};
|
||||
|
||||
// pointers
|
||||
|
||||
template<class T, class U> struct common_type_impl4;
|
||||
|
||||
template<class T, class U> struct common_type_impl3: public boost::conditional<
|
||||
boost::is_pointer<T>::value || boost::is_pointer<U>::value,
|
||||
composite_pointer_type<T, U>,
|
||||
common_type_impl4<T, U> >::type
|
||||
{
|
||||
};
|
||||
|
||||
// pointers to members
|
||||
|
||||
template<class T, class U> struct common_type_impl5;
|
||||
|
||||
template<class T, class U> struct common_type_impl4: public boost::conditional<
|
||||
boost::is_member_pointer<T>::value || boost::is_member_pointer<U>::value,
|
||||
composite_member_pointer_type<T, U>,
|
||||
common_type_impl5<T, U> >::type
|
||||
{
|
||||
};
|
||||
|
||||
// arithmetic types (including class types w/ conversions to arithmetic and enums)
|
||||
|
||||
template<class T, class U> struct common_type_impl5: public common_arithmetic_type<T, U>
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace type_traits_detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_TYPE_TRAITS_DETAIL_COMMON_TYPE_IMPL_HPP_INCLUDED
|
@ -0,0 +1,105 @@
|
||||
#ifndef BOOST_TYPE_TRAITS_DETAIL_COMPOSITE_MEMBER_POINTER_TYPE_HPP_INCLUDED
|
||||
#define BOOST_TYPE_TRAITS_DETAIL_COMPOSITE_MEMBER_POINTER_TYPE_HPP_INCLUDED
|
||||
|
||||
//
|
||||
// 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
|
||||
//
|
||||
|
||||
#include <boost/type_traits/detail/composite_pointer_type.hpp>
|
||||
#include <boost/type_traits/remove_pointer.hpp>
|
||||
#include <boost/type_traits/is_base_of.hpp>
|
||||
#include <boost/type_traits/conditional.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <cstddef>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace type_traits_detail
|
||||
{
|
||||
|
||||
template<class T, class U> struct composite_member_pointer_type;
|
||||
|
||||
// nullptr_t
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_NULLPTR )
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_DECLTYPE ) && ( ( defined( __clang__ ) && !defined( _LIBCPP_VERSION ) ) || defined( __INTEL_COMPILER ) )
|
||||
|
||||
template<class C, class T> struct composite_member_pointer_type<T C::*, decltype(nullptr)>
|
||||
{
|
||||
typedef T C::* type;
|
||||
};
|
||||
|
||||
template<class C, class T> struct composite_member_pointer_type<decltype(nullptr), T C::*>
|
||||
{
|
||||
typedef T C::* type;
|
||||
};
|
||||
|
||||
template<> struct composite_member_pointer_type<decltype(nullptr), decltype(nullptr)>
|
||||
{
|
||||
typedef decltype(nullptr) type;
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
template<class C, class T> struct composite_member_pointer_type<T C::*, std::nullptr_t>
|
||||
{
|
||||
typedef T C::* type;
|
||||
};
|
||||
|
||||
template<class C, class T> struct composite_member_pointer_type<std::nullptr_t, T C::*>
|
||||
{
|
||||
typedef T C::* type;
|
||||
};
|
||||
|
||||
template<> struct composite_member_pointer_type<std::nullptr_t, std::nullptr_t>
|
||||
{
|
||||
typedef std::nullptr_t type;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif // !defined( BOOST_NO_CXX11_NULLPTR )
|
||||
|
||||
template<class C1, class C2> struct common_member_class;
|
||||
|
||||
template<class C> struct common_member_class<C, C>
|
||||
{
|
||||
typedef C type;
|
||||
};
|
||||
|
||||
template<class C1, class C2> struct common_member_class
|
||||
{
|
||||
typedef typename boost::conditional<
|
||||
|
||||
boost::is_base_of<C1, C2>::value,
|
||||
C2,
|
||||
typename boost::conditional<boost::is_base_of<C2, C1>::value, C1, void>::type
|
||||
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template<class C1, class T1, class C2, class T2> struct composite_member_pointer_type<T1 C1::*, T2 C2::*>
|
||||
{
|
||||
private:
|
||||
|
||||
typedef typename composite_pointer_type<T1*, T2*>::type CPT;
|
||||
typedef typename boost::remove_pointer<CPT>::type CT;
|
||||
|
||||
typedef typename common_member_class<C1, C2>::type CB;
|
||||
|
||||
public:
|
||||
|
||||
typedef CT CB::* type;
|
||||
};
|
||||
|
||||
} // namespace type_traits_detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_TYPE_TRAITS_DETAIL_COMPOSITE_MEMBER_POINTER_TYPE_HPP_INCLUDED
|
144
include/boost/type_traits/detail/composite_pointer_type.hpp
Normal file
144
include/boost/type_traits/detail/composite_pointer_type.hpp
Normal file
@ -0,0 +1,144 @@
|
||||
#ifndef BOOST_TYPE_TRAITS_DETAIL_COMPOSITE_POINTER_TYPE_HPP_INCLUDED
|
||||
#define BOOST_TYPE_TRAITS_DETAIL_COMPOSITE_POINTER_TYPE_HPP_INCLUDED
|
||||
|
||||
//
|
||||
// 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
|
||||
//
|
||||
|
||||
#include <boost/type_traits/copy_cv.hpp>
|
||||
#include <boost/type_traits/remove_cv.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/type_traits/is_void.hpp>
|
||||
#include <boost/type_traits/is_base_of.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <cstddef>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace type_traits_detail
|
||||
{
|
||||
|
||||
template<class T, class U> struct composite_pointer_type;
|
||||
|
||||
// same type
|
||||
|
||||
template<class T> struct composite_pointer_type<T*, T*>
|
||||
{
|
||||
typedef T* type;
|
||||
};
|
||||
|
||||
// nullptr_t
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_NULLPTR )
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_DECLTYPE ) && ( ( defined( __clang__ ) && !defined( _LIBCPP_VERSION ) ) || defined( __INTEL_COMPILER ) )
|
||||
|
||||
template<class T> struct composite_pointer_type<T*, decltype(nullptr)>
|
||||
{
|
||||
typedef T* type;
|
||||
};
|
||||
|
||||
template<class T> struct composite_pointer_type<decltype(nullptr), T*>
|
||||
{
|
||||
typedef T* type;
|
||||
};
|
||||
|
||||
template<> struct composite_pointer_type<decltype(nullptr), decltype(nullptr)>
|
||||
{
|
||||
typedef decltype(nullptr) type;
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
template<class T> struct composite_pointer_type<T*, std::nullptr_t>
|
||||
{
|
||||
typedef T* type;
|
||||
};
|
||||
|
||||
template<class T> struct composite_pointer_type<std::nullptr_t, T*>
|
||||
{
|
||||
typedef T* type;
|
||||
};
|
||||
|
||||
template<> struct composite_pointer_type<std::nullptr_t, std::nullptr_t>
|
||||
{
|
||||
typedef std::nullptr_t type;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif // !defined( BOOST_NO_CXX11_NULLPTR )
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class T, class U> struct has_common_pointee
|
||||
{
|
||||
private:
|
||||
|
||||
typedef typename boost::remove_cv<T>::type T2;
|
||||
typedef typename boost::remove_cv<U>::type U2;
|
||||
|
||||
public:
|
||||
|
||||
BOOST_STATIC_CONSTANT( bool, value =
|
||||
(boost::is_same<T2, U2>::value)
|
||||
|| boost::is_void<T2>::value
|
||||
|| boost::is_void<U2>::value
|
||||
|| (boost::is_base_of<T2, U2>::value)
|
||||
|| (boost::is_base_of<U2, T2>::value) );
|
||||
};
|
||||
|
||||
template<class T, class U> struct common_pointee
|
||||
{
|
||||
private:
|
||||
|
||||
typedef typename boost::remove_cv<T>::type T2;
|
||||
typedef typename boost::remove_cv<U>::type U2;
|
||||
|
||||
public:
|
||||
|
||||
typedef typename boost::conditional<
|
||||
|
||||
boost::is_same<T2, U2>::value || boost::is_void<T2>::value || boost::is_base_of<T2, U2>::value,
|
||||
typename boost::copy_cv<T, U>::type,
|
||||
typename boost::copy_cv<U, T>::type
|
||||
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template<class T, class U> struct composite_pointer_impl
|
||||
{
|
||||
private:
|
||||
|
||||
typedef typename boost::remove_cv<T>::type T2;
|
||||
typedef typename boost::remove_cv<U>::type U2;
|
||||
|
||||
public:
|
||||
|
||||
typedef typename boost::copy_cv<typename boost::copy_cv<typename composite_pointer_type<T2, U2>::type const, T>::type, U>::type type;
|
||||
};
|
||||
|
||||
} // detail
|
||||
|
||||
template<class T, class U> struct composite_pointer_type<T*, U*>
|
||||
{
|
||||
typedef typename boost::conditional<
|
||||
|
||||
detail::has_common_pointee<T, U>::value,
|
||||
detail::common_pointee<T, U>,
|
||||
detail::composite_pointer_impl<T, U>
|
||||
|
||||
>::type::type * type;
|
||||
};
|
||||
|
||||
} // namespace type_traits_detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_TYPE_TRAITS_DETAIL_COMPOSITE_POINTER_TYPE_HPP_INCLUDED
|
@ -31,7 +31,7 @@
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
#endif
|
||||
#if !defined(BOOST_NO_SFINAE_EXPR) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
# include <boost/utility/declval.hpp>
|
||||
# include <boost/type_traits/declval.hpp>
|
||||
#endif
|
||||
#elif defined(BOOST_MSVC) || defined(BOOST_INTEL)
|
||||
#include <boost/type_traits/is_function.hpp>
|
||||
|
@ -18,7 +18,7 @@
|
||||
&& !defined(BOOST_INTEL_CXX_VERSION) && \
|
||||
!(defined(BOOST_MSVC) && _MSC_VER == 1800)
|
||||
#define BOOST_TT_CXX11_IS_COPY_ASSIGNABLE
|
||||
#include <boost/utility/declval.hpp>
|
||||
#include <boost/type_traits/declval.hpp>
|
||||
#else
|
||||
//For compilers without decltype
|
||||
#include <boost/type_traits/is_const.hpp>
|
||||
|
@ -13,7 +13,7 @@
|
||||
#include <boost/type_traits/is_base_and_derived.hpp>
|
||||
#include <boost/type_traits/add_reference.hpp>
|
||||
#include <boost/type_traits/is_rvalue_reference.hpp>
|
||||
#include <boost/utility/declval.hpp>
|
||||
#include <boost/type_traits/declval.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
@ -17,7 +17,7 @@
|
||||
#include <boost/type_traits/is_array.hpp>
|
||||
#include <boost/type_traits/is_reference.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/utility/declval.hpp>
|
||||
#include <boost/type_traits/declval.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
|
@ -31,7 +31,7 @@ template <class T> struct is_nothrow_move_constructible<T&&> : public ::boost::f
|
||||
|
||||
#elif !defined(BOOST_NO_CXX11_NOEXCEPT) && !defined(BOOST_NO_SFINAE_EXPR)
|
||||
|
||||
#include <boost/utility/declval.hpp>
|
||||
#include <boost/type_traits/declval.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
|
||||
namespace boost{ namespace detail{
|
||||
|
22
include/boost/type_traits/type_identity.hpp
Normal file
22
include/boost/type_traits/type_identity.hpp
Normal file
@ -0,0 +1,22 @@
|
||||
#ifndef BOOST_TYPE_TRAITS_TYPE_IDENTITY_HPP_INCLUDED
|
||||
#define BOOST_TYPE_TRAITS_TYPE_IDENTITY_HPP_INCLUDED
|
||||
|
||||
//
|
||||
// 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
|
||||
//
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
template<class T> struct type_identity
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_TYPE_TRAITS_TYPE_IDENTITY_HPP_INCLUDED
|
@ -8,37 +8,6 @@
|
||||
#ifndef BOOST_UTILITY_DECLVAL_HPP
|
||||
#define BOOST_UTILITY_DECLVAL_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
#include <boost/type_traits/add_rvalue_reference.hpp>
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
// //
|
||||
// C++03 implementation of //
|
||||
// 20.2.4 Function template declval [declval] //
|
||||
// Written by Vicente J. Botet Escriba //
|
||||
// //
|
||||
// 1 The library provides the function template declval to simplify the
|
||||
// definition of expressions which occur as unevaluated operands.
|
||||
// 2 Remarks: If this function is used, the program is ill-formed.
|
||||
// 3 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. For another example
|
||||
// see class template common_type (20.9.7.6). -end example ]
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
namespace boost {
|
||||
|
||||
template <typename T>
|
||||
typename add_rvalue_reference<T>::type declval() BOOST_NOEXCEPT; // as unevaluated operand
|
||||
|
||||
} // namespace boost
|
||||
#include <boost/type_traits/declval.hpp>
|
||||
|
||||
#endif // BOOST_UTILITY_DECLVAL_HPP
|
||||
|
22
test/common_type_3_test.cpp
Normal file
22
test/common_type_3_test.cpp
Normal file
@ -0,0 +1,22 @@
|
||||
|
||||
// Copyright Peter Dimov 2015
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.tt.org/LICENSE_1_0.txt)
|
||||
|
||||
#include "test.hpp"
|
||||
#include "check_type.hpp"
|
||||
#ifdef TEST_STD
|
||||
# include <type_traits>
|
||||
#else
|
||||
# include <boost/type_traits/common_type.hpp>
|
||||
#endif
|
||||
#include <iostream>
|
||||
|
||||
TT_TEST_BEGIN(common_type_3)
|
||||
{
|
||||
// just check whether the nullary specialization compiles
|
||||
tt::common_type<> tmp;
|
||||
(void)tmp;
|
||||
}
|
||||
TT_TEST_END
|
57
test/common_type_4_test.cpp
Normal file
57
test/common_type_4_test.cpp
Normal file
@ -0,0 +1,57 @@
|
||||
|
||||
// Copyright Peter Dimov 2015
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.tt.org/LICENSE_1_0.txt)
|
||||
|
||||
#include "test.hpp"
|
||||
#include "check_type.hpp"
|
||||
#ifdef TEST_STD
|
||||
# include <type_traits>
|
||||
#else
|
||||
# include <boost/type_traits/common_type.hpp>
|
||||
#endif
|
||||
#include <iostream>
|
||||
|
||||
TT_TEST_BEGIN(common_type_4)
|
||||
{
|
||||
// the unary case should be the same as decay
|
||||
|
||||
BOOST_CHECK_TYPE(tt::common_type<void>::type, void);
|
||||
BOOST_CHECK_TYPE(tt::common_type<void const>::type, void);
|
||||
BOOST_CHECK_TYPE(tt::common_type<void volatile>::type, void);
|
||||
BOOST_CHECK_TYPE(tt::common_type<void const volatile>::type, void);
|
||||
|
||||
BOOST_CHECK_TYPE(tt::common_type<char>::type, char);
|
||||
BOOST_CHECK_TYPE(tt::common_type<char const>::type, char);
|
||||
BOOST_CHECK_TYPE(tt::common_type<char volatile>::type, char);
|
||||
BOOST_CHECK_TYPE(tt::common_type<char const volatile>::type, char);
|
||||
|
||||
BOOST_CHECK_TYPE(tt::common_type<char&>::type, char);
|
||||
BOOST_CHECK_TYPE(tt::common_type<char const&>::type, char);
|
||||
BOOST_CHECK_TYPE(tt::common_type<char volatile&>::type, char);
|
||||
BOOST_CHECK_TYPE(tt::common_type<char const volatile&>::type, char);
|
||||
|
||||
BOOST_CHECK_TYPE(tt::common_type<char[]>::type, char*);
|
||||
BOOST_CHECK_TYPE(tt::common_type<char const[]>::type, char const*);
|
||||
BOOST_CHECK_TYPE(tt::common_type<char volatile[]>::type, char volatile*);
|
||||
BOOST_CHECK_TYPE(tt::common_type<char const volatile[]>::type, char const volatile*);
|
||||
|
||||
BOOST_CHECK_TYPE(tt::common_type<char[2]>::type, char*);
|
||||
BOOST_CHECK_TYPE(tt::common_type<char const[2]>::type, char const*);
|
||||
BOOST_CHECK_TYPE(tt::common_type<char volatile[2]>::type, char volatile*);
|
||||
BOOST_CHECK_TYPE(tt::common_type<char const volatile[2]>::type, char const volatile*);
|
||||
|
||||
BOOST_CHECK_TYPE(tt::common_type<char (&) [2]>::type, char*);
|
||||
BOOST_CHECK_TYPE(tt::common_type<char const (&) [2]>::type, char const*);
|
||||
BOOST_CHECK_TYPE(tt::common_type<char volatile (&) [2]>::type, char volatile*);
|
||||
BOOST_CHECK_TYPE(tt::common_type<char const volatile (&) [2]>::type, char const volatile*);
|
||||
|
||||
BOOST_CHECK_TYPE(tt::common_type<char()>::type, char(*)());
|
||||
|
||||
BOOST_CHECK_TYPE(tt::common_type<UDT()>::type, UDT(*)());
|
||||
BOOST_CHECK_TYPE(tt::common_type<UDT const()>::type, UDT const(*)());
|
||||
BOOST_CHECK_TYPE(tt::common_type<UDT volatile()>::type, UDT volatile(*)());
|
||||
BOOST_CHECK_TYPE(tt::common_type<UDT const volatile()>::type, UDT const volatile(*)());
|
||||
}
|
||||
TT_TEST_END
|
56
test/common_type_5_test.cpp
Normal file
56
test/common_type_5_test.cpp
Normal file
@ -0,0 +1,56 @@
|
||||
|
||||
// Copyright Peter Dimov 2015
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.tt.org/LICENSE_1_0.txt)
|
||||
|
||||
#include "test.hpp"
|
||||
#include "check_type.hpp"
|
||||
#ifdef TEST_STD
|
||||
# include <type_traits>
|
||||
#else
|
||||
# include <boost/type_traits/common_type.hpp>
|
||||
#endif
|
||||
#include <iostream>
|
||||
|
||||
template<class T> struct X
|
||||
{
|
||||
T t_;
|
||||
|
||||
X(): t_() {}
|
||||
template<class U> X( X<U> const & x ): t_( x.t_ ) {}
|
||||
};
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
template<class T, class U> struct common_type< X<T>, X<U> >
|
||||
{
|
||||
typedef X<typename common_type<T, U>::type> type;
|
||||
};
|
||||
|
||||
} // namespace boost
|
||||
|
||||
TT_TEST_BEGIN(common_type_5)
|
||||
{
|
||||
// user specializations, binary
|
||||
|
||||
BOOST_CHECK_TYPE3( tt::common_type< X<char>, X<char> >::type, X<char> );
|
||||
|
||||
BOOST_CHECK_TYPE3( tt::common_type< X<char>&, X<char>& >::type, X<char> );
|
||||
BOOST_CHECK_TYPE3( tt::common_type< X<char>&, X<char> const& >::type, X<char> );
|
||||
BOOST_CHECK_TYPE3( tt::common_type< X<char> const&, X<char>& >::type, X<char> );
|
||||
BOOST_CHECK_TYPE3( tt::common_type< X<char> const&, X<char> const& >::type, X<char> );
|
||||
|
||||
BOOST_CHECK_TYPE3( tt::common_type< X<char>, X<unsigned char> >::type, X<int> );
|
||||
|
||||
BOOST_CHECK_TYPE3( tt::common_type< X<char>&, X<unsigned char>& >::type, X<int> );
|
||||
BOOST_CHECK_TYPE3( tt::common_type< X<char>&, X<unsigned char> const& >::type, X<int> );
|
||||
BOOST_CHECK_TYPE3( tt::common_type< X<char> const&, X<unsigned char>& >::type, X<int> );
|
||||
BOOST_CHECK_TYPE3( tt::common_type< X<char> const&, X<unsigned char> const& >::type, X<int> );
|
||||
|
||||
// ternary
|
||||
|
||||
BOOST_CHECK_TYPE4( tt::common_type< X<char>&, X<long> const&, X<short> volatile& >::type, X<long> );
|
||||
}
|
||||
TT_TEST_END
|
44
test/copy_cv_test.cpp
Normal file
44
test/copy_cv_test.cpp
Normal file
@ -0,0 +1,44 @@
|
||||
|
||||
// Copyright Peter Dimov 2015
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.tt.org/LICENSE_1_0.txt)
|
||||
|
||||
#include "test.hpp"
|
||||
#include "check_type.hpp"
|
||||
#ifdef TEST_STD
|
||||
# include <type_traits>
|
||||
#else
|
||||
# include <boost/type_traits/copy_cv.hpp>
|
||||
#endif
|
||||
#include <iostream>
|
||||
|
||||
TT_TEST_BEGIN(copy_cv)
|
||||
{
|
||||
BOOST_CHECK_TYPE3(tt::copy_cv<int, void>::type, int);
|
||||
BOOST_CHECK_TYPE3(tt::copy_cv<int const, void>::type, int const);
|
||||
BOOST_CHECK_TYPE3(tt::copy_cv<int volatile, void>::type, int volatile);
|
||||
BOOST_CHECK_TYPE3(tt::copy_cv<int const volatile, void>::type, int const volatile);
|
||||
|
||||
BOOST_CHECK_TYPE3(tt::copy_cv<int, void const>::type, int const);
|
||||
BOOST_CHECK_TYPE3(tt::copy_cv<int const, void const>::type, int const);
|
||||
BOOST_CHECK_TYPE3(tt::copy_cv<int volatile, void const>::type, int const volatile);
|
||||
BOOST_CHECK_TYPE3(tt::copy_cv<int const volatile, void const>::type, int const volatile);
|
||||
|
||||
BOOST_CHECK_TYPE3(tt::copy_cv<int, void volatile>::type, int volatile);
|
||||
BOOST_CHECK_TYPE3(tt::copy_cv<int const, void volatile>::type, int const volatile);
|
||||
BOOST_CHECK_TYPE3(tt::copy_cv<int volatile, void volatile>::type, int volatile);
|
||||
BOOST_CHECK_TYPE3(tt::copy_cv<int const volatile, void volatile>::type, int const volatile);
|
||||
|
||||
BOOST_CHECK_TYPE3(tt::copy_cv<int, void const volatile>::type, int const volatile);
|
||||
BOOST_CHECK_TYPE3(tt::copy_cv<int const, void const volatile>::type, int const volatile);
|
||||
BOOST_CHECK_TYPE3(tt::copy_cv<int volatile, void const volatile>::type, int const volatile);
|
||||
BOOST_CHECK_TYPE3(tt::copy_cv<int const volatile, void const volatile>::type, int const volatile);
|
||||
|
||||
BOOST_CHECK_TYPE3(tt::copy_cv<int&, void const volatile>::type, int&);
|
||||
|
||||
BOOST_CHECK_TYPE3(tt::copy_cv<int const*, void volatile>::type, int const* volatile);
|
||||
|
||||
BOOST_CHECK_TYPE3(tt::copy_cv<long, int const volatile&>::type, long);
|
||||
}
|
||||
TT_TEST_END
|
60
test/type_identity_test.cpp
Normal file
60
test/type_identity_test.cpp
Normal file
@ -0,0 +1,60 @@
|
||||
|
||||
// (C) Copyright John Maddock 2000.
|
||||
// (C) Copyright Peter Dimov 2015.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.tt.org/LICENSE_1_0.txt)
|
||||
|
||||
#include "test.hpp"
|
||||
#include "check_type.hpp"
|
||||
#ifdef TEST_STD
|
||||
# include <type_traits>
|
||||
#else
|
||||
# include <boost/type_traits/type_identity.hpp>
|
||||
#endif
|
||||
|
||||
BOOST_DECL_TRANSFORM_TEST(type_identity_test_1, ::tt::type_identity, const, const)
|
||||
BOOST_DECL_TRANSFORM_TEST(type_identity_test_2, ::tt::type_identity, volatile, volatile)
|
||||
BOOST_DECL_TRANSFORM_TEST(type_identity_test_3, ::tt::type_identity, const volatile, const volatile)
|
||||
BOOST_DECL_TRANSFORM_TEST0(type_identity_test_4, ::tt::type_identity)
|
||||
BOOST_DECL_TRANSFORM_TEST(type_identity_test_5, ::tt::type_identity, [], [])
|
||||
BOOST_DECL_TRANSFORM_TEST(type_identity_test_6, ::tt::type_identity, *const, *const)
|
||||
BOOST_DECL_TRANSFORM_TEST(type_identity_test_7, ::tt::type_identity, *volatile, *volatile)
|
||||
BOOST_DECL_TRANSFORM_TEST(type_identity_test_8, ::tt::type_identity, *const volatile, *const volatile)
|
||||
BOOST_DECL_TRANSFORM_TEST(type_identity_test_9, ::tt::type_identity, *, *)
|
||||
BOOST_DECL_TRANSFORM_TEST(type_identity_test_10, ::tt::type_identity, *, *)
|
||||
BOOST_DECL_TRANSFORM_TEST(type_identity_test_11, ::tt::type_identity, volatile*, volatile*)
|
||||
BOOST_DECL_TRANSFORM_TEST(type_identity_test_12, ::tt::type_identity, const[2], const[2])
|
||||
BOOST_DECL_TRANSFORM_TEST(type_identity_test_13, ::tt::type_identity, volatile[2], volatile[2])
|
||||
BOOST_DECL_TRANSFORM_TEST(type_identity_test_14, ::tt::type_identity, const volatile[2], const volatile[2])
|
||||
BOOST_DECL_TRANSFORM_TEST(type_identity_test_15, ::tt::type_identity, [2], [2])
|
||||
BOOST_DECL_TRANSFORM_TEST(type_identity_test_16, ::tt::type_identity, const*, const*)
|
||||
BOOST_DECL_TRANSFORM_TEST(type_identity_test_17, ::tt::type_identity, const*volatile, const*volatile)
|
||||
BOOST_DECL_TRANSFORM_TEST(type_identity_test_18, ::tt::type_identity, (), ())
|
||||
BOOST_DECL_TRANSFORM_TEST(type_identity_test_19, ::tt::type_identity, (int), (int))
|
||||
BOOST_DECL_TRANSFORM_TEST(type_identity_test_20, ::tt::type_identity, (*const)(), (*const)())
|
||||
|
||||
TT_TEST_BEGIN(type_identity)
|
||||
|
||||
type_identity_test_1();
|
||||
type_identity_test_2();
|
||||
type_identity_test_3();
|
||||
type_identity_test_4();
|
||||
type_identity_test_5();
|
||||
type_identity_test_6();
|
||||
type_identity_test_7();
|
||||
type_identity_test_8();
|
||||
type_identity_test_9();
|
||||
type_identity_test_10();
|
||||
type_identity_test_11();
|
||||
type_identity_test_12();
|
||||
type_identity_test_13();
|
||||
type_identity_test_14();
|
||||
type_identity_test_15();
|
||||
type_identity_test_16();
|
||||
type_identity_test_17();
|
||||
type_identity_test_18();
|
||||
type_identity_test_19();
|
||||
type_identity_test_20();
|
||||
|
||||
TT_TEST_END
|
Reference in New Issue
Block a user