teditor  1.8.0@@fee5e94
Terminal based editor written in C++
number.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <stdint.h>
4 #include <cmath>
5 #include <string>
6 #include "core/utils.h"
7 
8 namespace std {
9 template <typename T> T sq(T in) { return in * in; }
10 template <typename T> T cube(T in) { return in * in * in; }
11 }; // namespace std
12 
13 namespace teditor {
14 namespace calc {
15 
16 #define OP(b, op) do { \
17  if (isInt && b.isInt) { \
18  i = i op b.i; \
19  } else if (isInt && !b.isInt) { \
20  isInt = false; \
21  f = FloatT(i) op b.f; \
22  } else if (!isInt && b.isInt) { \
23  f = f op FloatT(b.i); \
24  } else { \
25  f = f op b.f; \
26  } \
27  } while(0); \
28  return *this
29 
30 #define B_OP(b, op) do { \
31  if (isInt && b.isInt) return i op b.i; \
32  if (isInt && !b.isInt) return FloatT(i) op b.f; \
33  if (!isInt && b.isInt) return f op FloatT(b.i); \
34  return f op b.f; \
35  } while(0)
36 
37 namespace {
38 template <typename T>
39 T toNumber(const std::string& str, bool& processed);
40 template <>
41 int32_t toNumber(const std::string& str, bool& processed) {
42  size_t pos;
43  auto i = std::stoi(str, &pos);
44  processed = pos == str.size();
45  return i;
46 }
47 template <>
48 int64_t toNumber(const std::string& str, bool& processed) {
49  size_t pos;
50  auto i = std::stol(str, &pos);
51  processed = pos == str.size();
52  return i;
53 }
54 template <>
55 float toNumber(const std::string& str, bool& processed) {
56  size_t pos;
57  auto i = std::stof(str, &pos);
58  processed = pos == str.size();
59  return i;
60 }
61 template <>
62 double toNumber(const std::string& str, bool& processed) {
63  size_t pos;
64  auto i = std::stod(str, &pos);
65  processed = pos == str.size();
66  return i;
67 }
68 } // anonymous namespace
69 
75 template <typename IntT, typename FloatT>
76 struct Number {
78 
80  union {
81  IntT i;
82  FloatT f;
83  }; // union
85  bool isInt;
86 
87  Number() : i(0), isInt(true) {}
88  Number(IntT v) : i(v), isInt(true) {}
89  Number(FloatT v) : f(v), isInt(false) {}
90  Number(const Num& n) : i(n.i), isInt(n.isInt) {}
91  Number(const std::string& str) : i(0), isInt(true) {
92  bool processed;
93  IntT tmpi = toNumber<IntT>(str, processed);
94  if (processed) {
95  isInt = true;
96  i = tmpi;
97  return;
98  }
99  FloatT tmpf = toNumber<FloatT>(str, processed);
100  if (processed) {
101  isInt = false;
102  f = tmpf;
103  return;
104  }
105  ASSERT(false, "Incorrect number passed '%s'!", str.c_str());
106  }
107 
108  const Num& operator=(const Num& n) {
109  i = n.i;
110  isInt = n.isInt;
111  return *this;
112  }
113 
114  Num& operator+() { return *this; }
116  if (isInt) i = -i;
117  else f = -f;
118  return *this;
119  }
120 
121  // inplace operators
122  const Num& operator+=(const Num& b) { OP(b, +); }
123  const Num& operator-=(const Num& b) { OP(b, -); }
124  const Num& operator*=(const Num& b) { OP(b, *); }
125  const Num& operator/=(const Num& b) { OP(b, /); }
126 
127  // comparisons
128  bool operator==(const Num& b) const { B_OP(b, ==); }
129  bool operator!=(const Num& b) const { B_OP(b, !=); }
130  bool operator<(const Num& b) const { B_OP(b, <); }
131  bool operator<=(const Num& b) const { B_OP(b, <=); }
132  bool operator>(const Num& b) const { B_OP(b, >); }
133  bool operator>=(const Num& b) const { B_OP(b, >=); }
134 
135  // conversions
136  Num toInt() const {
137  Num ret(*this);
138  if (!ret.isInt) {
139  ret.isInt = true;
140  ret.i = IntT(ret.f);
141  }
142  return ret;
143  }
144  Num toFloat() const {
145  Num ret(*this);
146  if (ret.isInt) {
147  ret.isInt = false;
148  ret.f = FloatT(ret.i);
149  }
150  return ret;
151  }
152 
153  static const Num e;
154  static const Num pi;
155  static const Num nan;
156  static const Num log2e;
157  static const Num log10e;
158  static const Num sqrt2;
159  static const Num sqrt1_2;
160 }; // struct Number
161 
162 #undef B_OP
163 #undef OP
164 
165 
166 #define CONST(var, val) \
167  template <typename I, typename F> \
168  const Number<I, F> Number<I, F>::var((F)val)
169 CONST(e, M_E);
170 CONST(pi, M_PI);
171 CONST(nan, NAN);
172 CONST(log2e, M_LOG2E);
173 CONST(log10e, M_LOG10E);
174 CONST(sqrt2, M_SQRT2);
175 CONST(sqrt1_2, M_SQRT1_2);
176 #undef CONST
177 
178 
179 // operator overloads
180 template <typename I, typename F>
182  Number<I, F> ret = a;
183  ret += b;
184  return ret;
185 }
186 template <typename I, typename F>
188  Number<I, F> ret = a;
189  ret -= b;
190  return ret;
191 }
192 template <typename I, typename F>
194  Number<I, F> ret = a;
195  ret *= b;
196  return ret;
197 }
198 template <typename I, typename F>
200  Number<I, F> ret = a;
201  ret /= b;
202  return ret;
203 }
204 
205 // generic functions
206 #define FUNC(name) \
207  template <typename I, typename F> \
208  Number<I, F> name(const Number<I, F>& in) { \
209  Number<I, F> out; \
210  out.isInt = in.isInt; \
211  if (out.isInt) { \
212  out.i = std::name(in.i); \
213  } else { \
214  out.f = std::name(in.f); \
215  } \
216  return out; \
217  }
218 FUNC(sq);
219 FUNC(cube);
220 #undef FUNC
221 
222 // floating point functions
223 #define FP_FUNC(name) \
224  template <typename I, typename F> \
225  Number<I, F> name(const Number<I, F>& in) { \
226  Number<I, F> out; \
227  out.isInt = false; \
228  out.f = std::name(in.isInt ? F(in.i) : in.f); \
229  return out; \
230  }
231 FP_FUNC(abs);
232 FP_FUNC(sin);
233 FP_FUNC(cos)
234 FP_FUNC(tan);
235 FP_FUNC(asin);
236 FP_FUNC(acos)
237 FP_FUNC(atan);
238 FP_FUNC(sinh);
239 FP_FUNC(cosh)
240 FP_FUNC(tanh);
241 FP_FUNC(asinh);
242 FP_FUNC(acosh)
243 FP_FUNC(atanh);
244 FP_FUNC(sqrt);
245 FP_FUNC(cbrt);
246 FP_FUNC(log);
247 FP_FUNC(log10);
248 FP_FUNC(exp);
249 FP_FUNC(floor);
250 FP_FUNC(ceil);
251 FP_FUNC(round);
252 #undef FP_FUNC
253 template <typename I, typename F>
254 Number<I, F> toInt(const Number<I, F>& a) { return a.toInt(); }
255 template <typename I, typename F>
256 Number<I, F> toFloat(const Number<I, F>& a) { return a.toFloat(); }
257 
258 #define FP_FUNC2(name) \
259  template <typename I, typename F> \
260  Number<I, F> name(const Number<I, F>& in1, const Number<I, F>& in2) { \
261  Number<I, F> out; \
262  out.isInt = false; \
263  out.f = std::name(in1.isInt ? F(in1.i) : in1.f, \
264  in2.isInt ? F(in2.i) : in2.f); \
265  return out; \
266  }
267 FP_FUNC2(pow);
268 FP_FUNC2(hypot);
269 #undef FP_FUNC2
270 
273 
274 } // namespace calc
275 } // namespace teditor
teditor::calc::Number::e
static const Num e
Definition: number.h:153
teditor::calc::Number::log10e
static const Num log10e
Definition: number.h:157
teditor::calc::Number::operator<
bool operator<(const Num &b) const
Definition: number.h:130
std::sq
T sq(T in)
Definition: number.h:9
teditor::calc::Number::operator-
Num & operator-()
Definition: number.h:115
teditor::calc::Number
Core number used for computing in the calculator.
Definition: number.h:76
teditor::calc::Number::operator!=
bool operator!=(const Num &b) const
Definition: number.h:129
OP
#define OP(b, op)
Definition: number.h:16
teditor::calc::toFloat
Number< I, F > toFloat(const Number< I, F > &a)
Definition: number.h:256
teditor::calc::Number::sqrt1_2
static const Num sqrt1_2
Definition: number.h:159
std::cube
T cube(T in)
Definition: number.h:10
teditor::calc::CONST
CONST(e, M_E)
B_OP
#define B_OP(b, op)
Definition: number.h:30
teditor::calc::Number::toInt
Num toInt() const
Definition: number.h:136
teditor::calc::Number::log2e
static const Num log2e
Definition: number.h:156
teditor::calc::operator+
Number< I, F > operator+(const Number< I, F > &a, const Number< I, F > &b)
Definition: number.h:181
teditor::calc::FP_FUNC2
FP_FUNC2(pow)
teditor::calc::FP_FUNC
FP_FUNC(abs)
teditor::calc::toInt
Number< I, F > toInt(const Number< I, F > &a)
Definition: number.h:254
teditor::calc::Number::operator>
bool operator>(const Num &b) const
Definition: number.h:132
teditor::calc::Number::operator+
Num & operator+()
Definition: number.h:114
utils.h
teditor::calc::Number::Number
Number()
Definition: number.h:87
teditor::calc::Number::Num
Number< IntT, FloatT > Num
Definition: number.h:77
teditor::calc::operator*
Number< I, F > operator*(const Number< I, F > &a, const Number< I, F > &b)
Definition: number.h:193
teditor::calc::Num32
Number< int32_t, float > Num32
Definition: number.h:271
teditor::calc::Number::toFloat
Num toFloat() const
Definition: number.h:144
ASSERT
#define ASSERT(check, fmt,...)
Macro to assert with runtime_error exception if the check fails.
Definition: utils.h:35
teditor::calc::Number::operator-=
const Num & operator-=(const Num &b)
Definition: number.h:123
teditor::calc::Number::Number
Number(IntT v)
Definition: number.h:88
teditor::calc::Number::Number
Number(const std::string &str)
Definition: number.h:91
teditor::calc::operator/
Number< I, F > operator/(const Number< I, F > &a, const Number< I, F > &b)
Definition: number.h:199
teditor::calc::Number::operator/=
const Num & operator/=(const Num &b)
Definition: number.h:125
teditor::calc::Number::operator*=
const Num & operator*=(const Num &b)
Definition: number.h:124
std
Definition: number.h:8
teditor::calc::Number::Number
Number(const Num &n)
Definition: number.h:90
teditor::calc::Number::operator>=
bool operator>=(const Num &b) const
Definition: number.h:133
teditor::calc::Number::Number
Number(FloatT v)
Definition: number.h:89
teditor::calc::Number::sqrt2
static const Num sqrt2
Definition: number.h:158
teditor::calc::operator-
Number< I, F > operator-(const Number< I, F > &a, const Number< I, F > &b)
Definition: number.h:187
teditor::calc::Number::i
IntT i
Definition: number.h:81
teditor::calc::Number::operator==
bool operator==(const Num &b) const
Definition: number.h:128
teditor::calc::Number::operator+=
const Num & operator+=(const Num &b)
Definition: number.h:122
teditor::calc::Number::isInt
bool isInt
Definition: number.h:85
teditor::calc::Number::f
FloatT f
Definition: number.h:82
teditor::calc::Number::operator=
const Num & operator=(const Num &n)
Definition: number.h:108
teditor::calc::Num64
Number< int64_t, double > Num64
Definition: number.h:272
teditor::calc::Number::nan
static const Num nan
Definition: number.h:155
teditor::calc::Number::operator<=
bool operator<=(const Num &b) const
Definition: number.h:131
teditor::calc::FUNC
FUNC(sq)
teditor::calc::Number::pi
static const Num pi
Definition: number.h:154
teditor
Definition: any.hpp:10