diff --git a/qse/include/qse/cmn/Array.hpp b/qse/include/qse/cmn/Array.hpp index 058576ea..10878945 100644 --- a/qse/include/qse/cmn/Array.hpp +++ b/qse/include/qse/cmn/Array.hpp @@ -116,9 +116,7 @@ public: this->init_array (capacity); } - Array (const SelfType& array): - Mmged(array.getMmgr()), - count(0), capacity(0), buffer(QSE_NULL) + Array (const SelfType& array): Mmged(array.getMmgr()), count(0), capacity(0), buffer(QSE_NULL) { if (array.buffer) { @@ -129,10 +127,7 @@ public: } #if defined(QSE_CPP_ENABLE_CPP11_MOVE) - - Array (SelfType&& array): - Mmged(array.getMmgr()), - count(0), capacity(0), buffer(QSE_NULL) + Array (SelfType&& array): Mmged(array.getMmgr()), count(0), capacity(0), buffer(QSE_NULL) { if (array.buffer) { @@ -173,11 +168,14 @@ public: { if (this != &array) { + // since 'array' is an rvalue, i know it's going to be destroyed. + // it should be safe to destroy all my items here first instead of + // arranging to swap with items of 'array'. this->clear (true); if (array.buffer) { - // TODO: show i block move if mmgrs are differnt + // TODO: should i swap items if mmgrs are differnt // between *this and array? this->setMmgr (array.getMmgr()); // copy over mmgr. @@ -186,6 +184,8 @@ public: this->count = array.count; this->capacity = array.capacity; + // since i cleared all items in the existing array, + // i can simply do the followings. array.buffer = QSE_NULL; array.count = 0; array.capacity = 0; diff --git a/qse/include/qse/cmn/BinaryHeap.hpp b/qse/include/qse/cmn/BinaryHeap.hpp index ee03dcac..35f3c828 100644 --- a/qse/include/qse/cmn/BinaryHeap.hpp +++ b/qse/include/qse/cmn/BinaryHeap.hpp @@ -123,27 +123,17 @@ public: INVALID_INDEX = ParentType::INVALID_INDEX }; - BinaryHeap (qse_size_t capacity = DEFAULT_CAPACITY): ParentType (QSE_NULL, capacity) - { - } + BinaryHeap (qse_size_t capacity = DEFAULT_CAPACITY): ParentType (QSE_NULL, capacity) {} - BinaryHeap (Mmgr* mmgr, qse_size_t capacity = DEFAULT_CAPACITY): ParentType (mmgr, capacity) - { - } + BinaryHeap (Mmgr* mmgr, qse_size_t capacity = DEFAULT_CAPACITY): ParentType (mmgr, capacity) {} - BinaryHeap (const SelfType& heap): ParentType (heap) - { - } + BinaryHeap (const SelfType& heap): ParentType (heap) {} #if defined(QSE_CPP_ENABLE_CPP11_MOVE) - BinaryHeap (SelfType& heap): ParentType (heap) - { - } + BinaryHeap (SelfType&& heap): ParentType ((ParentType&&)heap) {} #endif - ~BinaryHeap () - { - } + ~BinaryHeap () {} SelfType& operator= (const SelfType& heap) { @@ -159,7 +149,7 @@ public: { if (this != &heap) { - ParentType::operator= (heap); + ParentType::operator= ((ParentType&&)heap); } return *this; } diff --git a/qse/include/qse/cmn/RedBlackTree.hpp b/qse/include/qse/cmn/RedBlackTree.hpp index 96c84036..df6c1936 100644 --- a/qse/include/qse/cmn/RedBlackTree.hpp +++ b/qse/include/qse/cmn/RedBlackTree.hpp @@ -259,15 +259,13 @@ public: bool operator== (const SelfType& it) const { QSE_ASSERT (this->current != QSE_NULL); - return this->current == it.current && - this->previous == it.previous; + return this->current == it.current && this->previous == it.previous; } bool operator!= (const SelfType& it) const { QSE_ASSERT (this->current != QSE_NULL); - return this->current != it.current || - this->previous != it.previous; + return this->current != it.current || this->previous != it.previous; } bool isLegit() const @@ -381,6 +379,8 @@ public: } } + // TODO: move constructors and move assignment operators for c++11 + ~RedBlackTree () { this->clear (true); diff --git a/qse/include/qse/cmn/StrBase.hpp b/qse/include/qse/cmn/StrBase.hpp index 06b8aa64..3128b77e 100644 --- a/qse/include/qse/cmn/StrBase.hpp +++ b/qse/include/qse/cmn/StrBase.hpp @@ -273,6 +273,15 @@ public: this->ref_item (); } +#if defined(QSE_CPP_ENABLE_CPP11_MOVE) + StrBase (SelfType&& str): Mmged(str) + { + this->_item = str._item; // still it from the rvalue. + str._item = QSE_NULL; // the rvalue is soon to be destroyed. so nullify it + // no reference count manipulation is needed. + } +#endif + ~StrBase () { if (this->_item) this->deref_item (); @@ -295,6 +304,26 @@ public: return *this; } +#if defined(QSE_CPP_ENABLE_CPP11_MOVE) + SelfType& operator= (SelfType&& str) + { + if (this->_item != str._item) + { + this->deref_item (); + + // the data to be reference could be allocated using the + // memory manager of str. and it may be freed or resized by + // this. so the inner memory manager must be switched. + this->setMmgr (str.getMmgr()); // copy over mmgr. + + this->_item = str._item; + str._item = QSE_NULL; + // no reference count manipulation is needed. + } + return *this; + } +#endif + SelfType& operator= (const CHAR_TYPE* str) { if (this->_item->buffer != str) @@ -481,10 +510,9 @@ public: // str.truncate (100). if (this->_item) { - StringItem* old_item = QSE_NULL; - if (this->_item->isShared()) { + #if 0 StringItem* t; if (new_size > this->_item->capacity) @@ -492,21 +520,26 @@ public: else t = this->_item->copy (this->getMmgr()); - old_item = this->_item; + this->deref_item (); this->_item = t; this->ref_item (); + #else + if (new_size > this->_item->capacity) + this->possess_data (this->adjust_desired_capacity(new_size)); + else + this->possess_data (); + #endif } - else if (new_size > this->_item->capacity) + else if (new_size > this->_item->capacity) { StringItem* t = this->_item->copy (this->getMmgr(), this->adjust_desired_capacity(new_size)); - old_item = this->_item; + this->deref_item(); this->_item = t; - this->ref_item ();; + this->ref_item (); } this->_item->buffer[new_size] = NULL_CHAR; this->_item->size = new_size; - if (old_item) this->deref_item (old_item); } else { @@ -691,7 +724,7 @@ public: } /// The update() function replaces a \a size substring staring from the \a offset - /// with a new \a ssize string pointed to by \a str starign from the \a soffset. + /// with a new \a ssize string pointed to by \a str starting from the \a soffset. void update (qse_size_t index, qse_size_t size, const CHAR_TYPE* str, qse_size_t ssize) { this->remove (index, size); @@ -733,7 +766,8 @@ public: void clear () { - this->remove (0, this->_item->size); + //this->remove (0, this->_item->size); + this->truncate (0); } /// The compact() function compacts the internal buffer to the length of @@ -804,9 +838,9 @@ public: loop_findIndex: while (p1 <= e1 && *p1 != first) p1++; if (p1 > e1) return INVALID_INDEX; - + const CHAR_TYPE* s2 = str + offset + 1; - + CHAR_TYPE* p2 = p1 + 1; CHAR_TYPE* e2 = p2 + size - 1; @@ -991,8 +1025,8 @@ public: { while ((index = this->findIndex(index, str1)) != INVALID_INDEX) { - this->update (index, str1.data->data->size, str2); - index += str2.data->data->size; + this->update (index, str1._item->size, str2); + index += str2._item->size; } } @@ -1051,7 +1085,6 @@ private: new_capacity = this->round_capacity(new_capacity); return new_capacity; } - }; diff --git a/qse/include/qse/cmn/String.hpp b/qse/include/qse/cmn/String.hpp index b459c9a6..d920ae2b 100644 --- a/qse/include/qse/cmn/String.hpp +++ b/qse/include/qse/cmn/String.hpp @@ -198,8 +198,16 @@ public: WcString (qse_wchar_t c, qse_size_t size): ParentType(c, size) {} WcString (Mmgr* mmgr, qse_wchar_t c, qse_size_t size): ParentType(mmgr, c, size) {} WcString (const WcString& str): ParentType(str) {} +#if defined(QSE_CPP_ENABLE_CPP11_MOVE) + WcString (WcString&& str): ParentType((ParentType&&)str) {} + WcString (ParentType&& str): ParentType((ParentType&&)str) {} // added for ParentType returned in some methods defined in ParentType. e.g. getSubstring() +#endif WcString& operator= (const WcString& str) { ParentType::operator=(str); return *this; } +#if defined(QSE_CPP_ENABLE_CPP11_MOVE) + WcString& operator= (WcString&& str) { ParentType::operator=((WcString&&)str); return *this; } + WcString& operator= (ParentType&& str) { ParentType::operator=((WcString&&)str); return *this; } // added for ParentType returned in some methods defined in ParentType. e.g. getSubstring() +#endif WcString& operator= (const qse_wchar_t* str) { ParentType::operator=(str); return *this; } WcString& operator= (const qse_wchar_t c) { ParentType::operator=(c); return *this; } //using ParentType::operator=; @@ -227,8 +235,18 @@ public: MbString (qse_mchar_t c, qse_size_t size): ParentType(c, size) {} MbString (Mmgr* mmgr, qse_mchar_t c, qse_size_t size): ParentType(mmgr, c, size) {} MbString (const MbString& str): ParentType(str) {} + MbString (const ParentType& str): ParentType(str) {} +#if defined(QSE_CPP_ENABLE_CPP11_MOVE) + MbString (MbString&& str): ParentType((ParentType&&)str) {} + MbString (ParentType&& str): ParentType((ParentType&&)str) {} // added for ParentType returned in some methods defined in ParentType. e.g. getSubstring() +#endif MbString& operator= (const MbString& str) { ParentType::operator=(str); return *this; } + MbString& operator= (const ParentType& str) { ParentType::operator=(str); return *this; } +#if defined(QSE_CPP_ENABLE_CPP11_MOVE) + MbString& operator= (MbString&& str) { ParentType::operator=((MbString&&)str); return *this; } + MbString& operator= (ParentType&& str) { ParentType::operator=((MbString&&)str); return *this; } // added for ParentType returned in some methods defined in ParentType. e.g. getSubstring() +#endif MbString& operator= (const qse_mchar_t* str) { ParentType::operator=(str); return *this; } MbString& operator= (const qse_mchar_t c) { ParentType::operator=(c); return *this; } //using ParentType::operator=; diff --git a/qse/samples/cmn/bh01.cpp b/qse/samples/cmn/bh01.cpp index ed44bea9..8a752ffe 100644 --- a/qse/samples/cmn/bh01.cpp +++ b/qse/samples/cmn/bh01.cpp @@ -129,59 +129,133 @@ public: }; + +static StrHeap getStrHeap () +{ + char buf[100]; + StrHeap h; + + for (int i = 0; i < 25; i++) + { + sprintf (buf, "binary heap item %d", i); + h.insert (buf); + } + + return h; +} + int main () { char buf[20]; StrHeap h; - for (int i = 0; i < 20; i++) +#define TOTAL 22 + printf ("[TEST #1 - %d strings must be shown]\n", TOTAL * 2); + for (int i = 0; i < TOTAL; i++) { sprintf (buf, "hello %d", i); h.insert (buf); h.insert (buf); } - - for (qse_size_t i = 0; i < h.getSize(); i++) + if (h.getSize() != TOTAL * 2) { - printf ("%05d %s\n", (int)h.getIndex(h[i]), h[i].c_str()); + printf ("[FAILURE] ------------------------ \n"); } - printf ("----------------\n"); - - - while (!h.isEmpty()) + else { - printf ("%s\n", h[0u].c_str()); + for (qse_size_t i = 0; i < h.getSize(); i++) + { + printf ("%05d %s\n", (int)h.getIndex(h[i]), h[i].c_str()); + } + } + printf ("\n"); + + + ////////////////////////////////////////////////////////////////////////////// + + printf ("[TEST #2 - strings must be shown in ascending order]\n"); + const char* x = h[0u].c_str(); + std::string oldx; + while (true) + { + oldx = x; + printf ("%s\n", x); h.remove (0); + if (h.isEmpty()) break; + x = h[0u].c_str(); + if (strcmp (x, oldx.c_str()) < 0) + { + printf ("[FAILURE] ------------------------ \n"); + break; + } } - printf ("----------------\n"); + printf ("\n"); + ////////////////////////////////////////////////////////////////////////////// + + + printf ("[TEST #3 - integers must be shown in ascending order]\n"); { + QSE::BinaryHeap h2; - QSE::BinaryHeap h2; - - h2.insert (70); - h2.insert (90); - h2.insert (10); - h2.insert (5); - h2.insert (88); - h2.insert (87); - h2.insert (300); - h2.insert (91); - h2.insert (100); - h2.insert (200); - - while (h2.getSize() > 0) - { - printf ("%d\n", h2.getValueAt(0)); - h2.remove (0); - } + h2.insert (70); + h2.insert (90); + h2.insert (10); + h2.insert (5); + h2.insert (88); + h2.insert (87); + h2.insert (300); + h2.insert (91); + h2.insert (100); + h2.insert (200); + + int x = h2.getValueAt(0); + int oldx; + while (true) + { + oldx = x; + printf ("%d\n", x); + h2.remove (0); + if (h2.getSize() <= 0) break; + x = h2.getValueAt(0); + if (x < oldx) + { + printf ("[FAILURE] ------------------------ \n"); + break; + } + } } + printf ("\n"); + ////////////////////////////////////////////////////////////////////////////// - printf ("----------------\n"); + printf ("[TEST #4 - strings must be shown in the ascending order]\n"); + { + StrHeap h (getStrHeap ()); + + const char* x = h.getValueAt(0).c_str(); + std::string oldx; + while (true) + { + oldx = x; + printf ("%s\n", x); + h.remove (0); + if (h.isEmpty()) break; + x = h.getValueAt(0).c_str(); + if (strcmp (x, oldx.c_str()) < 0) + { + printf ("[FAILURE] ------------------------ \n"); + break; + } + } + } + printf ("\n"); + ////////////////////////////////////////////////////////////////////////////// + + printf ("[TEST #5 - random test]\n"); { Container c; StrList::Node* node2, * node14; - for (qse_size_t i = 0; i < 20; i++) + for (qse_size_t i = 0; i < TOTAL; i++) { sprintf (buf, "hello %d", (int)i); @@ -209,13 +283,14 @@ int main () } */ - for (int i = 0; c.getSize() > 0; i++) - { + for (int i = 0; c.getSize() > 0; i++) + { if (i == 3) c.remove (node2); if (i == 5) c.remove (node14); - + const char* largest = c.getLargest().c_str(); - printf ("%s\n", largest); + printf ("%s\n", largest); + c.removeLargest (); } }