26 #if ! defined (octave_oct_inttypes_h)
27 #define octave_oct_inttypes_h 1
29 #include "octave-config.h"
41 #if defined (OCTAVE_INT_USE_LONG_DOUBLE)
47 inline long double round (
long double x)
49 return std::roundl (
x);
52 inline long double isnan (
long double x)
54 return isnan (
static_cast<double> (
x));
70 return (
x >= 0 ?
x : -
x);
75 template <
int qsize,
bool q
signed>
88 #define OCTAVE_REGISTER_INT_TYPE(TYPE) \
90 class query_integer_type<sizeof (TYPE), \
91 std::numeric_limits<TYPE>::is_signed> \
95 static const bool registered = true; \
110 #undef OCTAVE_REGISTER_INT_TYPE
123 template <
typename T1,
typename T2>
127 static const bool pint = (
sizeof (T1) <
sizeof (
int)
128 &&
sizeof (T2) <
sizeof (
int));
130 static const bool t1sig = std::numeric_limits<T1>::is_signed;
131 static const bool t2sig = std::numeric_limits<T2>::is_signed;
139 : (
sizeof (T2) >
sizeof (T1) ?
sizeof (T2) :
sizeof (T1)));
148 template <
typename xop,
int size>
158 return xop::op (
x, y);
163 return xop::op (
x, y);
168 return (
x < 0) ? xop::ltval : xop::op (
static_cast<utype> (
x), y);
173 return (y < 0) ? xop::gtval : xop::op (
x,
static_cast<utype> (y));
184 #define OCTAVE_REGISTER_INT_CMP_OP(NM, OP) \
189 static const bool ltval = (0 OP 1); \
190 static const bool gtval = (1 OP 0); \
192 template <typename T> \
193 static bool op (T x, T y) { return x OP y; } \
203 #undef OCTAVE_REGISTER_INT_CMP_OP
208 #define OCTAVE_REGISTER_INT_CONST_OP(NM, VALUE) \
213 static const bool ltval = VALUE; \
214 static const bool gtval = VALUE; \
216 template <typename T> \
217 static bool op (T, T) { return VALUE; } \
223 #undef OCTAVE_REGISTER_INT_CONST_OP
227 template <
typename xop,
typename T1,
typename T2>
234 return uiop<xop,
sizeof (PT1)>::
op (
static_cast<PT1
> (
x),
235 static_cast<PT2
> (y));
242 template <
typename xop,
typename T>
243 static bool mop (T
x,
double y)
245 return xop::op (
static_cast<double> (
x), y);
248 template <
typename xop,
typename T>
249 static bool mop (
double x, T y)
251 return xop::op (
x,
static_cast<double> (y));
254 #if defined (OCTAVE_ENSURE_LONG_DOUBLE_OPERATIONS_ARE_NOT_TRUNCATED)
256 # define OCTAVE_DECLARE_EXTERNAL_LONG_DOUBLE_INT_CMP_OPS(T) \
257 template <typename xop> \
258 static OCTAVE_API bool external_mop (double, T); \
260 template <typename xop> \
261 static OCTAVE_API bool external_mop (T, double)
262 OCTAVE_DECLARE_EXTERNAL_LONG_DOUBLE_INT_CMP_OPS (int64_t);
263 OCTAVE_DECLARE_EXTERNAL_LONG_DOUBLE_INT_CMP_OPS (uint64_t);
270 #if defined (OCTAVE_INT_USE_LONG_DOUBLE)
272 # if defined (OCTAVE_ENSURE_LONG_DOUBLE_OPERATIONS_ARE_NOT_TRUNCATED)
274 # define OCTAVE_DEFINE_LONG_DOUBLE_INT_CMP_OP(T) \
275 template <typename xop> \
276 static bool mop (double x, T y) \
278 return external_mop<xop> (x, y); \
281 template <typename xop> \
282 static bool mop (T x, double y) \
284 return external_mop<xop> (x, y); \
289 # define OCTAVE_DEFINE_LONG_DOUBLE_INT_CMP_OP(T) \
290 template <typename xop> \
291 static bool mop (double x, T y) \
293 return xop::op (static_cast<long double> (x), \
294 static_cast<long double> (y)); \
297 template <typename xop> \
298 static bool mop (T x, double y) \
300 return xop::op (static_cast<long double> (x), \
301 static_cast<long double> (y)); \
314 # define OCTAVE_DEFINE_LONG_DOUBLE_INT_CMP_OP(T) \
315 template <typename xop> \
316 static OCTAVE_API bool emulate_mop (double, T); \
318 template <typename xop> \
319 static bool mop (double x, T y) \
321 return emulate_mop<xop> (x, y); \
324 template <typename xop> \
325 static OCTAVE_API bool emulate_mop (T, double); \
327 template <typename xop> \
328 static bool mop (T x, double y) \
330 return emulate_mop<xop> (x, y); \
338 #undef OCTAVE_DEFINE_LONG_DOUBLE_INT_CMP_OP
344 template <
typename T>
354 template <
typename S>
360 static const bool t_is_signed = std::numeric_limits<T>::is_signed;
361 static const bool s_is_signed = std::numeric_limits<S>::is_signed;
363 static const int t_size =
sizeof (T);
364 static const int s_size =
sizeof (S);
366 static const bool omit_chk_min
367 = (! s_is_signed || (t_is_signed && t_size >= s_size));
369 static const bool omit_chk_max
371 || (t_size == s_size && (! t_is_signed || s_is_signed)));
386 if (chk_min::op (value,
static_cast<S
> (
min_val ())))
388 else if (chk_max::op (value,
static_cast<S
> (
max_val ())))
391 return static_cast<T
> (value);
398 template <
typename S>
409 val *= (
static_cast<S
> (1) - (std::numeric_limits<S>::epsilon () / 2));
418 template <
typename S>
428 template <
typename T,
bool is_
signed>
435 template <
typename T>
442 static T
signum (T
x) {
return x ?
static_cast<T
> (1) :
static_cast<T
> (0); }
450 static T
minus (T) {
return static_cast<T
> (0); }
488 *
static_cast<mptype
> (y));
512 static T
rem (T
x, T y) {
return y != 0 ?
x % y : 0; }
516 static T
mod (T
x, T y) {
return y != 0 ?
x % y :
x; }
519 #if defined (OCTAVE_INT_USE_LONG_DOUBLE)
523 # if defined (OCTAVE_ENSURE_LONG_DOUBLE_OPERATIONS_ARE_NOT_TRUNCATED)
526 octave_external_uint64_uint64_mul (uint64_t, uint64_t);
536 long double p =
static_cast<long double> (
x) *
static_cast<long double> (y);
541 retval =
static_cast<uint64_t
> (p);
550 # if defined (OCTAVE_ENSURE_LONG_DOUBLE_OPERATIONS_ARE_NOT_TRUNCATED)
551 return octave_external_uint64_uint64_mul (
x, y);
553 return mul_internal (
x, y);
567 template <
typename T>
590 : ((
x < 0) ? -
x :
x));
597 return ((
x > 0) ? 1 : 0) - __signbit (
x);
657 *
static_cast<mptype
> (y));
686 z -= 1 - (__signbit (
x) << 1);
699 z += 1 - (__signbit (
x) << 1);
708 return y != 0 ?
x % y : 0;
718 return (
r == 0) ? 0 : (((
r < 0) != (y < 0)) ?
r + y :
r);
725 #if defined (OCTAVE_INT_USE_LONG_DOUBLE)
729 # if defined (OCTAVE_ENSURE_LONG_DOUBLE_OPERATIONS_ARE_NOT_TRUNCATED)
732 octave_external_int64_int64_mul (int64_t, int64_t);
742 long double p =
static_cast<long double> (
x) *
static_cast<long double> (y);
749 retval =
static_cast<int64_t
> (p);
758 # if defined (OCTAVE_ENSURE_LONG_DOUBLE_OPERATIONS_ARE_NOT_TRUNCATED)
759 return octave_external_int64_int64_mul (
x, y);
761 return mul_internal (
x, y);
776 template <
typename T>
781 template <
typename T>
794 #if defined (OCTAVE_HAVE_OVERLOAD_CHAR_INT8_TYPES)
798 : m_ival (
octave_int_base<T>::truncate_int (static_cast<unsigned char> (c)))
809 #if defined (OCTAVE_INT_USE_LONG_DOUBLE)
818 template <
typename U>
822 template <
typename U>
832 T
value (
void)
const {
return m_ival; }
834 const unsigned char *
iptr (
void)
const
836 return reinterpret_cast<const unsigned char *
> (& m_ival);
841 bool bool_value (
void)
const {
return static_cast<bool> (value ()); }
843 char char_value (
void)
const {
return static_cast<char> (value ()); }
845 double double_value (
void)
const {
return static_cast<double> (value ()); }
847 float float_value (
void)
const {
return static_cast<float> (value ()); }
849 operator T (
void)
const {
return value (); }
854 #define OCTAVE_INT_UN_OP(OPNAME, NAME) \
855 inline octave_int<T> \
858 return octave_int_arith<T>::NAME (m_ival); \
865 #undef OCTAVE_INT_UN_OP
874 #define OCTAVE_INT_BIN_OP(OP, NAME, ARGT) \
875 inline octave_int<T> \
876 operator OP (const ARGT& y) const \
878 return octave_int_arith<T>::NAME (m_ival, y); \
881 inline octave_int<T>& \
882 operator OP##= (const ARGT& y) \
884 m_ival = octave_int_arith<T>::NAME (m_ival, y); \
896 #undef OCTAVE_INT_BIN_OP
901 static int nbits (
void) {
return std::numeric_limits<T>::digits; }
915 template <
typename T>
922 template <
typename T>
935 template <
typename T>
947 template <
typename T>
951 template <
typename T>
955 template <
typename T>
959 template <
typename T>
963 template <
typename T>
971 template <
typename T>
975 template <
typename T>
981 #define OCTAVE_INT_CMP_OP(OP, NAME) \
982 template <typename T1, typename T2> \
984 operator OP (const octave_int<T1>& x, const octave_int<T2>& y) \
986 return octave_int_cmp_op::op<octave_int_cmp_op::NAME, T1, T2> (x.value (), y.value ()); \
996 #undef OCTAVE_INT_CMP_OP
998 template <
typename T>
1002 os << ival.
value ();
1006 template <
typename T>
1007 inline std::istream&
1023 inline std::ostream&
1026 os << static_cast<int> (ival.
value ());
1032 inline std::ostream&
1035 os << static_cast<unsigned int> (ival.
value ());
1041 inline std::istream&
1046 ival =
static_cast<int8_t
> (tmp);
1052 inline std::istream&
1055 unsigned int tmp = 0;
1057 ival =
static_cast<uint8_t
> (tmp);
1064 #define OCTAVE_INT_BITCMP_OP(OP) \
1065 template <typename T> \
1067 operator OP (const octave_int<T>& x, const octave_int<T>& y) \
1069 return x.value () OP y.value (); \
1076 #undef OCTAVE_INT_BITCMP_OP
1079 template <
typename T>
1085 return (a <<
n) & mask;
1087 return (a >> -
n) & mask;
1092 #if defined (OCTAVE_ENSURE_LONG_DOUBLE_OPERATIONS_ARE_NOT_TRUNCATED)
1094 # define OCTAVE_DECLARE_EXTERNAL_LONG_DOUBLE_INT_OP(T, OP) \
1095 extern OCTAVE_API T \
1096 external_double_ ## T ## _ ## OP (double x, T y); \
1098 extern OCTAVE_API T \
1099 external_ ## T ## _double_ ## OP (T x, double y)
1101 # define OCTAVE_DECLARE_EXTERNAL_LONG_DOUBLE_INT_OPS(T) \
1102 OCTAVE_DECLARE_EXTERNAL_LONG_DOUBLE_INT_OP (T, add); \
1103 OCTAVE_DECLARE_EXTERNAL_LONG_DOUBLE_INT_OP (T, sub); \
1104 OCTAVE_DECLARE_EXTERNAL_LONG_DOUBLE_INT_OP (T, mul); \
1105 OCTAVE_DECLARE_EXTERNAL_LONG_DOUBLE_INT_OP (T, div)
1107 OCTAVE_DECLARE_EXTERNAL_LONG_DOUBLE_INT_OPS (
octave_int64);
1108 OCTAVE_DECLARE_EXTERNAL_LONG_DOUBLE_INT_OPS (
octave_uint64);
1112 #define OCTAVE_INT_DOUBLE_BIN_OP0(OP) \
1113 template <typename T> \
1114 inline octave_int<T> \
1115 operator OP (const octave_int<T>& x, const double& y) \
1117 return octave_int<T> (static_cast<double> (x) OP y); \
1120 template <typename T> \
1121 inline octave_int<T> \
1122 operator OP (const double& x, const octave_int<T>& y) \
1124 return octave_int<T> (x OP static_cast<double> (y)); \
1127 #if defined (OCTAVE_INT_USE_LONG_DOUBLE)
1131 # if defined (OCTAVE_ENSURE_LONG_DOUBLE_OPERATIONS_ARE_NOT_TRUNCATED)
1133 # define OCTAVE_INT_DOUBLE_BIN_OP(OP, NAME) \
1134 OCTAVE_INT_DOUBLE_BIN_OP0(OP) \
1137 inline octave_int64 \
1138 operator OP (const double& x, const octave_int64& y) \
1140 return external_double_octave_int64_ ## NAME (x, y); \
1144 inline octave_uint64 \
1145 operator OP (const double& x, const octave_uint64& y) \
1147 return external_double_octave_uint64_ ## NAME (x, y); \
1151 inline octave_int64 \
1152 operator OP (const octave_int64& x, const double& y) \
1154 return external_octave_int64_double_ ## NAME (x, y); \
1158 inline octave_uint64 \
1159 operator OP (const octave_uint64& x, const double& y) \
1161 return external_octave_uint64_double_ ## NAME (x, y); \
1166 # define OCTAVE_INT_DOUBLE_BIN_OP(OP, NAME) \
1167 OCTAVE_INT_DOUBLE_BIN_OP0(OP) \
1170 inline octave_int64 \
1171 operator OP (const double& x, const octave_int64& y) \
1173 return octave_int64 (x OP static_cast<long double> (y.value ())); \
1177 inline octave_uint64 \
1178 operator OP (const double& x, const octave_uint64& y) \
1180 return octave_uint64 (x OP static_cast<long double> (y.value ())); \
1184 inline octave_int64 \
1185 operator OP (const octave_int64& x, const double& y) \
1187 return octave_int64 (static_cast<long double> (x.value ()) OP y); \
1191 inline octave_uint64 \
1192 operator OP (const octave_uint64& x, const double& y) \
1194 return octave_uint64 (static_cast<long double> (x.value ()) OP y); \
1203 # define OCTAVE_INT_DOUBLE_BIN_OP(OP, NAME) \
1204 OCTAVE_INT_DOUBLE_BIN_OP0(OP) \
1207 OCTAVE_API octave_int64 \
1208 operator OP (const double&, const octave_int64&); \
1211 OCTAVE_API octave_uint64 \
1212 operator OP (const double&, const octave_uint64&); \
1215 OCTAVE_API octave_int64 \
1216 operator OP (const octave_int64&, const double&); \
1219 OCTAVE_API octave_uint64 \
1220 operator OP (const octave_uint64&, const double&);
1229 #undef OCTAVE_INT_DOUBLE_BIN_OP0
1230 #undef OCTAVE_INT_DOUBLE_BIN_OP
1231 #undef OCTAVE_DECLARE_EXTERNAL_LONG_DOUBLE_INT_OP
1232 #undef OCTAVE_DECLARE_EXTERNAL_LONG_DOUBLE_INT_OPS
1234 #define OCTAVE_INT_DOUBLE_CMP_OP(OP, NAME) \
1235 template <typename T> \
1237 operator OP (const octave_int<T>& x, const double& y) \
1239 return octave_int_cmp_op::mop<octave_int_cmp_op::NAME> (x.value (), y); \
1242 template <typename T> \
1244 operator OP (const double& x, const octave_int<T>& y) \
1246 return octave_int_cmp_op::mop<octave_int_cmp_op::NAME> (x, y.value ()); \
1256 #undef OCTAVE_INT_DOUBLE_CMP_OP
1260 #define OCTAVE_INT_FLOAT_BIN_OP(OP) \
1261 template <typename T> \
1262 inline octave_int<T> \
1263 operator OP (const octave_int<T>& x, float y) \
1265 return x OP static_cast<double> (y); \
1268 template <typename T> \
1269 inline octave_int<T> \
1270 operator OP (float x, const octave_int<T>& y) \
1272 return static_cast<double> (x) OP y; \
1280 #undef OCTAVE_INT_FLOAT_BIN_OP
1282 #define OCTAVE_INT_FLOAT_CMP_OP(OP) \
1283 template <typename T> \
1285 operator OP (const octave_int<T>& x, const float& y) \
1287 return x OP static_cast<double> (y); \
1290 template <typename T> \
1292 operator OP (const float& x, const octave_int<T>& y) \
1294 return static_cast<double> (x) OP y; \
1304 #undef OCTAVE_INT_FLOAT_CMP_OP
1306 template <
typename T>
1310 const T xv =
x.value ();
1311 const T yv = y.
value ();
1316 template <
typename T>
1320 const T xv =
x.value ();
1321 const T yv = y.
value ();
1328 #define OCTAVE_INT_IDX_TYPE_BIN_OP(OP) \
1329 template <typename T> \
1330 inline octave_int<T> \
1331 operator OP (const octave_int<T>& x, octave_idx_type y) \
1333 return x OP octave_int<T> (y); \
1336 template <typename T> \
1337 inline octave_int<T> \
1338 operator OP (octave_idx_type x, const octave_int<T>& y) \
1340 return octave_int<T> (x) OP y; \
1348 #undef OCTAVE_INT_IDX_TYPE_BIN_OP
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 OCTAVE_API 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 const OCTAVE_API char * type_name()
static int byte_size(void)
~octave_int(void)=default
static octave_int< T > max(void)
bool bool_value(void) const
static octave_int< T > min(void)
char char_value(void) const
const unsigned char * iptr(void) const
static const octave_int s_one
double double_value(void) const
float float_value(void) const
octave_int(const octave_int< U > &i)
octave_int(const octave_int< T > &)=default
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
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)
class OCTAVE_TEMPLATE_API octave_int
#define OCTAVE_INT_DOUBLE_BIN_OP(OP, NAME)
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)
#define OCTAVE_INT_UN_OP(OPNAME, NAME)
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)
#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_IDX_TYPE_BIN_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)
bool isnan(const octave_int< T > &)
#define OCTAVE_REGISTER_INT_CONST_OP(NM, VALUE)
OCTAVE_API octave_int< T > pow(const octave_int< T > &, const octave_int< T > &)
#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 operator!(const octave_value &a)
static const bool registered