123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151 |
- // common_type.hpp ---------------------------------------------------------//
- // Copyright 2008 Howard Hinnant
- // Copyright 2008 Beman Dawes
- // Distributed under the Boost Software License, Version 1.0.
- // See http://www.boost.org/LICENSE_1_0.txt
- #ifndef BOOST_EX_TYPE_TRAITS_EXT_COMMON_TYPE_HPP
- #define BOOST_EX_TYPE_TRAITS_EXT_COMMON_TYPE_HPP
- #include <boost/config.hpp>
- //----------------------------------------------------------------------------//
- #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
- #define BOOST_EX_COMMON_TYPE_ARITY 3
- #endif
- //----------------------------------------------------------------------------//
- #if defined(BOOST_NO_CXX11_DECLTYPE) && !defined(BOOST_EX_COMMON_TYPE_DONT_USE_TYPEOF)
- #define BOOST_TYPEOF_SILENT
- #include <boost/typeof/typeof.hpp> // boost wonders never cease!
- #endif
- //----------------------------------------------------------------------------//
- #ifndef BOOST_NO_CXX11_STATIC_ASSERT
- #define BOOST_EX_COMMON_TYPE_STATIC_ASSERT(CND, MSG, TYPES) static_assert(CND,MSG)
- #elif defined(BOOST_EX_COMMON_TYPE_USES_STATIC_ASSERT)
- #include <boost/static_assert.hpp>
- #define BOOST_EX_COMMON_TYPE_STATIC_ASSERT(CND, MSG, TYPES) BOOST_STATIC_ASSERT(CND)
- #elif defined(BOOST_EX_COMMON_TYPE_USES_MPL_ASSERT)
- #include <boost/mpl/assert.hpp>
- #include <boost/mpl/bool.hpp>
- #define BOOST_EX_COMMON_TYPE_STATIC_ASSERT(CND, MSG, TYPES) \
- BOOST_MPL_ASSERT_MSG(boost::mpl::bool_< (CND) >::type::value, MSG, TYPES)
- #else
- //~ #elif defined(BOOST_EX_COMMON_TYPE_USES_ARRAY_ASSERT)
- #define BOOST_EX_COMMON_TYPE_CONCAT(A,B) A##B
- #define BOOST_EX_COMMON_TYPE_NAME(A,B) BOOST_EX_COMMON_TYPE_CONCAT(A,B)
- #define BOOST_EX_COMMON_TYPE_STATIC_ASSERT(CND, MSG, TYPES) static char BOOST_EX_COMMON_TYPE_NAME(__boost_common_type_test_,__LINE__)[(CND)?1:-1]
- //~ #define BOOST_EX_COMMON_TYPE_STATIC_ASSERT(CND, MSG, TYPES)
- #endif
- #if !defined(BOOST_NO_CXX11_STATIC_ASSERT) || !defined(BOOST_EX_COMMON_TYPE_USES_MPL_ASSERT)
- #define BOOST_EX_COMMON_TYPE_MUST_BE_A_COMPLE_TYPE "must be complete type"
- #endif
- #if defined(BOOST_NO_CXX11_DECLTYPE) && defined(BOOST_EX_COMMON_TYPE_DONT_USE_TYPEOF)
- #include "detail/common_type.hpp"
- #include <boost/type_traits/remove_cv.hpp>
- #endif
- #include <boost/mpl/if.hpp>
- #include "declval.hpp"
- //----------------------------------------------------------------------------//
- // //
- // C++03 implementation of //
- // 20.6.7 Other transformations [meta.trans.other] //
- // Written by Howard Hinnant //
- // Adapted for Boost by Beman Dawes, Vicente Botet and Jeffrey Hellrung //
- // //
- //----------------------------------------------------------------------------//
- namespace boost_ex {
- // 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
- // 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_EX_COMMON_TYPE_STATIC_ASSERT(sizeof(T) > 0, BOOST_EX_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_EX_COMMON_TYPE_STATIC_ASSERT(sizeof(T) > 0, BOOST_EX_COMMON_TYPE_MUST_BE_A_COMPLE_TYPE, (T));
- BOOST_EX_COMMON_TYPE_STATIC_ASSERT(sizeof(U) > 0, BOOST_EX_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
- #if !defined(BOOST_NO_CXX11_DECLTYPE)
- public:
- typedef decltype(declval<bool>() ? declval<T>() : declval<U>()) type;
- #elif defined(BOOST_EX_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
- public:
- //~ typedef BOOST_TYPEOF_TPL(declval_bool() ? declval_T() : declval_U()) type;
- typedef BOOST_TYPEOF_TPL(declval<bool>() ? declval<T>() : declval<U>()) type;
- #endif
- };
- template <class T>
- struct common_type_2<T, T>
- {
- typedef T type;
- };
- }
- #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
- : type_traits_detail::common_type_2<T,U>
- { };
- // 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_ex
- #endif // BOOST_TYPE_TRAITS_EXT_COMMON_TYPE_HPP
|