Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r65251 - in sandbox/chrono/boost/type_traits/ext: . detail
From: vicente.botet_at_[hidden]
Date: 2010-09-04 09:19:57


Author: viboes
Date: 2010-09-04 09:19:57 EDT (Sat, 04 Sep 2010)
New Revision: 65251
URL: http://svn.boost.org/trac/boost/changeset/65251

Log:
Continue the library split with Boost.TypeTraits.Ext
Added:
   sandbox/chrono/boost/type_traits/ext/
   sandbox/chrono/boost/type_traits/ext/common_type.hpp (contents, props changed)
   sandbox/chrono/boost/type_traits/ext/detail/
   sandbox/chrono/boost/type_traits/ext/detail/common_type.hpp (contents, props changed)

Added: sandbox/chrono/boost/type_traits/ext/common_type.hpp
==============================================================================
--- (empty file)
+++ sandbox/chrono/boost/type_traits/ext/common_type.hpp 2010-09-04 09:19:57 EDT (Sat, 04 Sep 2010)
@@ -0,0 +1,197 @@
+// 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_TYPE_TRAITS_EXT_COMMON_TYPE_HPP
+#define BOOST_TYPE_TRAITS_EXT_COMMON_TYPE_HPP
+
+#include <boost/config.hpp>
+
+//----------------------------------------------------------------------------//
+#if defined(BOOST_NO_VARIADIC_TEMPLATES)
+#define BOOST_COMMON_TYPE_ARITY 3
+#endif
+
+//----------------------------------------------------------------------------//
+#if defined(BOOST_NO_DECLTYPE) && !defined(BOOST_COMMON_TYPE_DONT_USE_TYPEOF)
+#define BOOST_TYPEOF_SILENT
+#include <boost/typeof/typeof.hpp> // boost wonders never cease!
+#endif
+
+//----------------------------------------------------------------------------//
+#ifndef BOOST_NO_STATIC_ASSERT
+#define BOOST_COMMON_TYPE_STATIC_ASSERT(CND, MSG, TYPES) static_assert(CND,MSG)
+#elif defined(BOOST_COMMON_TYPE_USES_STATIC_ASSERT)
+#include <boost/static_assert.hpp>
+#define BOOST_COMMON_TYPE_STATIC_ASSERT(CND, MSG, TYPES) BOOST_STATIC_ASSERT(CND)
+#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)
+#elif defined(BOOST_COMMON_TYPE_USES_ARRAY_ASSERT)
+#define BOOST_COMMON_TYPE_CONCAT(A,B) A##B
+#define BOOST_COMMON_TYPE_NAME(A,B) BOOST_COMMON_TYPE_CONCAT(A,B)
+#define BOOST_COMMON_TYPE_STATIC_ASSERT(CND, MSG, TYPES) static char BOOST_COMMON_TYPE_NAME(__boost_common_type_test_,__LINE__)[CND]
+#else
+#define BOOST_COMMON_TYPE_STATIC_ASSERT(CND, MSG, TYPES)
+#endif
+
+#if !defined(BOOST_NO_STATIC_ASSERT) || !defined(BOOST_COMMON_TYPE_USES_MPL_ASSERT)
+#define BOOST_COMMON_TYPE_MUST_BE_A_COMPLE_TYPE "must be complete type"
+#endif
+
+#include <boost/type_traits/ext/detail/common_type.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/type_traits/is_void.hpp>
+#include <boost/type_traits/is_reference.hpp>
+#include <boost/type_traits/is_pointer.hpp>
+#include <boost/type_traits/remove_cv.hpp>
+
+//----------------------------------------------------------------------------//
+// //
+// C++03 implementation of //
+// 20.6.7 Other transformations [meta.trans.other] //
+// Written by Howard Hinnant //
+// Adapted for Boost by Beman Dawes //
+// //
+//----------------------------------------------------------------------------//
+
+namespace boost {
+
+// prototype
+#if !defined(BOOST_NO_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_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 <typename T,
+ bool = !is_reference<T>::value && ! is_pointer<T>::value && !is_void<T>::value>
+ struct add_rvalue_reference_helper
+ { typedef T type; };
+
+ template <typename T>
+ struct add_rvalue_reference_helper<T, true>
+ {
+#if !defined(BOOST_NO_RVALUE_REFERENCES)
+ typedef T&& type;
+#else
+ typedef T type;
+#endif
+ };
+
+ /// add_rvalue_reference
+ template <typename T>
+ struct add_rvalue_reference
+ : public add_rvalue_reference_helper<T>
+ { };
+
+ template <typename T>
+ struct add_rvalue_reference<T&>
+ { typedef T& type;
+ };
+
+
+ template <typename T>
+ typename add_rvalue_reference<T>::type declval();
+
+ 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_helper<T>::type declval_T(); // workaround gcc bug; not required by std
+ static typename add_rvalue_reference_helper<U>::type declval_U(); // workaround gcc bug; not required by std
+
+#if !defined(BOOST_NO_DECLTYPE)
+ public:
+ typedef decltype(declval<bool>() ? declval<T>() : declval<U>()) type;
+#elif defined(BOOST_COMMON_TYPE_DONT_USE_TYPEOF)
+#if 0
+ typedef char (&yes)[1];
+ typedef char (&no)[2];
+ //~ static yes deduce(typename add_rvalue_reference_helper<T>::type);
+ //~ static no deduce(typename add_rvalue_reference_helper<U>::type);
+ static yes deduce(T);
+ static no deduce(U);
+ public:
+ typedef typename mpl::if_c<
+ sizeof( deduce( declval_bool() ? declval_T() : declval_U() ) ) == sizeof( yes ),
+ T,
+ U
+ >::type type;
+#else
+ public:
+ typedef typename detail_type_traits_common_type::common_type_impl<
+ typename remove_cv<T>::type,
+ typename remove_cv<U>::type
+ >::type type;
+#endif
+#else
+ public:
+ 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_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_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 // BOOST_TYPE_TRAITS_EXT_COMMON_TYPE_HPP

Added: sandbox/chrono/boost/type_traits/ext/detail/common_type.hpp
==============================================================================
--- (empty file)
+++ sandbox/chrono/boost/type_traits/ext/detail/common_type.hpp 2010-09-04 09:19:57 EDT (Sat, 04 Sep 2010)
@@ -0,0 +1,324 @@
+/*******************************************************************************
+ * boost/type_traits/detail/common_type.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_EXT_DETAIL_COMMON_TYPE_HPP
+#define BOOST_TYPE_TRAITS_EXT_DETAIL_COMMON_TYPE_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>
+
+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
+{ };
+
+/*******************************************************************************
+ * anon_obj<T>() -> T
+ *
+ * This dummy function only serves to generate an expression of type T. This
+ * will be an rvalue expression if T is a non-reference type, and will be an
+ * lvalue expression if T is a reference type.
+ ******************************************************************************/
+
+template< class T > T anon_obj();
+
+/*******************************************************************************
+ * 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
+ * anon_obj< bool >() ? anon_obj<T>() : anon_obj<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(
+ anon_obj< bool >() ? anon_obj<T>() : anon_obj<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 = sizeof( ::boost::detail_type_traits_common_type::rvalue_test(
+ anon_obj< bool >() ? anon_obj<T>() : anon_obj<U>()
+ ) ) == sizeof( yes_type )
+>
+struct common_type_dispatch_on_rvalueness;
+
+template< class T, class U >
+struct common_type_dispatch_on_rvalueness< T, U, true >
+ : 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>
+{ };
+
+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
+
+//~ template< class T, class U >
+//~ struct common_type
+ //~ : detail_type_traits_common_type::common_type_impl<
+ //~ typename remove_cv<T>::type,
+ //~ typename remove_cv<U>::type
+ //~ >
+//~ { };
+
+} // namespace boost
+
+#endif // BOOST_TYPE_TRAITS_EXT_DETAIL_COMMON_TYPE_HPP


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk