[type_traits] any interest in integral_promotion?

Class template integral_promotion<T> returns promoted type for all types listed in [conv.prom] except bit-fields. For other types it's noop. If you're interested I can try to boostify it. -- Alexander Nasonov // // integral_promotion.hpp // #include <boost/mpl/at.hpp> #include <boost/mpl/eval_if.hpp> #include <boost/mpl/identity.hpp> #include <boost/mpl/or.hpp> #include <boost/mpl/vector.hpp> #include <boost/type_traits/is_enum.hpp> #include <boost/type_traits/is_integral.hpp> #include <boost/type_traits/is_same.hpp> template<class T> struct is_short_integer : boost::mpl::or_< boost::is_same<T, char> , boost::is_same<T, signed char> , boost::is_same<T, unsigned char> , boost::is_same<T, signed short> , boost::is_same<T, unsigned short> > { }; template<int N> struct sized_type { typedef char (&type)[N]; }; sized_type<1>::type tester(int); sized_type<2>::type tester(unsigned int); sized_type<3>::type tester(long); sized_type<4>::type tester(unsigned long); template<class T> struct integral_promotion_impl { static T testee; // undefined typedef typename boost::mpl::at_c< boost::mpl::vector<int, unsigned int, long, unsigned long> , sizeof(tester(+testee)) - 1 // Unary plus ^ promotes testee. >::type type; }; template<class T> struct integral_promotion : boost::mpl::eval_if< boost::mpl::or_< is_short_integer<T> , boost::is_same<T,bool> , boost::is_enum<T> > , integral_promotion_impl<T> , boost::mpl::identity<T> > { }; // // test.cpp // // Tested on gcc 3.4.4 (cygming special) and // Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 13.10.3077 for 80x86 #include "integral_promotion.hpp" #include <boost/mpl/assert.hpp> #include <boost/type_traits/is_same.hpp> enum IntEnum { IntEnum_max = 1 }; int main() { BOOST_MPL_ASSERT(( boost::is_same< integral_promotion<char>::type, int> )); BOOST_MPL_ASSERT(( boost::is_same< integral_promotion<bool>::type, int> )); BOOST_MPL_ASSERT(( boost::is_same< integral_promotion<int>::type, int> )); BOOST_MPL_ASSERT(( boost::is_same< integral_promotion<long>::type, long> )); BOOST_MPL_ASSERT(( boost::is_same< integral_promotion<IntEnum>::type, int> )); }

"Alexander Nasonov" <alnsn-boost@yandex.ru> writes:
Class template integral_promotion<T> returns promoted type for all types listed in [conv.prom] except bit-fields. For other types it's noop. If you're interested I can try to boostify it.
I'm interested. I don't have an immediate need but I think it's important anyway. -- Dave Abrahams Boost Consulting www.boost-consulting.com

"David Abrahams" <dave@boost-consulting.com> wrote in message news:uzmti8rk1.fsf@boost-consulting.com...
"Alexander Nasonov" <alnsn-boost@yandex.ru> writes:
Class template integral_promotion<T> returns promoted type for all types listed in [conv.prom] except bit-fields. For other types it's noop. If you're interested I can try to boostify it.
I'm interested. I don't have an immediate need but I think it's important anyway.
Isnt any use case for this covered by Boost.Typeof ? Andy Little

Andy Little <andy <at> servocomm.freeserve.co.uk> writes:
Isnt any use case for this covered by Boost.Typeof ?
Quote from Boost.Typeof documentation: Other integral types, such as *enums*, need to be described explicitly with the BOOST_TYPEOF_INTEGRAL macro, like (BOOST_TYPEOF_INTEGRAL(MyEnum)) -- Alexander Nasonov

