9#ifndef __HRCORE_UTILS_HPP__
10#define __HRCORE_UTILS_HPP__
58 if (os.flags() & std::ios_base::hex) {
59 auto t = rhs._idata->
end();
60 os << (rhs._isPostive ?
"" :
"-") << (os.flags() & std::ios_base::showbase ?
"0x" :
"");
62 auto m = rhs._idata->
prev(t);
63 os << *t.data << (m ?
"," :
"");
71 os << (rhs._isPostive ?
"" :
"-");
72 auto r = ret->begin();
75 *r.data = *(tmp.getRemainder()._idata->begin().data);
77 src = tmp.getQuotient();
79 *r.data = *src._idata->
begin().data;
80 for (
bool flag =
false; r; flag =
true) {
81 auto t = ret->prev(r);
85 }
else if (*r.data < 100) {
89 if (*r.data == 1000) {
90#if HRCORE_ENABLE_IO_DELIMETER
98#if HRCORE_ENABLE_IO_DELIMETER
122 while ((c = is.peek()) ==
' ' || c ==
'\n' || c ==
'\r')
128 if (is.flags() & std::ios_base::hex) {
131 auto r = ret->
begin();
132 while ((c = is.peek()) != EOF) {
133 if (c ==
',' || c ==
' ' || c ==
'\n') {
146 if (ret->length() > rhs._idata->
length()) {
147 rhs._idata->
extend(ret->length());
149 rhs._idata->
shrink(ret->length());
151 for (
auto x = rhs._idata->
begin(); x && r; x = rhs._idata->
next(x), r = ret->prev(r))
158 bool positive = (c !=
'-');
159 if (c ==
'-' || c ==
'+')
161 while ((c = is.get()) != EOF) {
162 HRCORE_DBG(std::cout << c -
'0' << std::endl;)
163 if (c >=
'0' && c <=
'9') {
165 rhs = rhs * tim + tmp;
166 }
else if (c ==
',') {
187 if (is.flags() & std::ios_base::hex)
190 bool flag = rhs._isPostive;
191 rhs._isPostive =
true;
200 while ((c = is.get()) != EOF) {
201 if (c >=
'0' && c <=
'9') {
203 dim = dim * tim + tmp;
207 }
else if (c ==
',') {
215 if (tpos < rhs._precision) {
221 rhs = rhs +
Float((dim << -dtmp) / div, dtmp, tpos);
222 rhs._isPostive = flag;
223 HRCORE_DBGI(std::cout <<
"[operator>> @ Float] " << rhs._fpos << std::endl;)
234 if (os.flags() & std::ios_base::hex)
239 auto dtmp = rhs -
Float(it);
242 auto ret = tim._idata->newObject();
243 auto r = ret->begin();
245 Float tmp = dtmp * tim;
246 while (!Integer::_isZero(tmp)) {
248 *r.data = *(((
Float*)&x)->_idata->begin().data);
251 HRCORE_DBG(
operator<<(os, x);)
252 tmp = (tmp - x) * tim;
254 HRCORE_DBG(os << std::endl;)
257 if (os.flags() & std::ios_base::showpoint)
261 size_t i = rhs._tpos;
267 *ret->prev(r).data += (*r.data >= 5);
270 for (; i > 0; --i, r = ret->prev(r)) {
274 if (i > 0 && *r.data == 10) {
276 auto j = ret->prev(r);
300 if (os.flags() & std::ios_base::showpoint) {
305 for (
size_t x = 0; x < i; ++x, r = ret->next(r)) {
311 if (os.flags() & std::ios_base::showpoint) {
321#if HRCORE_ENABLE_UTILS
335 Value::Float abs(
const Value::Float& s)
344#if HRCORE_ENABLE_UTILS_IO
347 template <
typename G>
360 template <
typename G>
362 static G mod(
const G& l,
const G& r)
377 int8_t _getOp(
char c)
395 constexpr bool _isOpPrior(int8_t left, int8_t right)
397 return (left >= 0 && right >= 0) && !(left < 2 && right > 1);
410 template <
typename T,
typename U>
420 template <
typename T,
typename U>
421 std::istream&
operator>>(std::istream& is, Expression<T, U>& rhs);
427 template <
typename T,
typename U>
428 std::ostream&
operator<<(std::ostream& os, Expression<T, U>& rhs);
430 template <
typename T,
typename U>
438 T* _result =
nullptr;
439 std::deque<node_t> _data;
441 bool _isEval =
false;
442 bool _evalFailed =
false;
451 static T _doOperation(T& left, T& right, uint8_t op)
477 for (
auto x = this->_data.begin(); x != this->_data.end(); ++x) {
482 delete this->_result;
493 this->_isEval =
true;
494 this->_evalFailed =
true;
496 for (
auto x = this->_data.begin(); x != this->_data.end(); ++x) {
501 uint8_t op = (*x).sgn;
504 T* right = tmp.top();
509 HRCORE_DBG(std::cout << *left <<
' ' <<
int(op) <<
' ' << *right << std::endl;)
510 *left = _doOperation(*left, *right, op);
512 if (tmp.size() == 1) {
514 delete this->_result;
515 this->_result = tmp.top();
516 this->_evalFailed =
false;
526 return *this->_result;
530 friend std::ostream& operator<< <>(std::ostream& os,
Expression<T, U>& rhs);
533 template <
typename T,
typename U>
540 bool nextNeg =
false;
541 std::stack<int8_t> tmp;
542 while ((c = is.peek()) != EOF) {
544 while (c ==
' ' || c ==
'\n' || c ==
'\r') {
549 HRCORE_DBG(std::cout <<
int(c) << std::endl;)
552 if (c >=
'0' && c <=
'9') {
556 T& in = *
new T(rhs._newStorage(),
true,
true,
false);
563 rhs._data.push_back(ret);
575 while (tmp.size() && tmp.top() != -2) {
577 rhs._data.push_back(ret);
586 int8_t x = Internal::_getOp(c);
589 if (x == 1 && op != 1) {
598 while (tmp.size() && Internal::_isOpPrior(tmp.top(), x)) {
600 rhs._data.push_back(ret);
611 rhs._data.push_back(ret);
617 template <
typename T,
typename U>
622 if (!rhs._evalFailed) {
Exception os Expression failed to convert.
Exception of Expression evaluation: Invalid operation on seleted data type.
Exception of internal error. Please dig into it and solve.
A class as a storage interface, pure virtual.
virtual Interface * newObject()=0
Get a new object of same type.
virtual size_t length()=0
Get the length of storage.
virtual bool shrink(size_t len)=0
Remove data from the end to shrink the size to a given length.
virtual bool extend(size_t len)=0
Extend the storage to a given length.
virtual item_t next(item_t cur)=0
Get next item.
virtual item_t end()=0
Returns the last item of storage.
virtual item_t begin()=0
Return the first item of storage.
virtual item_t prev(item_t cur)=0
A class to get and evaluate expression.
T getResult()
Get the Result object. Make sure eval() returned true first, otherwise Segment Fault!
bool eval()
Evaluate the expression.
static Integer make()
Construct a new Integer object using given type of Storage::Interface implement.
Integer getInteger()
Get Interger section.
static Integer make()
Construct a new Integer object using given type of Storage::Interface implement.
static bool _absGreater(const Integer &l, const Integer &r)
Examine if l > r.
DivisionResult_t divideBy(const Integer &r)
A function to calculate (*this / r)
bool positive() const
Return the sign of object.
#define HRCORE_FP_BITS_BASE
Decide how many bits as a base of Float. Default: 24.
#define HRCORE_FP_BITS_PER_DIGIT
Decide how many bits for a digit in Float. Default: 8.
std::ostream & operator<<(std::ostream &os, Integer &rhs)
Reload of operator<< to support std::cout and other std::ostream with Integer.
std::istream & operator>>(std::istream &is, Integer &rhs)
Reload of operator>> to support std::cin and other std::istream with Integer.
std::ostream & operator<<(std::ostream &os, Expression< T, U > &rhs)
Output the value of an expression.
std::istream & operator>>(std::istream &is, Expression< T, U > &rhs)
Convert a stream into an expression.
bool _prepareNextStorageItem(Storage::Interface *i, Storage::Interface::item_t &r)
Prepare next item of Storage to be writen.
HRCore main namespace, contains all classes.