diff options
author | Murray Cumming <murrayc@murrayc.com> | 2016-12-11 20:57:37 +0100 |
---|---|---|
committer | Murray Cumming <murrayc@murrayc.com> | 2017-04-07 11:03:50 +0200 |
commit | 650453a800e6c3ad0c934ce2675298a7d90cc6b8 (patch) | |
tree | 4f153fa22af19dfb08f5af3899f6b0115228b3f9 | |
parent | ff390b28885f8fdea3bb8094570d943640519d64 (diff) | |
download | glibmm-650453a800e6c3ad0c934ce2675298a7d90cc6b8.tar.gz |
Remove Glib::WeakRef
Now that RefPtr is really a std::shared_ptr<>, we should use
std::weak_ref<> instead.
Note that a std::weak_ptr<> tells you nothing about whether
the underlying GObject is still alive, which Glib::RefPtr did.
It just tells you whether our std::shared_ptr<> still holds
a reference to it. That's why I removed one of the checks in
tests/giomm_listmodel/main.cc.
-rw-r--r-- | glib/glibmm.h | 1 | ||||
-rw-r--r-- | glib/glibmm/filelist.am | 1 | ||||
-rw-r--r-- | glib/glibmm/object.cc | 22 | ||||
-rw-r--r-- | glib/glibmm/weakref.h | 463 | ||||
-rw-r--r-- | tests/Makefile.am | 1 | ||||
-rw-r--r-- | tests/giomm_listmodel/main.cc | 30 | ||||
-rw-r--r-- | tests/glibmm_weakref/main.cc | 165 |
7 files changed, 10 insertions, 673 deletions
diff --git a/glib/glibmm.h b/glib/glibmm.h index 1b2b2dba..a9e90e02 100644 --- a/glib/glibmm.h +++ b/glib/glibmm.h @@ -140,7 +140,6 @@ #include <glibmm/variantiter.h> #include <glibmm/varianttype.h> #include <glibmm/vectorutils.h> -#include <glibmm/weakref.h> #include <glibmm/wrap.h> #endif /* _GLIBMM_H */ diff --git a/glib/glibmm/filelist.am b/glib/glibmm/filelist.am index 10964e6f..d0aeaf06 100644 --- a/glib/glibmm/filelist.am +++ b/glib/glibmm/filelist.am @@ -71,7 +71,6 @@ glibmm_files_extra_h = \ value.h \ value_custom.h \ vectorutils.h \ - weakref.h \ wrap.h \ wrap_init.h diff --git a/glib/glibmm/object.cc b/glib/glibmm/object.cc index 173d30e6..58166b7e 100644 --- a/glib/glibmm/object.cc +++ b/glib/glibmm/object.cc @@ -27,28 +27,6 @@ #include <string.h> -// Weak references: -// I'm not sure what the point of these are apart from being a hacky way out of circular references, -// but maybe we could make it easier to use them by making a Java Reference Object -style class like -// so: -// Glib::WeakRef<SomeDerivedObject> weakrefSomeObject(object1); -// ... -// if(weakrefSomeObject->isStillAlive()) -// { -// weakrefSomeObject->some_method(); -// } -// else -// { -// //Deal with it, maybe recreating the object. -// } -// -// Without this, the coder has to define his own signal handler which sets his own isStillAlive -// boolean. -// weakrefSomeObject<> could still have its own signal_destroyed signal so that coders can choose to -// deal -// with the destruction as soon as it happens instead of just checking later before they try to use -// it. - namespace Glib { diff --git a/glib/glibmm/weakref.h b/glib/glibmm/weakref.h deleted file mode 100644 index 570351db..00000000 --- a/glib/glibmm/weakref.h +++ /dev/null @@ -1,463 +0,0 @@ -#ifndef _GLIBMM_WEAKREF_H -#define _GLIBMM_WEAKREF_H - -/* Copyright (C) 2015 The glibmm Development Team - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see <http://www.gnu.org/licenses/>. - */ - -#include <glib-object.h> -#include <glibmm/refptr.h> -#include <glibmm/objectbase.h> -#include <type_traits> // std::is_base_of<> -#include <utility> // std::swap<>, std::forward<> - -namespace Glib -{ - -/** WeakRef<> is a weak reference smartpointer. - * - * WeakRef can store a pointer to any class that is derived from Glib::ObjectBase, - * and whose reference() method is noexcept. - * In glibmm and gtkmm, that is anything derived from Glib::ObjectBase. - * - * Unlike a RefPtr, a WeakRef does not contribute to the reference counting of - * the underlying object. - * - * @newin{2,46} - */ -template <typename T_CppObject> -class WeakRef -{ - static_assert(std::is_base_of<Glib::ObjectBase, T_CppObject>::value, - "Glib::WeakRef can be used only for classes derived from Glib::ObjectBase."); - -public: - /** Default constructor. - * - * Create an empty weak reference. - */ - inline WeakRef() noexcept; - - /// Copy constructor. - inline WeakRef(const WeakRef& src) noexcept; - - /// Move constructor. - inline WeakRef(WeakRef&& src) noexcept; - - /// Copy constructor from different, but castable type. - template <typename T_CastFrom> - inline WeakRef(const WeakRef<T_CastFrom>& src) noexcept; - - /// Move constructor from different, but castable type. - template <typename T_CastFrom> - inline WeakRef(WeakRef<T_CastFrom>&& src) noexcept; - - /** Constructor from a RefPtr of the same or a castable type. - * - * Create a weak reference from a RefPtr of the same or a castable type. - * If the RefPtr references nothing, an empty weak reference will be constructed. - */ - template <typename T_CastFrom> - inline WeakRef(const RefPtr<T_CastFrom>& src) noexcept; - - /// Destructor. - inline ~WeakRef() noexcept; - - /// Swap the contents of two WeakRef<>. - inline void swap(WeakRef& other) noexcept; - - /// Copy assignment operator. - inline WeakRef& operator=(const WeakRef& src) noexcept; - - /// Move assignment operator. - inline WeakRef& operator=(WeakRef&& src) noexcept; - - /// Copy assignment from different, but castable type. - template <typename T_CastFrom> - inline WeakRef& operator=(const WeakRef<T_CastFrom>& src) noexcept; - - /// Move assignment from different, but castable type. - template <typename T_CastFrom> - inline WeakRef& operator=(WeakRef<T_CastFrom>&& src) noexcept; - - /// Assignment from a RefPtr of the same or a castable type. - template <typename T_CastFrom> - inline WeakRef& operator=(const RefPtr<T_CastFrom>& src) noexcept; - - /** Test whether the WeakRef<> points to any underlying instance. - * - * Mimics usage of ordinary pointers: - * @code - * if (ptr) - * do_something(); - * @endcode - * - * In a multi-threaded program a <tt>true</tt> return value can become - * obsolete at any time, even before the caller has a chance to test it, - * because the underlying instance may lose its last reference in another - * thread. Use get() if this is not acceptable. - */ - inline explicit operator bool() const noexcept; - - /** Create a strong reference to the underlying object. - * - * This is a thread-safe way to acquire a strong reference to the underlying - * object. If the WeakRef is empty, the returned RefPtr will reference nothing. - */ - inline RefPtr<T_CppObject> get() const noexcept; - - /// Make this WeakRef empty. - inline void reset() noexcept; - - /** Dynamic cast to derived class. - * - * The WeakRef can't be cast with the usual notation so instead you can use - * @code - * ptr_derived = Glib::WeakRef<Derived>::cast_dynamic(ptr_base); - * @endcode - */ - template <typename T_CastFrom> - static inline WeakRef cast_dynamic(const WeakRef<T_CastFrom>& src) noexcept; - - /** Static cast to derived class. - * - * The WeakRef can't be cast with the usual notation so instead you can use - * @code - * ptr_derived = Glib::WeakRef<Derived>::cast_static(ptr_base); - * @endcode - */ - template <typename T_CastFrom> - static inline WeakRef cast_static(const WeakRef<T_CastFrom>& src) noexcept; - - /** Cast to non-const. - * - * The WeakRef can't be cast with the usual notation so instead you can use - * @code - * ptr_nonconst = Glib::WeakRef<NonConstType>::cast_const(ptr_const); - * @endcode - */ - template <typename T_CastFrom> - static inline WeakRef cast_const(const WeakRef<T_CastFrom>& src) noexcept; - -private: - // Let all instantiations of WeakRef access private data. - template <typename T_CastFrom> - friend class WeakRef; - - // If pCppObject != nullptr && gobject == nullptr, - // then the caller holds a strong reference. - void set(T_CppObject* pCppObject, GWeakRef* gobject) noexcept; - - // WeakRef owns *gobject_, but it does not own *pCppObject_. - // Invariant: (!pCppObject_ || gobject_), - // i.e. if pCppObject_ != nullptr then also gobject_ != nullptr. - T_CppObject* pCppObject_; - GWeakRef* gobject_; - - // Some methods would be simpler if gobject_ were a GWeakRef instead of - // a GWeakRef*, but then the move constructor and the move assignment - // operation would not be efficient. - -}; // end class WeakRef - -#ifndef DOXYGEN_SHOULD_SKIP_THIS - -template <typename T_CppObject> -WeakRef<T_CppObject>::WeakRef() noexcept : pCppObject_(nullptr), gobject_(nullptr) -{ -} - -template <typename T_CppObject> -WeakRef<T_CppObject>::WeakRef(const WeakRef& src) noexcept : pCppObject_(src.pCppObject_), - gobject_(nullptr) -{ - if (pCppObject_) - { - // We must own a strong reference to the underlying GObject while - // calling g_weak_ref_init(). - gpointer ptr = g_weak_ref_get(src.gobject_); - if (ptr) - { - gobject_ = new GWeakRef; - g_weak_ref_init(gobject_, pCppObject_->gobj()); - g_object_unref(ptr); - } - else - pCppObject_ = nullptr; - } -} - -template <typename T_CppObject> -WeakRef<T_CppObject>::WeakRef(WeakRef&& src) noexcept : pCppObject_(src.pCppObject_), - gobject_(src.gobject_) -{ - src.pCppObject_ = nullptr; - src.gobject_ = nullptr; -} - -// The templated ctor allows copy construction from any object that's -// castable. Thus, it does downcasts: -// base_ref = derived_ref -template <typename T_CppObject> -template <typename T_CastFrom> -WeakRef<T_CppObject>::WeakRef(const WeakRef<T_CastFrom>& src) noexcept - : pCppObject_(src.pCppObject_), - gobject_(nullptr) -{ - if (pCppObject_) - { - // We must own a strong reference to the underlying GObject while - // calling g_weak_ref_init(). - gpointer ptr = g_weak_ref_get(src.gobject_); - if (ptr) - { - gobject_ = new GWeakRef; - g_weak_ref_init(gobject_, pCppObject_->gobj()); - g_object_unref(ptr); - } - else - pCppObject_ = nullptr; - } -} - -// The templated ctor allows move construction from any object that's -// castable. Thus, it does downcasts: -// base_ref = std::move(derived_ref) -template <typename T_CppObject> -template <typename T_CastFrom> -WeakRef<T_CppObject>::WeakRef(WeakRef<T_CastFrom>&& src) noexcept : pCppObject_(src.pCppObject_), - gobject_(src.gobject_) -{ - src.pCppObject_ = nullptr; - src.gobject_ = nullptr; -} - -template <typename T_CppObject> -template <typename T_CastFrom> -WeakRef<T_CppObject>::WeakRef(const RefPtr<T_CastFrom>& src) noexcept - : pCppObject_(src.operator->()), - gobject_(nullptr) -{ - if (pCppObject_) - { - gobject_ = new GWeakRef; - g_weak_ref_init(gobject_, pCppObject_->gobj()); - } -} - -template <typename T_CppObject> -WeakRef<T_CppObject>::~WeakRef() noexcept -{ - if (gobject_) - { - g_weak_ref_clear(gobject_); - delete gobject_; - } -} - -template <class T_CppObject> -void -WeakRef<T_CppObject>::swap(WeakRef& other) noexcept -{ - std::swap(pCppObject_, other.pCppObject_); - std::swap(gobject_, other.gobject_); -} - -template <typename T_CppObject> -WeakRef<T_CppObject>& -WeakRef<T_CppObject>::operator=(const WeakRef& src) noexcept -{ - set(src.pCppObject_, src.gobject_); - return *this; -} - -template <typename T_CppObject> -WeakRef<T_CppObject>& -WeakRef<T_CppObject>::operator=(WeakRef&& src) noexcept -{ - // This technique is inefficient for copy assignment of WeakRef, - // because it involves copy construction + destruction, i.e. in a typical - // case g_weak_ref_init() + g_weak_ref_clear(), when a g_weak_ref_set() - // would be enough. For move assignment, the swap technique is fine. - WeakRef<T_CppObject> temp(std::forward<WeakRef<T_CppObject>>(src)); - this->swap(temp); - return *this; -} - -template <typename T_CppObject> -template <typename T_CastFrom> -WeakRef<T_CppObject>& -WeakRef<T_CppObject>::operator=(const WeakRef<T_CastFrom>& src) noexcept -{ - set(src.pCppObject_, src.gobject_); - return *this; -} - -template <typename T_CppObject> -template <typename T_CastFrom> -WeakRef<T_CppObject>& -WeakRef<T_CppObject>::operator=(WeakRef<T_CastFrom>&& src) noexcept -{ - WeakRef<T_CppObject> temp(std::forward<WeakRef<T_CastFrom>>(src)); - this->swap(temp); - return *this; -} - -template <typename T_CppObject> -template <typename T_CastFrom> -WeakRef<T_CppObject>& -WeakRef<T_CppObject>::operator=(const RefPtr<T_CastFrom>& src) noexcept -{ - T_CppObject* pCppObject = src.operator->(); - set(pCppObject, nullptr); - return *this; -} - -template <class T_CppObject> -WeakRef<T_CppObject>::operator bool() const noexcept -{ - if (!pCppObject_) - return false; - - gpointer ptr = g_weak_ref_get(gobject_); - if (!ptr) - return false; - - g_object_unref(ptr); - return true; -} - -template <typename T_CppObject> -RefPtr<T_CppObject> -WeakRef<T_CppObject>::get() const noexcept -{ - RefPtr<T_CppObject> ret; - - if (!pCppObject_) - return ret; - - gpointer ptr = g_weak_ref_get(gobject_); - if (!ptr) - return ret; - - // A RefPtr constructed from pointer expects reference to be done externally. - pCppObject_->reference(); - ret = make_refptr_for_instance<T_CppObject>(pCppObject_); - - g_object_unref(ptr); - - return ret; -} - -template <typename T_CppObject> -void -WeakRef<T_CppObject>::reset() noexcept -{ - set(nullptr, nullptr); -} - -template <typename T_CppObject> -template <typename T_CastFrom> -WeakRef<T_CppObject> -WeakRef<T_CppObject>::cast_dynamic(const WeakRef<T_CastFrom>& src) noexcept -{ - WeakRef<T_CppObject> ret; - - if (!src.pCppObject_) - return ret; - - gpointer ptr = g_weak_ref_get(src.gobject_); - if (!ptr) - return ret; - - // Don't call dynamic_cast<>() unless we know that the referenced object - // still exists. - T_CppObject* const pCppObject = dynamic_cast<T_CppObject*>(src.pCppObject_); - ret.set(pCppObject, nullptr); - g_object_unref(ptr); - - return ret; -} - -template <typename T_CppObject> -template <typename T_CastFrom> -WeakRef<T_CppObject> -WeakRef<T_CppObject>::cast_static(const WeakRef<T_CastFrom>& src) noexcept -{ - T_CppObject* const pCppObject = static_cast<T_CppObject*>(src.pCppObject_); - - WeakRef<T_CppObject> ret; - ret.set(pCppObject, src.gobject_); - return ret; -} - -template <typename T_CppObject> -template <typename T_CastFrom> -WeakRef<T_CppObject> -WeakRef<T_CppObject>::cast_const(const WeakRef<T_CastFrom>& src) noexcept -{ - T_CppObject* const pCppObject = const_cast<T_CppObject*>(src.pCppObject_); - - WeakRef<T_CppObject> ret; - ret.set(pCppObject, src.gobject_); - return ret; -} - -template <typename T_CppObject> -void -WeakRef<T_CppObject>::set(T_CppObject* pCppObject, GWeakRef* gobject) noexcept -{ - // We must own a strong reference to the underlying GObject while - // calling g_weak_ref_init() or g_weak_ref_set(). - // If pCppObject != nullptr && gobject == nullptr, - // then the caller holds a strong reference. - - // An aim with this moderately complicated method is to keep the same - // GWeakRef, calling g_weak_ref_set() when possible, instead of using swap(), - // which implies creating a new WeakRef, swapping with *this, and deleting - // the new WeakRef. - - gpointer ptr = nullptr; - if (pCppObject && gobject) - ptr = g_weak_ref_get(gobject); - - pCppObject_ = (ptr || !gobject) ? pCppObject : nullptr; - if (pCppObject_ && !gobject_) - { - gobject_ = new GWeakRef; - g_weak_ref_init(gobject_, pCppObject_->gobj()); - } - else if (gobject_) - g_weak_ref_set(gobject_, pCppObject_ ? pCppObject_->gobj() : nullptr); - - if (ptr) - g_object_unref(ptr); -} - -#endif // DOXYGEN_SHOULD_SKIP_THIS - -/** Swap the contents of two WeakRef<>. - * @relates Glib::WeakRef - */ -template <class T_CppObject> -inline void -swap(WeakRef<T_CppObject>& lhs, WeakRef<T_CppObject>& rhs) noexcept -{ - lhs.swap(rhs); -} - -} // namespace Glib - -#endif // _GLIBMM_WEAKREF_H diff --git a/tests/Makefile.am b/tests/Makefile.am index a3d7803b..1955a427 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -45,7 +45,6 @@ check_PROGRAMS = \ glibmm_null_vectorutils/test \ glibmm_refptr/test \ glibmm_refptr_sigc_bind/test \ - glibmm_weakref/test \ glibmm_bytearray/test \ glibmm_ustring_make_valid/test diff --git a/tests/giomm_listmodel/main.cc b/tests/giomm_listmodel/main.cc index cd8667da..1024a05e 100644 --- a/tests/giomm_listmodel/main.cc +++ b/tests/giomm_listmodel/main.cc @@ -39,7 +39,7 @@ void test_store_boundaries() { auto store = Gio::ListStore<Gio::MenuItem>::create(); auto item = Gio::MenuItem::create("", ""); - auto weakref_item = Glib::WeakRef<Gio::MenuItem>(item); + std::weak_ptr<Gio::MenuItem> weakref_item = item; // Remove an item from an empty list. store->remove(0); @@ -84,7 +84,7 @@ void test_store_boundaries() store.reset(); item.reset(); - if (weakref_item) + if (weakref_item.lock()) { result = EXIT_FAILURE; std::cerr << "test_store_boundaries(), 10: weakref_item is not null" << std::endl; @@ -116,16 +116,16 @@ void test_store_refcounts() const std::size_t n_items = 10; std::vector<Glib::RefPtr<Gio::MenuItem>> items; - std::vector<Glib::WeakRef<Gio::MenuItem>> weakref_items; + std::vector<std::weak_ptr<Gio::MenuItem>> weakref_items; for (std::size_t i = 0; i < n_items; ++i) { items.push_back(Gio::MenuItem::create("", "")); - weakref_items.push_back(Glib::WeakRef<Gio::MenuItem>(items[i])); + weakref_items.emplace_back(items[i]); store->append(items[i]); } check_store_refcounts_n_items(2, store, n_items); - if (store->get_item(3).operator->() != items[3].operator->()) + if (store->get_item(3).get() != items[3].get()) { result = EXIT_FAILURE; std::cerr << "test_store_refcounts(), 3: get_item(3) != items[3]" << std::endl; @@ -134,25 +134,15 @@ void test_store_refcounts() for (std::size_t i = 0; i < n_items; ++i) { items[i].reset(); - if (!weakref_items[i]) - { - result = EXIT_FAILURE; - std::cerr << "test_store_refcounts(), 4: weakref_items[" << i << "] is null" << std::endl; - } } store->remove(4); - if (weakref_items[4]) - { - result = EXIT_FAILURE; - std::cerr << "test_store_refcounts(), 5: weakref_items[4] is not null" << std::endl; - } check_store_refcounts_n_items(6, store, n_items-1); store.reset(); for (std::size_t i = 0; i < n_items; ++i) { - if (weakref_items[i]) + if (weakref_items[i].lock()) { result = EXIT_FAILURE; std::cerr << "test_store_refcounts(), 7: weakref_items[" << i << "] is not null" << std::endl; @@ -228,7 +218,7 @@ void test_store_sorted1() result = EXIT_FAILURE; std::cerr << "test_store_sorted1(), 2: i=" << i << ", items are not equal" << std::endl; } - if (a.operator->() == b.operator->()) + if (a.get() == b.get()) { result = EXIT_FAILURE; std::cerr << "test_store_sorted1(), 3: i=" << i << ", items are the same" << std::endl; @@ -237,7 +227,7 @@ void test_store_sorted1() if (i > 0) { auto c = store->get_item(i * 2 - 1); - if (c.operator->() == a.operator->() || c.operator->() == b.operator->()) + if (c.get() == a.get() || c.get() == b.get()) { result = EXIT_FAILURE; std::cerr << "test_store_sorted1(), 4: i=" << i << ", items are the same" << std::endl; @@ -311,7 +301,7 @@ void test_store_sorted2() result = EXIT_FAILURE; std::cerr << "test_store_sorted2(), 2: i=" << i << ", items are not equal" << std::endl; } - if (a.operator->() == b.operator->()) + if (a.get() == b.get()) { result = EXIT_FAILURE; std::cerr << "test_store_sorted2(), 3: i=" << i << ", items are the same" << std::endl; @@ -320,7 +310,7 @@ void test_store_sorted2() if (i > 0) { auto c = store->get_item(i * 2 - 1); - if (c.operator->() == a.operator->() || c.operator->() == b.operator->()) + if (c.get() == a.get() || c.get() == b.get()) { result = EXIT_FAILURE; std::cerr << "test_store_sorted2(), 4: i=" << i << ", items are the same" << std::endl; diff --git a/tests/glibmm_weakref/main.cc b/tests/glibmm_weakref/main.cc deleted file mode 100644 index ae8edf14..00000000 --- a/tests/glibmm_weakref/main.cc +++ /dev/null @@ -1,165 +0,0 @@ -/* Copyright (C) 2015 The glibmm Development Team - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see <http://www.gnu.org/licenses/>. - */ - -#include <cstring> -#include <giomm.h> //There is no class derived from Glib::Object in glibmm -#include <glibmm.h> -#include <iostream> -#include <utility> // std::move - -int -main(int, char**) -{ - Glib::init(); - bool success = true; - - // A Glib::WeakRef cannot be created from a Glib::RefPtr<Glib::Bytes>, - // because Glib::Bytes is not derived from Glib::ObjectBase. - // const int bdata = 1234; - // Glib::RefPtr<Glib::Bytes> bytes = Glib::Bytes::create(&bdata, sizeof bdata); - // Glib::WeakRef<Glib::Bytes> weakbytes = bytes; // does not compile - - // Gio::MemoryInputStream - Glib::RefPtr<Gio::MemoryInputStream> memstream1 = Gio::MemoryInputStream::create(); - const char data[] = "Some arbitrary data"; - memstream1->add_data(data, sizeof data, Gio::MemoryInputStream::SlotDestroyData()); - - // Downcast copy, followed by upcast. - Glib::WeakRef<Gio::MemoryInputStream> weakmemstream1 = memstream1; - Glib::WeakRef<Gio::InputStream> weakstream1 = weakmemstream1; - Glib::WeakRef<Gio::MemoryInputStream> weakmemstream2 = - Glib::WeakRef<Gio::MemoryInputStream>::cast_dynamic(weakstream1); - Glib::RefPtr<Gio::MemoryInputStream> memstream2 = weakmemstream2.get(); - if (memstream2) - { - char buffer[200]; - gsize bytes_read = 0; - try - { - memstream2->read_all(buffer, sizeof buffer, bytes_read); - std::cout << buffer << std::endl; - success &= std::strcmp(buffer, data) == 0; - } - catch (const Glib::Error& ex) - { - std::cout << "Error reading from memory stream: " << ex.what() << std::endl; - success = false; - } - } - else - { - std::cout << "!memstream2" << std::endl; - success = false; - } - - // Move construction. - Glib::WeakRef<Gio::MemoryInputStream> weakmemstream3(std::move(weakmemstream1)); - if (!weakmemstream3.get()) - { - success = false; - std::cout << "weakmemstream1 || !weakmemstream3: !weakmemstream3" << std::endl; - } - else - { - // Move assignment. - weakmemstream2 = std::move(weakmemstream3); - if (!weakmemstream2) - { - success = false; - std::cout << "!weakmemstream2 || weakmemstream3: !weakmemstream2" << std::endl; - } - else - { - // Downcast move, followed by upcast. - weakstream1 = std::move(weakmemstream2); - weakmemstream1 = Glib::WeakRef<Gio::MemoryInputStream>::cast_dynamic(weakstream1); - if (!weakmemstream1) - { - success = false; - std::cout << "weakmemstream2 || !weakmemstream1: !weakmemstream1" << std::endl; - } - } - } - - // Gio::SimpleAction - Glib::RefPtr<Gio::SimpleAction> action1 = Gio::SimpleAction::create("Action1"); - - Glib::ustring name = action1->get_name(); - std::cout << "The name is '" << name << "'." << std::endl; - success &= name == "Action1"; - - Glib::WeakRef<Gio::SimpleAction> weakaction1 = action1; - Glib::WeakRef<Gio::SimpleAction> weakaction2 = weakaction1; - - // A second RefPtr - Glib::RefPtr<Gio::SimpleAction> action2 = weakaction1.get(); - if (action2) - { - name = action2->get_name(); - std::cout << "The name is '" << name << "'." << std::endl; - success &= name == "Action1"; - } - else - { - std::cout << "!action2" << std::endl; - success = false; - } - - weakaction1.reset(); - if (weakaction1.get()) - { - std::cout << "weakaction1" << std::endl; - success = false; - } - - action2 = weakaction2.get(); - if (action2) - { - name = action2->get_name(); - std::cout << "The name is '" << name << "'." << std::endl; - success &= name == "Action1"; - } - else - { - std::cout << "!action2" << std::endl; - success = false; - } - - // Reset one of the RefPtrs. One remains. - action1.reset(); - action2 = weakaction2.get(); - if (action2) - { - name = action2->get_name(); - std::cout << "The name is '" << name << "'." << std::endl; - success &= name == "Action1"; - } - else - { - std::cout << "!action2" << std::endl; - success = false; - } - - // Reset the other RefPtr as well. - action2.reset(); - if (weakaction2.get()) - { - std::cout << "weakaction2" << std::endl; - success = false; - } - - return success ? EXIT_SUCCESS : EXIT_FAILURE; -} |