135 lines
6.7 KiB
C++
135 lines
6.7 KiB
C++
/*
|
|
* moocpp/gobjinfo.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
|
|
|
|
#ifdef __cplusplus
|
|
|
|
#include <glib-object.h>
|
|
#include <type_traits>
|
|
#include <moocpp/strutils.h>
|
|
|
|
namespace moo {
|
|
|
|
void init_gobj_system ();
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// gobjinfo
|
|
//
|
|
|
|
template<typename Object, typename Super>
|
|
struct gobj_is_subclass
|
|
{
|
|
static const bool value = false;
|
|
};
|
|
|
|
// Generic implementation, all we know it's a subclass of GObject; we don't
|
|
// even know its GType. This implementation is needed so that it's possible
|
|
// to have gobj_ptr<GAnything> without having to define gobjinfo for it.
|
|
template<typename Object>
|
|
struct gobjinfo
|
|
{
|
|
static const bool is_gobject = true;
|
|
using object_type = Object;
|
|
using parent_type = GObject;
|
|
// object_g_type() is not defined
|
|
};
|
|
|
|
template<>
|
|
struct gobjinfo<GObject>
|
|
{
|
|
static const bool is_gobject = true;
|
|
using object_type = GObject;
|
|
static GType object_g_type() { return G_TYPE_OBJECT; }
|
|
};
|
|
|
|
template<typename T>
|
|
inline GType get_g_type()
|
|
{
|
|
return gobjinfo<T>::object_g_type();
|
|
}
|
|
|
|
template<>
|
|
struct gobj_is_subclass<GObject, GObject>
|
|
{
|
|
static const bool value = true;
|
|
static GObject* down_cast(GObject* o) { return o; }
|
|
};
|
|
|
|
#define MOO_DEFINE_GOBJ_TYPE(Object, Parent, g_type) \
|
|
namespace moo { \
|
|
\
|
|
template<> \
|
|
struct gobjinfo<Object> \
|
|
{ \
|
|
static const bool is_gobject = true; \
|
|
using object_type = Object; \
|
|
using parent_type = Parent; \
|
|
static GType object_g_type() { return g_type; } \
|
|
}; \
|
|
\
|
|
template<> \
|
|
struct gobj_is_subclass<Object, Object> \
|
|
{ \
|
|
static const bool value = true; \
|
|
static Object* down_cast(Object* o) { return o; } \
|
|
}; \
|
|
\
|
|
template<typename Super> \
|
|
struct gobj_is_subclass<Object, Super> \
|
|
{ \
|
|
static const bool value = true; \
|
|
static Super* down_cast(Object *o) \
|
|
{ \
|
|
static_assert(gobj_is_subclass<Object, Super>::value, \
|
|
"In " __FUNCTION__ ": Super is not a superclass of " #Object); \
|
|
Parent* p = reinterpret_cast<Parent*>(o); \
|
|
Super* s = gobj_is_subclass<Parent, Super>::down_cast(p); \
|
|
return s; \
|
|
} \
|
|
}; \
|
|
} \
|
|
|
|
#define MOO_DEFINE_GIFACE_TYPE(Iface, g_type) \
|
|
MOO_DEFINE_GOBJ_TYPE(Iface, GObject, g_type)
|
|
|
|
#define MOO_GOBJ_IMPLEMENTS_IFACE(Object, Iface) \
|
|
namespace moo { \
|
|
\
|
|
template<> \
|
|
struct gobj_is_subclass<Object, Iface> \
|
|
{ \
|
|
static const bool value = true; \
|
|
static Iface* down_cast(Object *o) \
|
|
{ \
|
|
return reinterpret_cast<Iface*>(o); \
|
|
} \
|
|
}; \
|
|
} \
|
|
|
|
|
|
#define MOO_DEFINE_NON_GOBJ_TYPE(Object) \
|
|
namespace moo { \
|
|
template<> struct gobjinfo<Object> { static const bool is_gobject = false; }; \
|
|
}
|
|
|
|
template<typename Object>
|
|
using gobj_parent_type = typename gobjinfo<Object>::parent_type;
|
|
|
|
} // namespace moo
|
|
|
|
#endif // __cplusplus
|