#include <limits>
#include <utility>
#include <iostream>
template < typename T>
struct is_integral {
static bool const value = std:: numeric_limits < T> :: is_integer ;
} ;
template < typename T>
struct is_real {
static bool const value = not is_integral< T> :: value ;
} ;
template < typename T, typename L, typename R>
struct are_all_integral {
static bool const value = is_integral< T> :: value and
is_integral< L> :: value and
is_integral< R> :: value ;
} ;
template < typename T, typename L, typename R>
struct is_any_real {
static bool const value = is_real< T> :: value or
is_real< L> :: value or
is_real< R> :: value ;
} ;
template < typename T, typename L, typename R>
typename std:: enable_if < are_all_integral< T, L, R> :: value , bool > :: type
inRange( T x, L start, R end) {
typedef typename std:: common_type < T, L, R> :: type common;
std:: cout << " inRange(" << x << ", " << start << ", " << end << ") -> Integral\n " ;
return static_cast < common> ( x) >= static_cast < common> ( start) and
static_cast < common> ( x) <= static_cast < common> ( end) ;
}
template < typename T, typename L, typename R>
typename std:: enable_if < is_any_real< T, L, R> :: value , bool > :: type
inRange( T x, L start, R end) {
typedef typename std:: common_type < T, L, R> :: type common;
std:: cout << " inRange(" << x << ", " << start << ", " << end << ") -> Real\n " ;
return static_cast < common> ( x) >= static_cast < common> ( start) and
static_cast < common> ( x) <= static_cast < common> ( end) ;
}
int main( ) {
std:: cout << "Pure cases\n " ;
inRange( 1 , 2 , 3 ) ;
inRange( 1.5 , 2.5 , 3.5 ) ;
std:: cout << "Mixed int/unsigned\n " ;
inRange( 1u, 2 , 3 ) ;
inRange( 1 , 2u, 3 ) ;
inRange( 1 , 2 , 3u) ;
std:: cout << "Mixed float/double\n " ;
inRange( 1.5f , 2.5 , 3.5 ) ;
inRange( 1.5 , 2.5f , 3.5 ) ;
inRange( 1.5 , 2.5 , 3.5f ) ;
std:: cout << "Mixed int/double\n " ;
inRange( 1.5 , 2 , 3 ) ;
inRange( 1 , 2.5 , 3 ) ;
inRange( 1 , 2 , 3.5 ) ;
std:: cout << "Mixed int/double, with more doubles\n " ;
inRange( 1.5 , 2.5 , 3 ) ;
inRange( 1.5 , 2 , 3.5 ) ;
inRange( 1 , 2.5 , 3.5 ) ;
}
I2luY2x1ZGUgPGxpbWl0cz4KI2luY2x1ZGUgPHV0aWxpdHk+CiNpbmNsdWRlIDxpb3N0cmVhbT4KCnRlbXBsYXRlIDx0eXBlbmFtZSBUPgpzdHJ1Y3QgaXNfaW50ZWdyYWwgewogIHN0YXRpYyBib29sIGNvbnN0IHZhbHVlID0gc3RkOjpudW1lcmljX2xpbWl0czxUPjo6aXNfaW50ZWdlcjsKfTsKCnRlbXBsYXRlIDx0eXBlbmFtZSBUPgpzdHJ1Y3QgaXNfcmVhbCB7CiAgc3RhdGljIGJvb2wgY29uc3QgdmFsdWUgPSBub3QgaXNfaW50ZWdyYWw8VD46OnZhbHVlOwp9OwoKdGVtcGxhdGUgPHR5cGVuYW1lIFQsIHR5cGVuYW1lIEwsIHR5cGVuYW1lIFI+CnN0cnVjdCBhcmVfYWxsX2ludGVncmFsIHsKICBzdGF0aWMgYm9vbCBjb25zdCB2YWx1ZSA9IGlzX2ludGVncmFsPFQ+Ojp2YWx1ZSBhbmQKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzX2ludGVncmFsPEw+Ojp2YWx1ZSBhbmQKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzX2ludGVncmFsPFI+Ojp2YWx1ZTsKfTsKCnRlbXBsYXRlIDx0eXBlbmFtZSBULCB0eXBlbmFtZSBMLCB0eXBlbmFtZSBSPgpzdHJ1Y3QgaXNfYW55X3JlYWwgewogIHN0YXRpYyBib29sIGNvbnN0IHZhbHVlID0gaXNfcmVhbDxUPjo6dmFsdWUgb3IKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzX3JlYWw8TD46OnZhbHVlIG9yCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc19yZWFsPFI+Ojp2YWx1ZTsKfTsKCgp0ZW1wbGF0ZSA8dHlwZW5hbWUgVCwgdHlwZW5hbWUgTCwgdHlwZW5hbWUgUj4KdHlwZW5hbWUgc3RkOjplbmFibGVfaWY8YXJlX2FsbF9pbnRlZ3JhbDxULCBMLCBSPjo6dmFsdWUsIGJvb2w+Ojp0eXBlCmluUmFuZ2UoVCB4LCBMIHN0YXJ0LCBSIGVuZCkgewogIHR5cGVkZWYgdHlwZW5hbWUgc3RkOjpjb21tb25fdHlwZTxULCBMLCBSPjo6dHlwZSBjb21tb247CiAgc3RkOjpjb3V0IDw8ICIgIGluUmFuZ2UoIiA8PCB4IDw8ICIsICIgPDwgc3RhcnQgPDwgIiwgIiA8PCBlbmQgPDwgIikgLT4gSW50ZWdyYWxcbiI7CiAgcmV0dXJuIHN0YXRpY19jYXN0PGNvbW1vbj4oeCkgPj0gc3RhdGljX2Nhc3Q8Y29tbW9uPihzdGFydCkgYW5kCiAgICAgICAgIHN0YXRpY19jYXN0PGNvbW1vbj4oeCkgPD0gc3RhdGljX2Nhc3Q8Y29tbW9uPihlbmQpOwp9Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgVCwgdHlwZW5hbWUgTCwgdHlwZW5hbWUgUj4KdHlwZW5hbWUgc3RkOjplbmFibGVfaWY8aXNfYW55X3JlYWw8VCwgTCwgUj46OnZhbHVlLCBib29sPjo6dHlwZQppblJhbmdlKFQgeCwgTCBzdGFydCwgUiBlbmQpIHsKICB0eXBlZGVmIHR5cGVuYW1lIHN0ZDo6Y29tbW9uX3R5cGU8VCwgTCwgUj46OnR5cGUgY29tbW9uOwogIHN0ZDo6Y291dCA8PCAiICBpblJhbmdlKCIgPDwgeCA8PCAiLCAiIDw8IHN0YXJ0IDw8ICIsICIgPDwgZW5kIDw8ICIpIC0+IFJlYWxcbiI7CiAgcmV0dXJuIHN0YXRpY19jYXN0PGNvbW1vbj4oeCkgPj0gc3RhdGljX2Nhc3Q8Y29tbW9uPihzdGFydCkgYW5kCiAgICAgICAgIHN0YXRpY19jYXN0PGNvbW1vbj4oeCkgPD0gc3RhdGljX2Nhc3Q8Y29tbW9uPihlbmQpOwp9CgppbnQgbWFpbigpIHsKICBzdGQ6OmNvdXQgPDwgIlB1cmUgY2FzZXNcbiI7CiAgaW5SYW5nZSgxLCAyLCAzKTsKICBpblJhbmdlKDEuNSwgMi41LCAzLjUpOwoKICBzdGQ6OmNvdXQgPDwgIk1peGVkIGludC91bnNpZ25lZFxuIjsKICBpblJhbmdlKDF1LCAyLCAzKTsKICBpblJhbmdlKDEsIDJ1LCAzKTsKICBpblJhbmdlKDEsIDIsIDN1KTsKCiAgc3RkOjpjb3V0IDw8ICJNaXhlZCBmbG9hdC9kb3VibGVcbiI7CiAgaW5SYW5nZSgxLjVmLCAyLjUsIDMuNSk7CiAgaW5SYW5nZSgxLjUsIDIuNWYsIDMuNSk7CiAgaW5SYW5nZSgxLjUsIDIuNSwgMy41Zik7CgogIHN0ZDo6Y291dCA8PCAiTWl4ZWQgaW50L2RvdWJsZVxuIjsKICBpblJhbmdlKDEuNSwgMiwgMyk7CiAgaW5SYW5nZSgxLCAyLjUsIDMpOwogIGluUmFuZ2UoMSwgMiwgMy41KTsKCiAgc3RkOjpjb3V0IDw8ICJNaXhlZCBpbnQvZG91YmxlLCB3aXRoIG1vcmUgZG91Ymxlc1xuIjsKICBpblJhbmdlKDEuNSwgMi41LCAzKTsKICBpblJhbmdlKDEuNSwgMiwgMy41KTsKICBpblJhbmdlKDEsIDIuNSwgMy41KTsKfQ==
stdout
Pure cases
inRange(1, 2, 3) -> Integral
inRange(1.5, 2.5, 3.5) -> Real
Mixed int/unsigned
inRange(1, 2, 3) -> Integral
inRange(1, 2, 3) -> Integral
inRange(1, 2, 3) -> Integral
Mixed float/double
inRange(1.5, 2.5, 3.5) -> Real
inRange(1.5, 2.5, 3.5) -> Real
inRange(1.5, 2.5, 3.5) -> Real
Mixed int/double
inRange(1.5, 2, 3) -> Real
inRange(1, 2.5, 3) -> Real
inRange(1, 2, 3.5) -> Real
Mixed int/double, with more doubles
inRange(1.5, 2.5, 3) -> Real
inRange(1.5, 2, 3.5) -> Real
inRange(1, 2.5, 3.5) -> Real