diff options
Diffstat (limited to 'boost/type_traits/common_type.hpp')
-rw-r--r-- | boost/type_traits/common_type.hpp | 249 |
1 files changed, 118 insertions, 131 deletions
diff --git a/boost/type_traits/common_type.hpp b/boost/type_traits/common_type.hpp index b52ff167eb..5c4303b9ec 100644 --- a/boost/type_traits/common_type.hpp +++ b/boost/type_traits/common_type.hpp @@ -1,157 +1,144 @@ -// 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/type_traits/decay.hpp> +#include <boost/type_traits/declval.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 +#if defined(BOOST_NO_CXX11_DECLTYPE) +#include <boost/type_traits/detail/common_type_impl.hpp> #endif -//----------------------------------------------------------------------------// -#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_COMMON_TYPE_ARITY) -#define BOOST_COMMON_TYPE_ARITY 3 +#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +#include <boost/type_traits/detail/mp_defer.hpp> #endif -//----------------------------------------------------------------------------// -#if defined(BOOST_NO_CXX11_DECLTYPE) && !defined(BOOST_COMMON_TYPE_DONT_USE_TYPEOF) -#include <boost/typeof/typeof.hpp> // boost wonders never cease! -#endif +namespace boost +{ -//----------------------------------------------------------------------------// -#ifndef BOOST_NO_CXX11_STATIC_ASSERT -#define BOOST_COMMON_TYPE_STATIC_ASSERT(CND, MSG, TYPES) static_assert(CND,MSG) -#elif defined(BOOST_COMMON_TYPE_USES_MPL_ASSERT) -#include <boost/mpl/assert.hpp> -#include <boost/mpl/bool.hpp> -#define BOOST_COMMON_TYPE_STATIC_ASSERT(CND, MSG, TYPES) \ - BOOST_MPL_ASSERT_MSG(boost::mpl::bool_< (CND) >::type::value, MSG, TYPES) -#else -#include <boost/static_assert.hpp> -#define BOOST_COMMON_TYPE_STATIC_ASSERT(CND, MSG, TYPES) BOOST_STATIC_ASSERT(CND) -#endif +// variadic common_type -#if !defined(BOOST_NO_CXX11_STATIC_ASSERT) || !defined(BOOST_COMMON_TYPE_USES_MPL_ASSERT) -#define BOOST_COMMON_TYPE_MUST_BE_A_COMPLE_TYPE "must be complete type" -#endif - -#if defined(BOOST_NO_CXX11_DECLTYPE) && defined(BOOST_COMMON_TYPE_DONT_USE_TYPEOF) -#include <boost/type_traits/detail/common_type_imp.hpp> -#include <boost/type_traits/remove_cv.hpp> -#endif -#include <boost/mpl/if.hpp> -#include <boost/utility/declval.hpp> -#include <boost/type_traits/add_rvalue_reference.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 { - -// 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; - }; -#endif +template<class... T> struct common_type +{ +}; + +#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) + +template<class... T> using common_type_t = typename common_type<T...>::type; + +namespace type_traits_detail +{ + +template<class T1, class T2, class... T> using common_type_fold = common_type_t<common_type_t<T1, T2>, T...>; + +} // namespace type_traits_detail + +template<class T1, class T2, class... T> +struct common_type<T1, T2, T...>: type_traits_detail::mp_defer<type_traits_detail::common_type_fold, T1, T2, T...> +{ +}; -// 1 arg - template<typename T> -#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - struct common_type<T> #else - struct common_type<T, void, void> -#endif - { - BOOST_COMMON_TYPE_STATIC_ASSERT(sizeof(T) > 0, BOOST_COMMON_TYPE_MUST_BE_A_COMPLE_TYPE, (T)); - public: - typedef T type; - }; - -// 2 args -namespace type_traits_detail { - - template <class T, class U> - struct common_type_2 - { - private: - BOOST_COMMON_TYPE_STATIC_ASSERT(sizeof(T) > 0, BOOST_COMMON_TYPE_MUST_BE_A_COMPLE_TYPE, (T)); - BOOST_COMMON_TYPE_STATIC_ASSERT(sizeof(U) > 0, BOOST_COMMON_TYPE_MUST_BE_A_COMPLE_TYPE, (U)); - static bool declval_bool(); // workaround gcc bug; not required by std - 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(); +template<class T1, class T2, class... T> +struct common_type<T1, T2, T...>: common_type<typename common_type<T1, T2>::type, T...> +{ +}; + +#endif // !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) + +#else + +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> +{ +}; + +#endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + +// 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 decltype(declval<bool>() ? declval<T>() : declval<U>()) 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; + +#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + +#if !defined(BOOST_MSVC) || BOOST_MSVC > 1800 + +// internal compiler error on msvc-12.0 + +template<class T1, class T2> using builtin_common_type = typename boost::decay<decltype( boost::declval<bool>()? boost::declval<T1>(): boost::declval<T2>() )>::type; + +template<class T1, class T2> struct common_type_impl: mp_defer<builtin_common_type, T1, T2> +{ +}; + #else - public: - typedef BOOST_TYPEOF_TPL(declval_b() ? declval_T() : declval_U()) 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> using builtin_common_type = decltype( boost::declval<bool>()? boost::declval<T1>(): boost::declval<T2>() ); - template <class T> - struct common_type_2<T, T> - { - typedef T type; - }; - } +template<class T1, class T2> struct common_type_impl_2: mp_defer<builtin_common_type, T1, T2> +{ +}; + +template<class T1, class T2> using decay_common_type = typename boost::decay<typename common_type_impl_2<T1, T2>::type>::type; + +template<class T1, class T2> struct common_type_impl: mp_defer<decay_common_type, T1, T2> +{ +}; + +#endif // !defined(BOOST_MSVC) || BOOST_MSVC > 1800 -#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> - { }; +template<class T1, class T2> struct common_type_impl: boost::decay<decltype( boost::declval<bool>()? boost::declval<T1>(): boost::declval<T2>() )> +{ +}; -// 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 +#endif // #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + +#endif // #if !defined(BOOST_NO_CXX11_DECLTYPE) + +// 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> +{ +}; + +template<class T1, class T2> struct common_type_decay_helper<T1, T2, T1, T2>: common_type_impl<T1, T2> +{ +}; + +} // 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 // BOOST_TYPE_TRAITS_COMMON_TYPE_HPP +#endif // #ifndef BOOST_TYPE_TRAITS_COMMON_TYPE_HPP_INCLUDED |