void BigNumber::push_front(int num,const unsigned char c) {//Push multiple characters front if(!len){ cap=len=num+1; val=alloc.allocate(cap); first_free=val; dot=0; while(num--) alloc.construct(first_free++,c); alloc.construct(first_free++,'+'); }else{ int newcap=len+num; int newdot=dot; unsigned char *newval=alloc.allocate(newcap); unsigned char *newfirst_free=newval; unsigned char *oldval=val; while(num--) alloc.construct(newfirst_free++,c); while(oldval!=first_free) alloc.construct(newfirst_free++,*oldval++); release(); val=newval; first_free=newfirst_free; cap=len=newcap; dot=newdot; } }
BigNumber& BigNumber::reverse_copy(BigNumber &A) {//Reverse copy cap=len=A.len; val=alloc.allocate(cap); first_free=val; dot=0; unsigned char *begin=A.first_free; while(begin!=A.val){ alloc.construct(first_free++,*--begin); if(*begin=='.') dot=first_free-val-1; } }
String &String::operator=(const String &str) { char *p = alloc.allocate(str.sz); char *q = p; for(size_t i = 0;i < str.sz; ++i) alloc.construct(q++,str.s[i]); free(); s = p; sz = str.sz; return *this; }
void StrVec::reallocate() { auto newcapacity = size() ? 2 * size() : 1; auto newdata = alloc.allocate(newcapacity); auto dest = newdata; auto elem = elements; 0 for (size_t i = 0; i != size(); ++i) { alloc.construct(dest++, std::move(*elem++)); } free(); elements = newdata; first_free = dest; cap = elements + newcapacity; }
BigNumber& BigNumber::operator=(const BigNumber &A) {//Copy a BigNumber int newcap = A.len; unsigned char *newval = alloc.allocate(newcap); unsigned char *newfirst_free = newval; int newlen = A.len; int newdot = A.dot; int count = 0; while(count < A.len) alloc.construct(newfirst_free++,A.val[count++]); release(); cap=newcap; val=newval; first_free=newfirst_free; len=newlen; dot=newdot; return *this; }
String &String::operator+(const String &str) { size_t sz_temp = sz + str.sz; char *p = alloc.allocate(sz_temp); char *q = p; for(size_t i = 0;i < sz_temp; ++i) { if(i < sz) alloc.construct(q++,s[i]); else alloc.construct(q++,str.s[i-sz]); } free(); s = p; sz = sz_temp; return *this; }
void BigNumber::push_back(const unsigned char c) {//Push a character back if(!len||len>=cap){ int newcap=cap?(2*cap):2; int newdot=dot; unsigned char *newval=alloc.allocate(newcap); unsigned char *newfirst_free=newval; unsigned char *oldval=val; while(oldval!=first_free) alloc.construct(newfirst_free++,*oldval++); alloc.construct(newfirst_free++,c); release(); val=newval; first_free=newfirst_free; len=first_free-val; cap=newcap; dot=newdot; }else{alloc.construct(first_free++,c);len++;} }
BigNumber& BigNumber::dot_erase_copy(BigNumber &A) {//Copy BigNumber without dot before division release(); cap = A.dot ? (A.len - 1) : A.len; len = cap; dot = 0; val=alloc.allocate(cap); first_free = val; int count = 0; while(count < A.len){ alloc.construct(first_free++,A.val[count]); if(A.val[++count]=='.') if(++count == (A.len - 2) && A.val[count] == '0'){ ++count; --len; } } return *this; }
void BigNumber::cut_tail(int num) { int newcap = num + 3; int newdot; unsigned char *newval = alloc.allocate(newcap); unsigned char *newfirst_free = newval; unsigned char *oldval = val; while((first_free - oldval) != newcap) ++oldval; unsigned char *start = oldval; while(oldval != first_free){ if(*oldval == '.') newdot = oldval - start; alloc.construct(newfirst_free++,*oldval++); } release(); val=newval; first_free=newfirst_free; len=first_free-val; cap=newcap; dot=newdot; }
core::result details::get_double_float_array( const char * * buffers, const std::size_t * sizes, std::size_t num_of_buffers, std::size_t & current_buffer, const char * & buffer_position, double * & values, std::size_t & length, allocator & alloc) { int raw_length; core::result res = get_integer(buffers, sizes, num_of_buffers, current_buffer, buffer_position, raw_length); if (res == core::ok) { length = static_cast<std::size_t>(raw_length); double * new_array = static_cast<double *>( alloc.allocate(length * sizeof(double))); if (new_array != NULL) { values = new_array; for (std::size_t i = 0; res == core::ok && i != length; ++i) { res = get_double_float(buffers, sizes, num_of_buffers, current_buffer, buffer_position, values[i]); } if (res != core::ok) { alloc.deallocate(new_array); } } else { res = core::no_memory; } } return res; }
BigNumber& BigNumber::operator=(long long num) {//Copy a long long integer release(); cap=21; val=alloc.allocate(cap); first_free=val; bool flag=true; long long e=num%10; num/=10; if(e<0) e=-e; if(num<0) {flag=false;num=-num;} alloc.construct(first_free++,e+48); while(num){ e=num%10; num/=10; alloc.construct(first_free++,e+48); } if(flag) alloc.construct(first_free++,'+'); else alloc.construct(first_free++,'-'); len=first_free-val; dot=0; }
core::result details::get_string(const char * * buffers, const std::size_t * sizes, std::size_t num_of_buffers, std::size_t & current_buffer, const char * & buffer_position, const char * & value, std::size_t & length, allocator & alloc) { int raw_length; core::result res = get_integer(buffers, sizes, num_of_buffers, current_buffer, buffer_position, raw_length); if (res == core::ok) { length = static_cast<std::size_t>(raw_length); char * new_buffer = static_cast<char *>(alloc.allocate(length)); if (new_buffer != NULL) { value = new_buffer; res = get_raw_string(buffers, sizes, num_of_buffers, current_buffer, buffer_position, new_buffer, length); if (res != core::ok) { alloc.deallocate(new_buffer); } } else { res = core::no_memory; } } return res; }
core::result details::get_boolean_array( const char * * buffers, const std::size_t * sizes, std::size_t num_of_buffers, std::size_t & current_buffer, const char * & buffer_position, bool * & values, std::size_t & length, allocator & alloc) { int raw_length; core::result res = get_integer(buffers, sizes, num_of_buffers, current_buffer, buffer_position, raw_length); if (res == core::ok) { length = static_cast<std::size_t>(raw_length); const std::size_t byte_length = length * sizeof(bool); bool * new_array = static_cast<bool *>( alloc.allocate(byte_length)); if (new_array != NULL) { std::memset(new_array, 0, byte_length); values = new_array; const std::size_t full_words = length / bits_in_word; char word[bytes_in_word]; // first process full words for (std::size_t i = 0; i != full_words; ++i) { res = get_word_preserve_order( buffers, sizes, num_of_buffers, current_buffer, buffer_position, word); if (res != core::ok) { break; } for (std::size_t j = 0; j != bits_in_word; ++j) { const std::size_t byte_position = j / bits_in_byte; const std::size_t bit_position = j % bits_in_byte; if (word[byte_position] & (1 << bit_position)) { values[i * bits_in_word + j] = true; } } } // tail (what could not be read as a full word) if (res == core::ok) { res = get_word_preserve_order( buffers, sizes, num_of_buffers, current_buffer, buffer_position, word); if (res == core::ok) { const std::size_t already_read_bits = full_words * bits_in_word; for (std::size_t j = already_read_bits; j != length; ++j) { const std::size_t byte_position = (j - already_read_bits) / bits_in_byte; const std::size_t bit_position = j % bits_in_byte; if (word[byte_position] & (1 << bit_position)) { values[j] = true; } } } } if (res != core::ok) { alloc.deallocate(new_array); } } else { res = core::no_memory; } } return res; }
pair<string*, string*> StrVec::alloc_n_copy(const string *b, const string *e) { auto data = alloc.allocate(e - b); return { data, uninitialized_copy(b, e, data) }; }
static T* create() { T* p = alloc_.allocate(1); if (!p) return nullptr; alloc_.construct(p); return p; };
pair<char*, char*> String::alloc_n_copy(const char* b, const char* e) { auto str = alloc.allocate(e - b); return {str, uninitialized_copy(b, e, str)}; }