/* * moocpp/gobjptr.h * * Copyright (C) 2004-2016 by Yevgen Muntyan * * This file is part of medit. medit 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. * * You should have received a copy of the GNU Lesser General Public * License along with medit. If not, see . */ #pragma once #include "moocpp/gobjinfo.h" namespace moo { template class gobj_ref; template class gobj_ptr; template class gobj_ptr_impl; template class gobj_raw_ptr; /////////////////////////////////////////////////////////////////////////////////////////// // // gobj_ref // class gobj_ref_base { protected: gobj_ref_base() : m_gobj(nullptr) {} using object_type = GObject; public: gobj_ref_base(const gobj_ref_base&) = default; gobj_ref_base& operator=(const gobj_ref_base&) = default; gobj_ref_base(gobj_ref_base&& other) : m_gobj(other.m_gobj) { other.m_gobj = nullptr; } gobj_ref_base& operator=(gobj_ref_base&& other) { m_gobj = other.m_gobj; other.m_gobj = nullptr; return *this; } GObject* gobj() { return m_gobj; } const GObject* gobj() const { return m_gobj; } operator GObject&() { return *m_gobj; } operator const GObject&() const { return *m_gobj; } operator GTypeInstance&() { return *reinterpret_cast(m_gobj); } operator const GTypeInstance&() const { return *reinterpret_cast(m_gobj); } protected: GObject* raw_gobj() const { return const_cast(m_gobj); } private: template friend class gobj_ptr_impl; template friend class gobj_raw_ptr; template friend class gobj_ref; void _set_gobj(gpointer gobj) { m_gobj = reinterpret_cast(gobj); } private: GObject* m_gobj; }; template<> class gobj_ref; // : public gobj_ref_base #define MOO_DEFINE_GOBJREF_METHODS_IMPL(Object, Super) \ using super = Super; \ using object_type = Object; \ using parent_object_type = typename super::object_type; \ using ptrtype = gobj_ptr; \ \ protected: \ friend class gobj_ptr_impl; \ friend class gobj_raw_ptr; \ friend class gobj_raw_ptr; \ \ gobj_ref() {} \ \ public: \ gobj_ref(object_type& gobj) \ { \ _set_gobj(&gobj); \ } \ \ object_type* gobj() \ { \ return reinterpret_cast(raw_gobj()); \ } \ \ const object_type* gobj() const \ { \ return reinterpret_cast(raw_gobj()); \ } \ \ template \ X* gobj() \ { \ return nc_gobj(); \ } \ \ template \ const X* gobj() const \ { \ return nc_gobj(); \ } \ \ object_type* nc_gobj() const \ { \ return const_cast(gobj()); \ } \ \ template \ X* nc_gobj() const \ { \ object_type* o = const_cast(gobj()); \ return gobj_is_subclass::down_cast(o); \ } \ \ gobj_ref* self() { return this; } \ const gobj_ref* self() const { return this; } \ \ operator object_type&() { return *gobj(); } \ operator const object_type&() const { return *gobj(); } \ gobj_raw_ptr operator&() { return nc_gobj(); } \ gobj_raw_ptr operator&() const { return nc_gobj(); } \ \ gobj_ref(const gobj_ref&) = default; \ gobj_ref& operator=(const gobj_ref&) = default; \ \ gobj_ref(gobj_ref&& other) \ : super(std::move(static_cast(other))) \ { \ } \ \ gobj_ref& operator=(gobj_ref&& other) \ { \ super::operator=(std::move(static_cast(other))); \ return *this; \ } #define MOO_DEFINE_GOBJREF_METHODS(Object) \ MOO_DEFINE_GOBJREF_METHODS_IMPL(Object, gobj_ref>) template using gobj_ref_parent = gobj_ref>; // Generic implementation, falls back to the parent type's gobj_ref implementation // if that's known, or to GObject's one, coming from the generic gobjinfo. template class gobj_ref : public gobj_ref_parent { public: MOO_DEFINE_GOBJREF_METHODS(Object) }; // Make sure these aren't called in code ported from pure glib C template void g_object_unref(const gobj_ref*) = delete; template void g_free(const gobj_ref*) = delete; } // namespace moo