Fix ensure_capacity

This commit is contained in:
Baptiste Wicht 2014-03-05 14:34:18 +01:00
parent dd93960662
commit c1231b728f

View File

@ -12,8 +12,6 @@
#include <vector.hpp> #include <vector.hpp>
#include <unique_ptr.hpp> #include <unique_ptr.hpp>
void k_print(const char* s);
namespace std { namespace std {
inline uint64_t str_len(const char* a){ inline uint64_t str_len(const char* a){
@ -136,14 +134,12 @@ public:
//Constructors //Constructors
basic_string() : _size(0){ basic_string() : _size(0){
k_print("basic_string ");
set_small(true); set_small(true);
(*this)[0] = '\0'; (*this)[0] = '\0';
} }
basic_string(const CharT* s) : _size(str_len(s)) { basic_string(const CharT* s) : _size(str_len(s)) {
k_print("basic_string(raw) ");
auto capacity = size() + 1; auto capacity = size() + 1;
set_small(capacity <= 16); set_small(capacity <= 16);
@ -156,7 +152,6 @@ public:
} }
explicit basic_string(size_t __capacity) : _size(0) { explicit basic_string(size_t __capacity) : _size(0) {
k_print("basic_string(cap) ");
set_small(__capacity <= 16); set_small(__capacity <= 16);
if(!is_small()){ if(!is_small()){
@ -169,7 +164,6 @@ public:
//Copy //Copy
basic_string(const basic_string& rhs) : _size(rhs._size) { basic_string(const basic_string& rhs) : _size(rhs._size) {
k_print("basic_string(&) ");
if(!is_small()){ if(!is_small()){
new (&storage.big) base_long<CharT>(size() + 1, new CharT[size() + 1]); new (&storage.big) base_long<CharT>(size() + 1, new CharT[size() + 1]);
} }
@ -178,7 +172,6 @@ public:
} }
basic_string& operator=(const basic_string& rhs){ basic_string& operator=(const basic_string& rhs){
k_print("operator=(&) ");
if(this != &rhs){ if(this != &rhs){
set_size(rhs.size()); set_size(rhs.size());
@ -204,7 +197,6 @@ public:
//Move //Move
basic_string(basic_string&& rhs) : _size(rhs._size) { basic_string(basic_string&& rhs) : _size(rhs._size) {
k_print("basic_string(&&) ");
if(is_small()){ if(is_small()){
new (&storage.small) base_short<CharT>(std::move(rhs.storage.small)); new (&storage.small) base_short<CharT>(std::move(rhs.storage.small));
} else { } else {
@ -216,22 +208,26 @@ public:
} }
basic_string& operator=(basic_string&& rhs){ basic_string& operator=(basic_string&& rhs){
k_print("operator=(&&) "); auto was_small = is_small();
auto was_long = !was_small;
if(!rhs.data_ptr()){ auto small = rhs.is_small();
k_print("KABOOM "); auto lng = !small;
}
bool was_small = is_small();
_size = rhs._size;
if(is_small()){ set_size(rhs.size());
if(was_small && small){
storage.small = std::move(rhs.storage.small); storage.small = std::move(rhs.storage.small);
} else { } else if(was_long && lng){
if(was_small){ storage.big = std::move(rhs.storage.big);
new (&storage.big) base_long<CharT>(std::move(rhs.storage.big)); } else if(was_small && lng){
} else { new (&storage.big) base_long<CharT>(std::move(rhs.storage.big));
storage.big = std::move(rhs.storage.big);
} set_small(false);
} else if(was_long && small){
ensure_capacity(rhs.size() + 1);
std::copy_n(begin(), rhs.begin(), size() + 1);
} }
rhs._size = 0; rhs._size = 0;
@ -243,11 +239,9 @@ public:
//Destructors //Destructors
~basic_string(){ ~basic_string(){
k_print("~BS_S ");
if(is_long()){ if(is_long()){
storage.big.~base_long(); storage.big.~base_long();
} }
k_print("~BS_E ");
} }
//Modifiers //Modifiers
@ -291,12 +285,15 @@ public:
void ensure_capacity(size_t new_capacity){ void ensure_capacity(size_t new_capacity){
if(new_capacity > 0 && (capacity() < new_capacity)){ if(new_capacity > 0 && (capacity() < new_capacity)){
k_print("grow ");
auto new_cap = capacity() * 2; auto new_cap = capacity() * 2;
if(new_cap < new_capacity){
new_cap = new_capacity;
}
auto new_data = new CharT[new_cap]; auto new_data = new CharT[new_cap];
std::copy_n(new_data, begin(), size()); std::copy_n(new_data, begin(), size() + 1);
if(is_small()){ if(is_small()){
new (&storage.big) base_long<CharT>(new_cap, new_data); new (&storage.big) base_long<CharT>(new_cap, new_data);