summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '3rdParty/Boost/src/boost/type_traits/detail/common_type_imp.hpp')
-rw-r--r--3rdParty/Boost/src/boost/type_traits/detail/common_type_imp.hpp302
1 files changed, 302 insertions, 0 deletions
diff --git a/3rdParty/Boost/src/boost/type_traits/detail/common_type_imp.hpp b/3rdParty/Boost/src/boost/type_traits/detail/common_type_imp.hpp
new file mode 100644
index 0000000..9e06282
--- /dev/null
+++ b/3rdParty/Boost/src/boost/type_traits/detail/common_type_imp.hpp
@@ -0,0 +1,302 @@
+/*******************************************************************************
+ * 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_signable_integral<T>
+ *
+ * This metafunction determines if T is an integral type which can be made
+ * signed or unsigned.
+ ******************************************************************************/
+
+template< class T >
+struct is_signable_integral
+ : mpl::or_< is_integral<T>, is_enum<T> >
+{ };
+template<>
+struct is_signable_integral< bool >
+ : false_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
+ : 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
+ : 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
+ : 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 T' and U' are both "signable integral types" (integral and enum
+ * types excepting bool), then:
+ * define the set of NominalCandidates to be
+ * { unsigned(T'), unsigned(U'), signed(T'), signed(U') }
+ * where unsigned(X) is make_unsigned<X>::type and signed(X) is
+ * make_signed<X>::type
+ * 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_signable_integral<V>::value && is_signable_integral<W>::value
+>
+struct nominal_candidates;
+
+template< class T, class U, class V, class W >
+struct nominal_candidates< T, U, V, W, false >
+{ typedef mpl::vector2<V,W> type; };
+
+template< class T, class U, class V, class W >
+struct nominal_candidates< T, U, V, W, true >
+{
+ typedef mpl::vector4<
+ typename make_unsigned<V>::type,
+ typename make_unsigned<W>::type,
+ typename make_signed<V>::type,
+ typename make_signed<W>::type
+ > 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
+ : 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
+ : 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
+