Wiselib
|
00001 00002 #ifndef STRING_DYNAMIC_H 00003 #define STRING_DYNAMIC_H 00004 00005 namespace wiselib { 00006 00013 template< 00014 typename OsModel_P, 00015 typename Allocator_P 00016 > 00017 class string_dynamic { 00018 public: 00019 typedef OsModel_P OsModel; 00020 typedef typename OsModel_P::size_t size_t; 00021 typedef Allocator_P Allocator; 00022 00023 typedef string_dynamic<OsModel_P, Allocator_P> self_type; 00024 typedef self_type* self_pointer_t; 00025 typedef typename Allocator::template Ref<char>::pointer_t char_pointer_t; 00026 00027 string_dynamic() : buffer_(0), size_(0), allocator_(0) { 00028 } 00029 00030 string_dynamic(Allocator& alloc) : buffer_(0), size_(0), allocator_(&alloc) { 00031 } 00032 00033 string_dynamic(const char* c, Allocator& alloc) : buffer_(0), size_(0), allocator_(&alloc) { 00034 resize(strlen(c)); 00035 to_buffer_(c, strlen(c)); 00036 } 00037 00038 string_dynamic(const string_dynamic& other) : buffer_(0), size_(0), allocator_(other.allocator_) { 00039 resize(other.size_); 00040 to_buffer_(other.buffer_, size_); 00041 } 00042 00043 string_dynamic& operator=(const string_dynamic& other) { 00044 if(!allocator_) { 00045 allocator_ = other.allocator_; 00046 } 00047 resize(other.size_); 00048 to_buffer_(other.buffer_, size_); 00049 return *this; 00050 } 00051 00052 string_dynamic& operator=(const char* other) { 00053 resize(strlen(other)); 00054 to_buffer_(other, size_); 00055 return *this; 00056 } 00057 00058 ~string_dynamic() { 00059 if(buffer_) { 00060 allocator_->template free_array<char>(buffer_); 00061 buffer_ = 0; 00062 size_ = 0; 00063 } 00064 } 00065 00066 00067 size_t size() const { 00068 return size_; 00069 } 00070 00071 void resize(size_t n, char c = '\0') { 00072 if(n == size_) { return; } 00073 size_ = n; 00074 00075 if(buffer_) { allocator_->template free_array<char>(buffer_); } 00076 buffer_ = allocator_->template allocate_array<char>(size_ + 1); 00077 } 00078 00079 const char* c_str() { 00080 buffer_[size_] = '\0'; 00081 return buffer_.raw(); 00082 } 00083 00084 bool operator==(const string_dynamic& other) { 00085 if(size_ != other.size_) { return false; } 00086 for(size_t i=0; i<size_; i++) { 00087 if(buffer_[i] != other.buffer_[i]) { 00088 return false; 00089 } 00090 } 00091 return true; 00092 } 00093 bool operator!=(const string_dynamic& other) { return !(*this == other); } 00094 00095 string_dynamic& append(const char* other) { 00096 return append(string_dynamic(other, *allocator_)); 00097 } 00098 00099 string_dynamic& append(const string_dynamic& other) { 00100 char_pointer_t old_buffer = buffer_; 00101 buffer_ = allocator_->template allocate_array<char>(size_ + other.size_ + 1); 00102 00103 if(old_buffer) { 00104 to_buffer_(old_buffer, size_); 00105 } 00106 to_buffer_(other.buffer_, other.size_, size_); 00107 00108 size_ = size_ + other.size_; 00109 if(old_buffer) { 00110 allocator_->template free_array<char>(old_buffer); 00111 } 00112 00113 return *this; 00114 } 00115 00116 private: 00117 template<typename T> 00118 void to_buffer_(T src, size_t n, size_t offset = 0) { 00119 char* ptr = buffer_.raw() + offset; 00120 for(size_t i=0; i<n; i++) { 00121 *ptr = *src; 00122 ++ptr; ++src; 00123 } 00124 } 00125 00126 char_pointer_t buffer_; 00127 size_t size_; 00128 typename Allocator::self_pointer_t allocator_; 00129 }; 00130 00133 template< 00134 typename String_P, 00135 typename Allocator_P 00136 > 00137 class string_creator { 00138 public: 00139 typedef String_P String; 00140 typedef Allocator_P Allocator; 00141 00142 string_creator(Allocator& alloc) : allocator_(alloc) { 00143 } 00144 00145 String operator()(const char* s) { 00146 return String(s, allocator_); 00147 } 00148 00149 private: 00150 Allocator& allocator_; 00151 }; 00152 00153 } // ns 00154 00155 #endif // STRING_DYNAMIC_H 00156