"Alexander Nasonov" <alnsn-boost@yandex.ru> wrote in message news:loom.20050622T171035-650@post.gmane.org...
Andy Little <andy <at> servocomm.freeserve.co.uk> writes:
Isnt any use case for this covered by Boost.Typeof ?
Quote from Boost.Typeof documentation:
Other integral types, such as *enums*, need to be described explicitly with the BOOST_TYPEOF_INTEGRAL macro, like (BOOST_TYPEOF_INTEGRAL(MyEnum))
I think that applies when the type of the enum is taken, but where required enums are promoted to some integer type,dependent on numeric value. In what other situation is promotion required? #define BOOST_TYPEOF_COMPLIANT #include <boost/typeof/typeof.hpp> #include <iostream> struct X{ enum id{x,y}; }; int main() { BOOST_AUTO( result , X::x + X::y); std::cout << typeid(result).name() <<'\n'; } Andy Little

"Andy Little" <andy@servocomm.freeserve.co.uk> wrote in message news:d9ccs0$qm7$2@sea.gmane.org...
"Alexander Nasonov" <alnsn-boost@yandex.ru> wrote in message news:loom.20050622T171035-650@post.gmane.org...
Andy Little <andy <at> servocomm.freeserve.co.uk> writes:
Isnt any use case for this covered by Boost.Typeof ?
Quote from Boost.Typeof documentation:
Other integral types, such as *enums*, need to be described explicitly
with
the BOOST_TYPEOF_INTEGRAL macro, like (BOOST_TYPEOF_INTEGRAL(MyEnum))
I think that applies when the type of the enum is taken, but where required enums are promoted to some integer type,dependent on numeric value. In what other situation is promotion required?
#define BOOST_TYPEOF_COMPLIANT #include <boost/typeof/typeof.hpp> #include <iostream>
struct X{ enum id{x,y}; };
int main() { BOOST_AUTO( result , X::x + X::y); std::cout << typeid(result).name() <<'\n'; }
Andy Little
FWIW, something like this: template<class T> struct promoted { typedef BOOST_TYPEOF_TPL(T()+T()) type; }; Would work on any integral type without registration. Enums can't be the result of a promotion, so no need to worry about their registration. Regards, Arkadiy

FWIW, something like this: template<class T> struct promoted { typedef BOOST_TYPEOF_TPL(T()+T()) type; };
Unary plus is slightly shorter then binary plus: BOOST_TYPEOF_TPL(+T()) :)
Would work on any integral type without registration. Enums can't be the result of a promotion, so no need to worry about their registration.
My code is very lightweight typeof simulation with only four types: 1 - int 2 - unsigned int 3 - long 4 - unsigned long BTW, I forgot to add wchar_t support to posted integral_promotion.hpp. -- Alexander Nasonov

FWIW, something like this: template<class T> struct promoted { typedef BOOST_TYPEOF_TPL(T()+T()) type; };
Unary plus is slightly shorter then binary plus: BOOST_TYPEOF_TPL(+T()) :)
Would work on any integral type without registration. Enums can't be the result of a promotion, so no need to worry about
"Alexander Nasonov" <alnsn-boost@yandex.ru> wrote in message news:CGEAJCADLHHFBJBADMJFAEDBCCAA.alnsn-boost@yandex.ru... their
registration.
My code is very lightweight typeof simulation with only four types: 1 - int 2 - unsigned int 3 - long 4 - unsigned long
One thing I can say for sure -- this will be much easier to port :) Regards, Arkadiy

Andy Little <andy <at> servocomm.freeserve.co.uk> writes:
"Arkadiy Vertleyb" <vertleyb <at> hotmail.com> wrote
FWIW, something like this:
template<class T> struct promoted { typedef BOOST_TYPEOF_TPL(T()+T()) type; };
But where would you need this ?
To implement int_fast_t? http://www.boost.org/libs/integer/integer.htm -- Alexander Nasonov

"Alexander Nasonov" <alnsn-boost@yandex.ru> wrote in message news:loom.20050623T155302-606@post.gmane.org...
Andy Little <andy <at> servocomm.freeserve.co.uk> writes:
"Arkadiy Vertleyb" <vertleyb <at> hotmail.com> wrote
FWIW, something like this:
template<class T> struct promoted { typedef BOOST_TYPEOF_TPL(T()+T()) type; };
But where would you need this ?
To implement int_fast_t?
To check that the result is capable of holding the argument ? After reading the standard on this I guess that it would be useful to have a representation of the promotion rules. As you point out the need here.. There must be other cases too. Andy Little

