2016-01-04 03:56:42 -08:00
|
|
|
/*
|
|
|
|
* moocpp/gobjptr.h
|
|
|
|
*
|
|
|
|
* Copyright (C) 2004-2016 by Yevgen Muntyan <emuntyan@users.sourceforge.net>
|
|
|
|
*
|
|
|
|
* 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 <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include "moocpp/gobjinfo.h"
|
|
|
|
|
|
|
|
namespace moo {
|
|
|
|
|
|
|
|
template<typename Object>
|
2016-01-04 09:56:33 -08:00
|
|
|
class gobj_ref;
|
2016-01-04 03:56:42 -08:00
|
|
|
template<typename Object>
|
2016-01-04 09:56:33 -08:00
|
|
|
class gobj_ptr;
|
2016-01-04 03:56:42 -08:00
|
|
|
template<typename Object>
|
2016-01-04 09:56:33 -08:00
|
|
|
class gobj_ptr_impl;
|
2016-01-04 03:56:42 -08:00
|
|
|
template<typename Object>
|
|
|
|
class gobj_raw_ptr;
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
2016-01-04 09:56:33 -08:00
|
|
|
// gobj_ref
|
2016-01-04 03:56:42 -08:00
|
|
|
//
|
|
|
|
|
2016-01-04 09:56:33 -08:00
|
|
|
class gobj_ref_base
|
2016-01-04 03:56:42 -08:00
|
|
|
{
|
|
|
|
protected:
|
2016-01-04 09:56:33 -08:00
|
|
|
gobj_ref_base() : m_gobj(nullptr) {}
|
2016-01-04 03:56:42 -08:00
|
|
|
using object_type = GObject;
|
|
|
|
|
|
|
|
public:
|
2016-01-04 09:56:33 -08:00
|
|
|
gobj_ref_base(const gobj_ref_base&) = default;
|
|
|
|
gobj_ref_base& operator=(const gobj_ref_base&) = default;
|
2016-01-04 03:56:42 -08:00
|
|
|
|
2016-01-04 09:56:33 -08:00
|
|
|
gobj_ref_base(gobj_ref_base&& other)
|
2016-01-04 03:56:42 -08:00
|
|
|
: m_gobj(other.m_gobj)
|
|
|
|
{
|
|
|
|
other.m_gobj = nullptr;
|
|
|
|
}
|
|
|
|
|
2016-01-04 09:56:33 -08:00
|
|
|
gobj_ref_base& operator=(gobj_ref_base&& other)
|
2016-01-04 03:56:42 -08:00
|
|
|
{
|
|
|
|
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<GTypeInstance*>(m_gobj); }
|
|
|
|
operator const GTypeInstance&() const { return *reinterpret_cast<const GTypeInstance*>(m_gobj); }
|
|
|
|
|
|
|
|
protected:
|
|
|
|
GObject* raw_gobj() const { return const_cast<GObject*>(m_gobj); }
|
|
|
|
|
|
|
|
private:
|
2016-01-04 09:56:33 -08:00
|
|
|
template<typename Object> friend class gobj_ptr_impl;
|
2016-01-04 03:56:42 -08:00
|
|
|
template<typename Object> friend class gobj_raw_ptr;
|
2016-01-04 09:56:33 -08:00
|
|
|
template<typename Object> friend class gobj_ref;
|
2016-01-04 03:56:42 -08:00
|
|
|
|
|
|
|
void _set_gobj(gpointer gobj) { m_gobj = reinterpret_cast<GObject*>(gobj); }
|
|
|
|
|
|
|
|
private:
|
|
|
|
GObject* m_gobj;
|
|
|
|
};
|
|
|
|
|
|
|
|
template<>
|
2016-01-04 09:56:33 -08:00
|
|
|
class gobj_ref<GObject>; // : public gobj_ref_base
|
2016-01-04 03:56:42 -08:00
|
|
|
|
2016-01-10 01:12:50 -08:00
|
|
|
#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<object_type>; \
|
|
|
|
\
|
|
|
|
protected: \
|
|
|
|
friend class gobj_ptr_impl<object_type>; \
|
|
|
|
friend class gobj_raw_ptr<object_type>; \
|
|
|
|
friend class gobj_raw_ptr<const object_type>; \
|
|
|
|
\
|
|
|
|
gobj_ref() {} \
|
|
|
|
\
|
|
|
|
public: \
|
|
|
|
gobj_ref(object_type& gobj) \
|
|
|
|
{ \
|
|
|
|
_set_gobj(&gobj); \
|
|
|
|
} \
|
|
|
|
\
|
|
|
|
object_type* gobj() \
|
|
|
|
{ \
|
|
|
|
return reinterpret_cast<object_type*>(raw_gobj()); \
|
|
|
|
} \
|
|
|
|
\
|
|
|
|
const object_type* gobj() const \
|
|
|
|
{ \
|
|
|
|
return reinterpret_cast<const object_type*>(raw_gobj()); \
|
|
|
|
} \
|
|
|
|
\
|
|
|
|
template<typename X> \
|
|
|
|
X* gobj() \
|
|
|
|
{ \
|
|
|
|
return nc_gobj<X>(); \
|
|
|
|
} \
|
|
|
|
\
|
|
|
|
template<typename X> \
|
|
|
|
const X* gobj() const \
|
|
|
|
{ \
|
|
|
|
return nc_gobj<X>(); \
|
|
|
|
} \
|
|
|
|
\
|
|
|
|
object_type* nc_gobj() const \
|
|
|
|
{ \
|
|
|
|
return const_cast<object_type*>(gobj()); \
|
|
|
|
} \
|
|
|
|
\
|
|
|
|
template<typename X> \
|
|
|
|
X* nc_gobj() const \
|
|
|
|
{ \
|
|
|
|
object_type* o = const_cast<object_type*>(gobj()); \
|
|
|
|
return gobj_is_subclass<Object, X>::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<object_type> operator&() { return nc_gobj(); } \
|
|
|
|
gobj_raw_ptr<const object_type> 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<super&&>(other))) \
|
|
|
|
{ \
|
|
|
|
} \
|
|
|
|
\
|
|
|
|
gobj_ref& operator=(gobj_ref&& other) \
|
|
|
|
{ \
|
|
|
|
super::operator=(std::move(static_cast<super&&>(other))); \
|
|
|
|
return *this; \
|
2016-01-04 03:56:42 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
#define MOO_DEFINE_GOBJREF_METHODS(Object) \
|
2016-01-04 09:56:33 -08:00
|
|
|
MOO_DEFINE_GOBJREF_METHODS_IMPL(Object, gobj_ref<gobj_parent_type<Object>>)
|
2016-01-04 03:56:42 -08:00
|
|
|
|
|
|
|
|
|
|
|
template<typename Object>
|
2016-01-04 09:56:33 -08:00
|
|
|
using gobj_ref_parent = gobj_ref<gobj_parent_type<Object>>;
|
2016-01-04 03:56:42 -08:00
|
|
|
|
2016-01-04 09:56:33 -08:00
|
|
|
// Generic implementation, falls back to the parent type's gobj_ref implementation
|
2016-01-04 03:56:42 -08:00
|
|
|
// if that's known, or to GObject's one, coming from the generic gobjinfo.
|
|
|
|
template<typename Object>
|
2016-01-04 09:56:33 -08:00
|
|
|
class gobj_ref : public gobj_ref_parent<Object>
|
2016-01-04 03:56:42 -08:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
MOO_DEFINE_GOBJREF_METHODS(Object)
|
|
|
|
};
|
|
|
|
|
2016-01-05 04:45:22 -08:00
|
|
|
} // namespace moo
|
|
|
|
|
2016-01-04 09:56:33 -08:00
|
|
|
// Make sure these aren't called in code ported from pure glib C
|
2016-01-04 03:56:42 -08:00
|
|
|
template<typename X>
|
2016-01-05 04:45:22 -08:00
|
|
|
void g_object_unref(const moo::gobj_ref<X>*) = delete;
|
2016-01-04 03:56:42 -08:00
|
|
|
template<typename X>
|
2016-01-05 04:45:22 -08:00
|
|
|
void g_free(const moo::gobj_ref<X>*) = delete;
|
2016-01-04 03:56:42 -08:00
|
|
|
|
2016-01-05 04:45:22 -08:00
|
|
|
void extern_g_free(gpointer);
|
|
|
|
void extern_g_object_unref(gpointer);
|