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:
jzmaddock
2015-06-08 11:41:56 +01:00
27 changed files with 1117 additions and 667 deletions

View File

@ -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
View 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]

View File

@ -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]

View File

@ -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
View 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]

View File

@ -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]

View File

@ -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"

View File

@ -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

View 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

View 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

View 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

View File

@ -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

View 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

View File

@ -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

View 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

View File

@ -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>

View File

@ -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>

View File

@ -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 {

View File

@ -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 {

View File

@ -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{

View 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

View File

@ -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

View 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

View 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

View 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
View 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

View 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