arithmetic meta functions and traits

Is there any use for something like this? Following compiles on MSVC 9.0. Despite the simplicity of the final template, it was *NOT* easy to get this working given that there's about 10 ways you should be able to do this according to the standard, but poor SFINAE support makes it next to impossible to get your compiler to accept anything. Since it doesn't do anything highly fancy, I would wager it works on GCC and other compilers as well, although it needs to be tested. struct no_type { }; #define MAKE_BINOP_METAFUNCTIONS(op, binop, traits) \ template<typename T, typename U> no_type operator op (T, U); \ template<typename T, typename U> \ struct traits \ { \ typedef BOOST_TYPEOF(T() op U()) type; \ }; \ template<typename T, typename U> \ struct binop \ { \ private: \ typedef typename traits<T,U>::type result_type; \ public: \ static const bool value = !boost::is_same<result_type,no_type>::value; \ }; MAKE_BINOP_METAFUNCTIONS(+, is_addable, addition_traits); MAKE_BINOP_METAFUNCTIONS(-, is_subtractable, subtraction_traits); MAKE_BINOP_METAFUNCTIONS(/, is_dividable, division_traits); MAKE_BINOP_METAFUNCTIONS(*, is_multipliable, multiplication_traits); Obviously you can define other operators similarly, as well as unary operators. Zach

Zachary Turner wrote:
Is there any use for something like this? Following compiles on MSVC 9.0. Despite the simplicity of the final template, it was *NOT* easy to get this working given that there's about 10 ways you should be able to do this according to the standard, but poor SFINAE support makes it next to impossible to get your compiler to accept anything. Since it doesn't do anything highly fancy, I would wager it works on GCC and other compilers as well, although it needs to be tested.
I think there is already something like this proposed as an extension to type_traits and use sizeof tricks to do that. -- ___________________________________________ Joel Falcou - Assistant Professor PARALL Team - LRI - Universite Paris Sud XI Tel : (+33)1 69 15 66 35

On Sun, Dec 6, 2009 at 2:28 AM, joel falcou <joel.falcou@lri.fr> wrote:
Zachary Turner wrote:
Is there any use for something like this? Following compiles on MSVC 9.0. Despite the simplicity of the final template, it was *NOT* easy to get this working given that there's about 10 ways you should be able to do this according to the standard, but poor SFINAE support makes it next to impossible to get your compiler to accept anything. Since it doesn't do anything highly fancy, I would wager it works on GCC and other compilers as well, although it needs to be tested.
I think there is already something like this proposed as an extension to type_traits and use sizeof tricks to do that.
The sizeof trick I'm aware of is comparing the size against an "unlikely" size N, something very large such as 43280 such that you're unlikely to come across two types P and Q such that sizeof(P()+Q()) == N. Is there any reason this method is preferable to the method I used above though, where it can provably never result in a false negative? Zach

Zachary Turner wrote:
The sizeof trick I'm aware of is comparing the size against an "unlikely" size N, something very large such as 43280 such that you're unlikely to come across two types P and Q such that sizeof(P()+Q()) == N. Is there any reason this method is preferable to the method I used above though, where it can provably never result in a false negative?
You get it wrong, that's not what we call the sizeof trick. Here is an example for checking for operator+: #include <boost/type_traits/remove_cv.hpp> #include <boost/static_assert.hpp> namespace detail { struct tag {}; struct any { template <class T> any(T const&); }; tag operator+(any const&, any const&); tag operator,(tag,int); char (& check(tag))[2]; template <class T> char check(T const&); template <class T> struct impl { static typename boost::remove_cv<T>::type& x; static const bool value = sizeof(check(((x + x),0))) == 1; }; } template <class T> struct is_addable : detail::impl<T> {}; struct A{}; int main() { BOOST_STATIC_ASSERT(is_addable<int>::value); BOOST_STATIC_ASSERT(!is_addable<A>::value); } And as I say, Frederic BRon already provided such traits in the upcoming type_traits revision I think -- ___________________________________________ Joel Falcou - Assistant Professor PARALL Team - LRI - Universite Paris Sud XI Tel : (+33)1 69 15 66 35

On Sun, Dec 6, 2009 at 3:19 AM, joel falcou <joel.falcou@lri.fr> wrote:
Zachary Turner wrote:
The sizeof trick I'm aware of is comparing the size against an "unlikely" size N, something very large such as 43280 such that you're unlikely to come across two types P and Q such that sizeof(P()+Q()) == N. Is there any reason this method is preferable to the method I used above though, where it can provably never result in a false negative?
You get it wrong, that's not what we call the sizeof trick.
Here is an example for checking for operator+:
#include <boost/type_traits/remove_cv.hpp> #include <boost/static_assert.hpp>
namespace detail { struct tag {};
struct any { template <class T> any(T const&); };
tag operator+(any const&, any const&);
tag operator,(tag,int);
Wow, overloaded operator comma. I don't know whether to laugh or cry. In any case, thanks for the code snippet :) Zach
participants (2)
-
joel falcou
-
Zachary Turner