But where would you need this ?
To implement int_fast_t?
Sorry, but why do you need it for that? the only choices for int_fast_t are: int or some type wider than int that happens to be "faster" on the platform in question. Still trying to understand what this ones for... John.

John Maddock writes:
Sorry, but why do you need it for that? the only choices for int_fast_t are:
int
or
some type wider than int that happens to be "faster" on the platform in question.
May be you right. An example of converting slow char to fast int attracted my attention and I posted a reference. Enums are out of scope of int_fast_t but even if they were, they are usually as fast as int (except for special cases like -fshort-enums flag on g++).
Still trying to understand what this ones for... John.
Well, if it's not performance then it's a size of application ;) If some function template treats enumerations as numeric then converting all enums to promoted types reduces number of instantiated functions. Typical example is integer to string conversion. BTW, why promotions exist in C/C++? -- Alexander Nasonov

Still trying to understand what this ones for... John.
Well, if it's not performance then it's a size of application ;) If some function template treats enumerations as numeric then converting all enums to promoted types reduces number of instantiated functions. Typical example is integer to string conversion.
OK, that's reasonable.
BTW, why promotions exist in C/C++?
If you search the std for (4.5) you'll find: Prior to applying a binary operator to two integer types. When accessing the value of an enum. When evaluating an integral non-type template argument. When passing an integral type through ellipsis in a function call. John.

Andy Little wrote:
"David Abrahams" <dave@boost-consulting.com> wrote in message news:uzmti8rk1.fsf@boost-consulting.com...
"Alexander Nasonov" <alnsn-boost@yandex.ru> writes:
Class template integral_promotion<T> returns promoted type for all types listed in [conv.prom] except bit-fields. For other types it's noop. If you're interested I can try to boostify it.
I'm interested. I don't have an immediate need but I think it's important anyway.
Isnt any use case for this covered by Boost.Typeof ?
Even if it is, that's a pretty heavy-weight solution. Jonathan

"Jonathan Turkanis" <technews@kangaroologic.com> wrote in message news:d9bvve$h8v$1@sea.gmane.org...
Andy Little wrote:
"David Abrahams" <dave@boost-consulting.com> wrote in message news:uzmti8rk1.fsf@boost-consulting.com...
"Alexander Nasonov" <alnsn-boost@yandex.ru> writes:
Class template integral_promotion<T> returns promoted type for all types listed in [conv.prom] except bit-fields. For other types it's noop. If you're interested I can try to boostify it.
I'm interested. I don't have an immediate need but I think it's important anyway.
Isnt any use case for this covered by Boost.Typeof ?
Even if it is, that's a pretty heavy-weight solution.
The implementation may be heavyweight but useage is lightweight. integers are registered automatically. regards Andy Little

David Abrahams <dave <at> boost-consulting.com> writes:
"Alexander Nasonov" <alnsn-boost <at> yandex.ru> writes:
Class template integral_promotion<T> returns promoted type for all types listed in [conv.prom] except bit-fields. For other types it's noop. If you're interested I can try to boostify it.
I'm interested. I don't have an immediate need but I think it's important anyway.
I've uploaded promote.tar.gz to http://boost-sandbox.sourceforge.net/vault/ In principle, tests compile on VC free version, various versions of gcc (>=3.2. 2), borland (without enums) and SunPro 5.3. I'm still not sure about an interface. Metafunction is called promote_integral. It recogizes cv qualifiers but discards them. References are not promoted. That is, short cv -> int short cv& -> short cv& std::string cv -> std::string std::string cv& -> std::string cv& Rationale for this is to be close to rvalues but the result isn't satisfactory. I'll rework it as soon as I find better solution. -- Alexander Nasonov
participants (6)
-
Alexander Nasonov
-
Andy Little
-
Arkadiy Vertleyb
-
David Abrahams
-
John Maddock
-
Jonathan Turkanis