From: Radosław Korzeniewski Date: Thu, 14 Oct 2021 15:26:31 +0000 (+0200) Subject: Add copy operator to smartalist. X-Git-Tag: Beta-15.0.0~800 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1883c45cd286a94eabfe731b2a5d169c34773bd4;p=thirdparty%2Fbacula.git Add copy operator to smartalist. --- diff --git a/bacula/src/plugins/fd/pluginlib/smartalist.h b/bacula/src/plugins/fd/pluginlib/smartalist.h index 0b11bc6ad..0326be4c5 100644 --- a/bacula/src/plugins/fd/pluginlib/smartalist.h +++ b/bacula/src/plugins/fd/pluginlib/smartalist.h @@ -29,6 +29,12 @@ #ifndef _SMARTALIST_H_ #define _SMARTALIST_H_ +// This is for custom alist iterator +// which is not working as Bacula can't use any of the modern C++ headers (yet?) +// #if __cplusplus >= 201104 +// #include // For std::forward_iterator_tag +// #include // For std::ptrdiff_t +// #endif /** * @brief This is a simple smart array list (alist) resource guard conceptually based on C++11 - RAII. @@ -38,20 +44,99 @@ template class smart_alist : public alist { +private: + void _destroy(bool _remove_items = true) + { + if (items) + { + for (int i = 0; i < max_items; i++) + { + if (items[i]) + { + T *item = (T*)items[i]; + items[i] = NULL; + delete item; + } + } + if (_remove_items) + { + free(items); + items = NULL; + } + } + num_items = 0; + last_item = 0; + max_items = 0; + } + public: + // This is a custom alist iteration for modern C++ + // #if __cplusplus >= 201104 + // struct Iterator + // { + // using iterator_category = std::forward_iterator_tag; + // using difference_type = std::ptrdiff_t; + // using value_type = T; + // using pointer = T*; // or also value_type* + // using reference = T&; // or also value_type& + + // private: + // pointer m_ptr; + + // public: + // Iterator(pointer ptr) : m_ptr(ptr) {} + // reference operator*() const { return *m_ptr; } + // pointer operator->() { return m_ptr; } + + // // Prefix increment + // Iterator& operator++() { m_ptr++; return *this; } + + // // Postfix increment + // Iterator operator++(int) { Iterator tmp = *this; ++(*this); return tmp; } + + // friend bool operator== (const Iterator& a, const Iterator& b) { return a.m_ptr == b.m_ptr; }; + // friend bool operator!= (const Iterator& a, const Iterator& b) { return a.m_ptr != b.m_ptr; }; + // }; + + // // our iterator interface + // inline Iterator begin() { return Iterator(&items[0]); } + // inline Iterator end() { return Iterator(NULL); } + // #endif + smart_alist(int num = 10) : alist(num, not_owned_by_alist) {} - ~smart_alist() + ~smart_alist() { _destroy(); } + + // This is a simple copy operator + // it requires a T(T*) constructor to work correctly + inline smart_alist &operator=(const smart_alist &other) { - T * it; - if (items) { - for (int i = 0; i < max_items; i++) { - if (items[i]) { - it = (T*)items[i]; - items[i] = NULL; - delete it; + if (items != other.items) + { + _destroy(false); + if (other.items) + { + for (int i = 0; i < other.max_items; i++) + { + if (other.items[i]) + { + T *item = New(T((const T*)other.items[i])); + this->append(item); + } } } } + return *this; + } + // This is a simple move operator + inline smart_alist &operator=(smart_alist &&other) + { + if (items != other.items) + { + _destroy(); + items = other.items; + other.init(other.num_grow, own_items); + } + return *this; } }; diff --git a/bacula/src/plugins/fd/pluginlib/smartalist_test.cpp b/bacula/src/plugins/fd/pluginlib/smartalist_test.cpp index c540cf06c..d590ab814 100644 --- a/bacula/src/plugins/fd/pluginlib/smartalist_test.cpp +++ b/bacula/src/plugins/fd/pluginlib/smartalist_test.cpp @@ -29,18 +29,26 @@ #include "pluginlib.h" #include "smartalist.h" #include "unittests.h" +#include bFuncs *bfuncs; bInfo *binfo; static int referencenumber = 0; -struct testclass +struct testclass : public SMARTALLOC { testclass() { referencenumber++; }; ~testclass() { referencenumber--; }; }; +struct testvalue : public SMARTALLOC +{ + int value; + testvalue(const testvalue *other) { value = other->value; } + testvalue() : value(0) {} +}; + int main() { Unittests pluglib_test("smartalist_test"); @@ -50,7 +58,7 @@ int main() { smart_alist list; - ti = new testclass; + ti = New(testclass); list.append(ti); ok(referencenumber == 1, "check first insert"); } @@ -64,7 +72,7 @@ int main() smart_alist list; for (int a = 0; a < refs; a++) { - ti = new testclass; + ti = New(testclass); list.append(ti); } ok(referencenumber == refs, "check bulk inserts"); @@ -72,6 +80,36 @@ int main() ok(referencenumber == 0, "check smart free"); + { + smart_alist list; + testvalue *ti = New(testvalue); + ti->value = 0xfff1; + list.append(ti); + + smart_alist copylist; + + copylist = list; + + testvalue *tv = (testvalue*)copylist.first(); + rok(tv != NULL, "test first value"); + ok(tv->value == ti->value, "test copy value"); + ok(tv != ti, "test copy pointer"); + } + +// #if __cplusplus >= 201104 +// { +// smart_alist list; +// // fill it with data +// for (int i = 0; i < 10;i++) +// { +// testvalue *ti = New(testvalue); +// ti->value = 100 + i; +// list.append(ti); +// } + +// ok(list.size() == 10, "test prefill data size"); +// } +// #endif return report(); }