summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMurray Cumming <murrayc@murrayc.com>2016-12-11 20:57:37 +0100
committerMurray Cumming <murrayc@murrayc.com>2017-04-07 11:03:50 +0200
commit650453a800e6c3ad0c934ce2675298a7d90cc6b8 (patch)
tree4f153fa22af19dfb08f5af3899f6b0115228b3f9
parentff390b28885f8fdea3bb8094570d943640519d64 (diff)
downloadglibmm-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.h1
-rw-r--r--glib/glibmm/filelist.am1
-rw-r--r--glib/glibmm/object.cc22
-rw-r--r--glib/glibmm/weakref.h463
-rw-r--r--tests/Makefile.am1
-rw-r--r--tests/giomm_listmodel/main.cc30
-rw-r--r--tests/glibmm_weakref/main.cc165
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;
-}