26 #if ! defined (octave_oct_inttypes_h)
27 #define octave_oct_inttypes_h 1
29 #include "octave-config.h"
52 #if defined (OCTAVE_INT_USE_LONG_DOUBLE)
58 inline long double round (
long double x)
60 return std::roundl (
x);
63 inline long double isnan (
long double x)
65 return isnan (
static_cast<double> (
x));
80 return (
x >= 0 ?
x : -
x);
85 template <
int qsize,
bool q
signed>
98 #define OCTAVE_REGISTER_INT_TYPE(TYPE) \
100 class query_integer_type<sizeof (TYPE), \
101 std::numeric_limits<TYPE>::is_signed> \
105 static const bool registered = true; \
120 #undef OCTAVE_REGISTER_INT_TYPE
133 template <
typename T1,
typename T2>
137 static const bool pint = (
sizeof (T1) <
sizeof (
int)
138 &&
sizeof (T2) <
sizeof (
int));
140 static const bool t1sig = std::numeric_limits<T1>::is_signed;
141 static const bool t2sig = std::numeric_limits<T2>::is_signed;
149 : (
sizeof (T2) >
sizeof (T1) ?
sizeof (T2) :
sizeof (T1)));
158 template <
typename xop,
int size>
168 return xop::op (
x, y);
173 return xop::op (
x, y);
178 return (
x < 0) ? xop::ltval : xop::op (
static_cast<utype> (
x), y);
183 return (y < 0) ? xop::gtval : xop::op (
x,
static_cast<utype> (y));
194 #define OCTAVE_REGISTER_INT_CMP_OP(NM, OP) \
199 static const bool ltval = (0 OP 1); \
200 static const bool gtval = (1 OP 0); \
202 template <typename T> \
203 static bool op (T x, T y) { return x OP y; } \
213 #undef OCTAVE_REGISTER_INT_CMP_OP
218 #define OCTAVE_REGISTER_INT_CONST_OP(NM, VALUE) \
223 static const bool ltval = VALUE; \
224 static const bool gtval = VALUE; \
226 template <typename T> \
227 static bool op (T, T) { return VALUE; } \
233 #undef OCTAVE_REGISTER_INT_CONST_OP
237 template <
typename xop,
typename T1,
typename T2>
244 return uiop<xop,
sizeof (PT1)>::
op (
static_cast<PT1
> (
x),
245 static_cast<PT2
> (y));
252 template <
typename xop,
typename T>
253 static bool mop (T
x,
double y)
255 return xop::op (
static_cast<double> (
x), y);
258 template <
typename xop,
typename T>
259 static bool mop (
double x, T y)
261 return xop::op (
x,
static_cast<double> (y));
264 #if defined (OCTAVE_ENSURE_LONG_DOUBLE_OPERATIONS_ARE_NOT_TRUNCATED)
266 # define OCTAVE_DECLARE_EXTERNAL_LONG_DOUBLE_INT_CMP_OPS(T) \
267 template <typename xop> \
268 static OCTAVE_API bool external_mop (double, T); \
270 template <typename xop> \
271 static OCTAVE_API bool external_mop (T, double)
273 OCTAVE_DECLARE_EXTERNAL_LONG_DOUBLE_INT_CMP_OPS (int64_t);
274 OCTAVE_DECLARE_EXTERNAL_LONG_DOUBLE_INT_CMP_OPS (uint64_t);
281 #if defined (OCTAVE_INT_USE_LONG_DOUBLE)
283 # if defined (OCTAVE_ENSURE_LONG_DOUBLE_OPERATIONS_ARE_NOT_TRUNCATED)
285 # define OCTAVE_DEFINE_LONG_DOUBLE_INT_CMP_OP(T) \
286 template <typename xop> \
287 static bool mop (double x, T y) \
289 return external_mop<xop> (x, y); \
292 template <typename xop> \
293 static bool mop (T x, double y) \
295 return external_mop<xop> (x, y); \
300 # define OCTAVE_DEFINE_LONG_DOUBLE_INT_CMP_OP(T) \
301 template <typename xop> \
302 static bool mop (double x, T y) \
304 return xop::op (static_cast<long double> (x), \
305 static_cast<long double> (y)); \
308 template <typename xop> \
309 static bool mop (T x, double y) \
311 return xop::op (static_cast<long double> (x), \
312 static_cast<long double> (y)); \
325 # define OCTAVE_DEFINE_LONG_DOUBLE_INT_CMP_OP(T) \
326 template <typename xop> \
327 static OCTAVE_API bool emulate_mop (double, T); \
329 template <typename xop> \
330 static bool mop (double x, T y) \
332 return emulate_mop<xop> (x, y); \
335 template <typename xop> \
336 static OCTAVE_API bool emulate_mop (T, double); \
338 template <typename xop> \
339 static bool mop (T x, double y) \
341 return emulate_mop<xop> (x, y); \
349 #undef OCTAVE_DEFINE_LONG_DOUBLE_INT_CMP_OP
355 template <
typename T>
365 template <
typename S>
371 static const bool t_is_signed = std::numeric_limits<T>::is_signed;
372 static const bool s_is_signed = std::numeric_limits<S>::is_signed;
374 static const int t_size =
sizeof (T);
375 static const int s_size =
sizeof (S);
377 static const bool omit_chk_min
378 = (! s_is_signed || (t_is_signed && t_size >= s_size));
380 static const bool omit_chk_max
382 || (t_size == s_size && (! t_is_signed || s_is_signed)));
397 if (chk_min::op (value,
static_cast<S
> (
min_val ())))
399 else if (chk_max::op (value,
static_cast<S
> (
max_val ())))
402 return static_cast<T
> (value);
409 template <
typename S>
420 val *= (
static_cast<S
> (1) - (std::numeric_limits<S>::epsilon () / 2));
429 template <
typename S>
439 template <
typename T,
bool is_
signed>
446 template <
typename T>
453 static T
signum (T
x) {
return x ?
static_cast<T
> (1) :
static_cast<T
> (0); }
461 static T
minus (T) {
return static_cast<T
> (0); }
499 *
static_cast<mptype
> (y));
523 static T
rem (T
x, T y) {
return y != 0 ?
x % y : 0; }
527 static T
mod (T
x, T y) {
return y != 0 ?
x % y :
x; }
530 #if defined (OCTAVE_INT_USE_LONG_DOUBLE)
534 # if defined (OCTAVE_ENSURE_LONG_DOUBLE_OPERATIONS_ARE_NOT_TRUNCATED)
536 extern OCTAVE_API uint64_t
537 octave_external_uint64_uint64_mul (uint64_t, uint64_t);
547 long double p =
static_cast<long double> (
x) *
static_cast<long double> (y);
552 retval =
static_cast<uint64_t
> (p);
561 # if defined (OCTAVE_ENSURE_LONG_DOUBLE_OPERATIONS_ARE_NOT_TRUNCATED)
562 return octave_external_uint64_uint64_mul (
x, y);
564 return mul_internal (
x, y);
578 template <
typename T>
601 : ((
x < 0) ? -
x :
x));
608 return ((
x > 0) ? 1 : 0) - __signbit (
x);
668 *
static_cast<mptype
> (y));
697 z -= 1 - (__signbit (
x) << 1);
710 z += 1 - (__signbit (
x) << 1);
719 return y != 0 ?
x % y : 0;
729 return (
r == 0) ? 0 : (((
r < 0) != (y < 0)) ?
r + y :
r);
736 #if defined (OCTAVE_INT_USE_LONG_DOUBLE)
740 # if defined (OCTAVE_ENSURE_LONG_DOUBLE_OPERATIONS_ARE_NOT_TRUNCATED)
742 extern OCTAVE_API int64_t
743 octave_external_int64_int64_mul (int64_t, int64_t);
753 long double p =
static_cast<long double> (
x) *
static_cast<long double> (y);
760 retval =
static_cast<int64_t
> (p);
769 # if defined (OCTAVE_ENSURE_LONG_DOUBLE_OPERATIONS_ARE_NOT_TRUNCATED)
770 return octave_external_int64_int64_mul (
x, y);
772 return mul_internal (
x, y);
787 template <
typename T>
792 template <
typename T>
804 #if defined (OCTAVE_HAVE_OVERLOAD_CHAR_INT8_TYPES)
808 : m_ival (
octave_int_base<T>::truncate_int (static_cast<unsigned char> (c)))
819 #if defined (OCTAVE_INT_USE_LONG_DOUBLE)
828 template <
typename U>
832 template <
typename U>
842 T
value (
void)
const {
return m_ival; }
844 const unsigned char *
iptr (
void)
const
846 return reinterpret_cast<const unsigned char *
> (& m_ival);
851 bool bool_value (
void)
const {
return static_cast<bool> (value ()); }
853 char char_value (
void)
const {
return static_cast<char> (value ()); }
855 double double_value (
void)
const {
return static_cast<double> (value ()); }
857 float float_value (
void)
const {
return static_cast<float> (value ()); }
859 operator T (
void)
const {
return value (); }
864 #define OCTAVE_INT_UN_OP(OPNAME, NAME) \
865 inline octave_int<T> \
868 return octave_int_arith<T>::NAME (m_ival); \
875 #undef OCTAVE_INT_UN_OP
878 #define OCTAVE_INT_BIN_OP(OP, NAME, ARGT) \
879 inline octave_int<T> \
880 operator OP (const ARGT& y) const \
882 return octave_int_arith<T>::NAME (m_ival, y); \
885 inline octave_int<T>& \
886 operator OP##= (const ARGT& y) \
888 m_ival = octave_int_arith<T>::NAME (m_ival, y); \
900 #undef OCTAVE_INT_BIN_OP
905 static int nbits (
void) {
return std::numeric_limits<T>::digits; }
923 template <
typename T>
930 template <
typename T>
943 template <
typename T>
954 template <
typename T>
958 template <
typename T>
962 template <
typename T>
966 template <
typename T>
970 template <
typename T>
978 template <
typename T>
982 template <
typename T>
988 #define OCTAVE_INT_CMP_OP(OP, NAME) \
989 template <typename T1, typename T2> \
991 operator OP (const octave_int<T1>& x, const octave_int<T2>& y) \
993 return octave_int_cmp_op::op<octave_int_cmp_op::NAME, T1, T2> (x.value (), y.value ()); \
1003 #undef OCTAVE_INT_CMP_OP
1005 template <
typename T>
1006 inline std::ostream&
1009 os << ival.
value ();
1013 template <
typename T>
1014 inline std::istream&
1030 inline std::ostream&
1033 os << static_cast<int> (ival.
value ());
1039 inline std::ostream&
1042 os << static_cast<unsigned int> (ival.
value ());
1048 inline std::istream&
1053 ival =
static_cast<int8_t
> (tmp);
1059 inline std::istream&
1062 unsigned int tmp = 0;
1064 ival =
static_cast<uint8_t
> (tmp);
1071 #define OCTAVE_INT_BITCMP_OP(OP) \
1072 template <typename T> \
1074 operator OP (const octave_int<T>& x, const octave_int<T>& y) \
1076 return x.value () OP y.value (); \
1083 #undef OCTAVE_INT_BITCMP_OP
1086 template <
typename T>
1092 return (a <<
n) & mask;
1094 return (a >> -
n) & mask;
1099 #if defined (OCTAVE_ENSURE_LONG_DOUBLE_OPERATIONS_ARE_NOT_TRUNCATED)
1101 # define OCTAVE_DECLARE_EXTERNAL_LONG_DOUBLE_INT_OP(T, OP) \
1102 extern OCTAVE_API T \
1103 external_double_ ## T ## _ ## OP (double x, T y); \
1105 extern OCTAVE_API T \
1106 external_ ## T ## _double_ ## OP (T x, double y)
1108 # define OCTAVE_DECLARE_EXTERNAL_LONG_DOUBLE_INT_OPS(T) \
1109 OCTAVE_DECLARE_EXTERNAL_LONG_DOUBLE_INT_OP (T, add); \
1110 OCTAVE_DECLARE_EXTERNAL_LONG_DOUBLE_INT_OP (T, sub); \
1111 OCTAVE_DECLARE_EXTERNAL_LONG_DOUBLE_INT_OP (T, mul); \
1112 OCTAVE_DECLARE_EXTERNAL_LONG_DOUBLE_INT_OP (T, div)
1114 OCTAVE_DECLARE_EXTERNAL_LONG_DOUBLE_INT_OPS (
octave_int64);
1115 OCTAVE_DECLARE_EXTERNAL_LONG_DOUBLE_INT_OPS (
octave_uint64);
1119 #define OCTAVE_INT_DOUBLE_BIN_OP0(OP) \
1120 template <typename T> \
1121 inline octave_int<T> \
1122 operator OP (const octave_int<T>& x, const double& y) \
1124 return octave_int<T> (static_cast<double> (x) OP y); \
1127 template <typename T> \
1128 inline octave_int<T> \
1129 operator OP (const double& x, const octave_int<T>& y) \
1131 return octave_int<T> (x OP static_cast<double> (y)); \
1134 #if defined (OCTAVE_INT_USE_LONG_DOUBLE)
1138 # if defined (OCTAVE_ENSURE_LONG_DOUBLE_OPERATIONS_ARE_NOT_TRUNCATED)
1140 # define OCTAVE_INT_DOUBLE_BIN_OP(OP, NAME) \
1141 OCTAVE_INT_DOUBLE_BIN_OP0(OP) \
1144 inline octave_int64 \
1145 operator OP (const double& x, const octave_int64& y) \
1147 return external_double_octave_int64_ ## NAME (x, y); \
1151 inline octave_uint64 \
1152 operator OP (const double& x, const octave_uint64& y) \
1154 return external_double_octave_uint64_ ## NAME (x, y); \
1158 inline octave_int64 \
1159 operator OP (const octave_int64& x, const double& y) \
1161 return external_octave_int64_double_ ## NAME (x, y); \
1165 inline octave_uint64 \
1166 operator OP (const octave_uint64& x, const double& y) \
1168 return external_octave_uint64_double_ ## NAME (x, y); \
1173 # define OCTAVE_INT_DOUBLE_BIN_OP(OP, NAME) \
1174 OCTAVE_INT_DOUBLE_BIN_OP0(OP) \
1177 inline octave_int64 \
1178 operator OP (const double& x, const octave_int64& y) \
1180 return octave_int64 (x OP static_cast<long double> (y.value ())); \
1184 inline octave_uint64 \
1185 operator OP (const double& x, const octave_uint64& y) \
1187 return octave_uint64 (x OP static_cast<long double> (y.value ())); \
1191 inline octave_int64 \
1192 operator OP (const octave_int64& x, const double& y) \
1194 return octave_int64 (static_cast<long double> (x.value ()) OP y); \
1198 inline octave_uint64 \
1199 operator OP (const octave_uint64& x, const double& y) \
1201 return octave_uint64 (static_cast<long double> (x.value ()) OP y); \
1210 # define OCTAVE_INT_DOUBLE_BIN_OP(OP, NAME) \
1211 OCTAVE_INT_DOUBLE_BIN_OP0(OP) \
1214 OCTAVE_API octave_int64 \
1215 operator OP (const double&, const octave_int64&); \
1218 OCTAVE_API octave_uint64 \
1219 operator OP (const double&, const octave_uint64&); \
1222 OCTAVE_API octave_int64 \
1223 operator OP (const octave_int64&, const double&); \
1226 OCTAVE_API octave_uint64 \
1227 operator OP (const octave_uint64&, const double&);
1236 #undef OCTAVE_INT_DOUBLE_BIN_OP0
1237 #undef OCTAVE_INT_DOUBLE_BIN_OP
1238 #undef OCTAVE_DECLARE_EXTERNAL_LONG_DOUBLE_INT_OP
1239 #undef OCTAVE_DECLARE_EXTERNAL_LONG_DOUBLE_INT_OPS
1241 #define OCTAVE_INT_DOUBLE_CMP_OP(OP, NAME) \
1242 template <typename T> \
1244 operator OP (const octave_int<T>& x, const double& y) \
1246 return octave_int_cmp_op::mop<octave_int_cmp_op::NAME> (x.value (), y); \
1249 template <typename T> \
1251 operator OP (const double& x, const octave_int<T>& y) \
1253 return octave_int_cmp_op::mop<octave_int_cmp_op::NAME> (x, y.value ()); \
1263 #undef OCTAVE_INT_DOUBLE_CMP_OP
1267 #define OCTAVE_INT_FLOAT_BIN_OP(OP) \
1268 template <typename T> \
1269 inline octave_int<T> \
1270 operator OP (const octave_int<T>& x, float y) \
1272 return x OP static_cast<double> (y); \
1275 template <typename T> \
1276 inline octave_int<T> \
1277 operator OP (float x, const octave_int<T>& y) \
1279 return static_cast<double> (x) OP y; \
1287 #undef OCTAVE_INT_FLOAT_BIN_OP
1289 #define OCTAVE_INT_FLOAT_CMP_OP(OP) \
1290 template <typename T> \
1292 operator OP (const octave_int<T>& x, const float& y) \
1294 return x OP static_cast<double> (y); \
1297 template <typename T> \
1299 operator OP (const float& x, const octave_int<T>& y) \
1301 return static_cast<double> (x) OP y; \
1311 #undef OCTAVE_INT_FLOAT_CMP_OP
1313 template <
typename T>
1317 const T xv =
x.value ();
1318 const T yv = y.
value ();
1323 template <
typename T>
1327 const T xv =
x.value ();
1328 const T yv = y.
value ();
charNDArray max(char d, const charNDArray &m)
charNDArray min(char d, const charNDArray &m)
static T lshift(T x, int n)
static T mul_internal(T x, T y)
static T rshift(T x, int n)
static T rshift(T x, int n)
query_integer_type< sizeof(T), false >::type UT
static T mul_internal(T x, T y)
static T lshift(T x, int n)
uint64_t mul_internal(uint64_t x, uint64_t y)
static T truncate_int(const S &value)
static S compute_threshold(S val, T orig_val)
static T convert_real(const S &value)
query_integer_type< psize, psig >::type type
static bool op(stype x, stype y)
static bool op(stype x, utype y)
query_integer_type< size, false >::type utype
static bool op(utype x, stype y)
query_integer_type< size, true >::type stype
static bool op(utype x, utype y)
static bool op(T1 x, T2 y)
static bool mop(T x, double y)
static bool mop(double x, T y)
static int byte_size(void)
~octave_int(void)=default
static octave_int< T > max(void)
bool bool_value(void) const
void * mex_get_data(void) const
static octave_int< T > min(void)
char char_value(void) const
const unsigned char * iptr(void) const
static const char * type_name()
double double_value(void) const
float float_value(void) const
octave_int(const octave_int< U > &i)
static const octave_int one
octave_int(const octave_int< T > &)=default
F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE * d
F77_RET_T const F77_DBLE * x
std::complex< double > w(std::complex< double > z, double relerr=0)
octave_int< uint32_t > octave_uint32
#define OCTAVE_INT_DOUBLE_BIN_OP(OP, NAME)
octave_int< int32_t > octave_int32
octave_int< T > operator+(const octave_int< T > &x, const double &y)
octave_int< T > rem(const octave_int< T > &x, const octave_int< T > &y)
octave_int< int16_t > octave_int16
#define OCTAVE_INT_UN_OP(OPNAME, NAME)
octave_int< int8_t > octave_int8
octave_int< T > bitshift(const octave_int< T > &a, int n, const octave_int< T > &mask=std::numeric_limits< T >::max())
std::ostream & operator<<(std::ostream &os, const octave_int< T > &ival)
octave_int< int64_t > octave_int64
#define OCTAVE_REGISTER_INT_CMP_OP(NM, OP)
#define OCTAVE_INT_BIN_OP(OP, NAME, ARGT)
#define OCTAVE_REGISTER_INT_TYPE(TYPE)
#define OCTAVE_INT_BITCMP_OP(OP)
#define OCTAVE_INT_DOUBLE_CMP_OP(OP, NAME)
octave_int< T > xmin(const octave_int< T > &x, const octave_int< T > &y)
octave_int< T > mod(const octave_int< T > &x, const octave_int< T > &y)
#define OCTAVE_INT_FLOAT_BIN_OP(OP)
OCTAVE_API octave_int< T > powf(const float &a, const octave_int< T > &b)
#define OCTAVE_REGISTER_INT_CONST_OP(NM, VALUE)
octave_int< uint64_t > octave_uint64
OCTAVE_API octave_int< T > pow(const octave_int< T > &, const octave_int< T > &)
octave_int< uint16_t > octave_uint16
octave_int< uint8_t > octave_uint8
#define OCTAVE_INT_CMP_OP(OP, NAME)
#define OCTAVE_DEFINE_LONG_DOUBLE_INT_CMP_OP(T)
#define OCTAVE_INT_FLOAT_CMP_OP(OP)
std::istream & operator>>(std::istream &is, octave_int< T > &ival)
octave_int< T > xmax(const octave_int< T > &x, const octave_int< T > &y)
octave_value::octave_value(const Array< char > &chm, char type) return retval
octave_value operator!(const octave_value &a)
static const bool registered