
On 8/14/2010 6:43 AM, vicente.botet wrote:
----- Original Message ----- From: "vicente.botet"<vicente.botet@wanadoo.fr> To:<boost@lists.boost.org> Sent: Saturday, August 14, 2010 1:15 PM Subject: Re: [boost] [chrono] [dependence of common_type on Boost.TypeOf] Hi Jeff,
Yes I see now better what was your idea. Have you tried to implement it?
I have. Unfortunately, 1) it will take some effort to remove dependencies on other in-house utilities; 2) my implementation is quite a bit more complex; and 3) the extra complexity is probably necessary. I will explain below.
I will try the approach to see what I can get, but I'm not sure to been able to manage with the ambiguous overloads.
I will comment on this below, as well.
Howard, what do you think about this approach? Have you already tried something like that?
Thanks, Vicente _______________________________________________
Hi again,
I have reached to manage with the ambiguous overloads and all the tests works as before.
I have do it as follows: [...template code removed...] #if 0 public: typedef BOOST_TYPEOF_TPL(m_f() ? m_t() : m_u()) type; #else typedef char (&yes)[1]; typedef char (&no)[2]; static yes deduce(T); static no deduce(U); public: typedef typename mpl::if_c< sizeof( deduce(m_f() ? m_t() : m_u()) ) == sizeof( yes ), T, U>::type type;
#endif [...more template code removed...]
As far as I know, this will generally only give the right result of common_type<T,U> for non-reference and non-pointer T's and U's. Unfortunately, it won't take care of cases such as common_type< int const *, int volatile * > -> int const volatile *. Reference types are even trickier, as their common_type could be either an lvalue reference (this is similar to the pointer case) or an rvalue. Here is a summary of the logic I use. For concreteness, we wish to compute common_type<T,U>, which is the type of the "conditional expression" (*), (bool_() ? t() : u()), where bool_() has type bool, t() has return type T, and u() has return type U. For simplicity, assume that cv qualifiers have already been stripped from T and U, as they don't affect the type of common_type<T,U>. First, we obtain a set of "candidate types", with the property that common_type<T,U> is among these candidate types. Once we have a finite set of candidate types, we can apply an extension of the "sizeof trick" (used above for deduce) to determine which of the candidates is the actual desired type. The set of candidate types will be constructed to make it easy to avoid ambiguous overloads, since we will remove duplicates, and either all candidate types will be reference types or all candidate types will be non-reference (and non-cv-qualified) types. To determine these candidate types, the logic goes roughly as follows (apply in order): (1) If T and U are reference types, say, T = T' & and U = U' &: If the conditional expression (*) is an rvalue, go on to (2) (this is a property that can be determined via another "sizeof trick"). Otherwise, the set of candidate types is { T' &, U' &, T' [cvU'] &, U' [cvT'] & }; where [cvX'] are the cv-qualifiers on X'; and assume duplicates are removed. (2) If T and U (after stripping any reference and cv qualifiers), are pointer types, say, T = T' * and U = U' *: The set of candidate types is { T' *, U' *, T' [cvU'] *, U' [cvT'] * }; where [cvX'] is as before; and assume duplicates are removed. (3) If T and U (after stripping any reference and cv qualifiers) are both builtin integral types: The set of candidate types is { T, U, make_signed(T), make_signed(U), make_unsigned(T), make_unsigned(U) }, with duplicates removed. This should catch any transfers of signed-ness or unsigned-ness. (4) If none of the above, then the set of candidate types is simply { T, U } (again, duplicates are removed, and these are the types after removal of reference and cv qualifiers). Case (4) is the case you've implemented in the code above, but (I think) it really should be the least prioritized case. I haven't rigorously tested this logic out, so I don't know if the preceding is a complete description of the conditional operator, but I think it should be pretty close. What do you think? - Jeff