Bunch of C++ utils
This commit is contained in:
parent
7bf6b3d849
commit
5df6c2d0c7
@ -49,6 +49,15 @@ SET(MOOUTILS_SOURCES
|
||||
moocombo.h
|
||||
moocompat.c
|
||||
moocompat.h
|
||||
moocpp.cpp
|
||||
moocpp.h
|
||||
moocpp-cont.h
|
||||
moocpp-gobject.cpp
|
||||
moocpp-gobject.h
|
||||
moocpp-gtk.h
|
||||
moocpp-macros.h
|
||||
moocpp-refptr.h
|
||||
moocpp-types.h
|
||||
moodialogs.c
|
||||
moodialogs.h
|
||||
mooeditops.c
|
||||
|
335
moo/mooutils/moocpp-cont.h
Normal file
335
moo/mooutils/moocpp-cont.h
Normal file
@ -0,0 +1,335 @@
|
||||
/*
|
||||
* moocpp-cont.h
|
||||
*
|
||||
* Copyright (C) 2004-2009 by Yevgen Muntyan <muntyan@tamu.edu>
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef MOO_CPP_CONT_H
|
||||
#define MOO_CPP_CONT_H
|
||||
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <mooutils/moocpp-macros.h>
|
||||
|
||||
namespace moo {
|
||||
|
||||
template<typename T>
|
||||
class CowData
|
||||
{
|
||||
public:
|
||||
CowData() : m_ref(0) {}
|
||||
CowData(const CowData&) : m_ref(0) {}
|
||||
virtual ~CowData() {}
|
||||
|
||||
int refCount() const { return m_ref; }
|
||||
void ref() const { m_ref.ref(); }
|
||||
bool unref() const { mCheck(refCount() > 0); return m_ref.unref(); }
|
||||
|
||||
static T *getDefault()
|
||||
{
|
||||
static T obj;
|
||||
if (obj.refCount() == 0)
|
||||
obj.ref();
|
||||
return &obj;
|
||||
}
|
||||
|
||||
static T *dup(const T &data) { return new T(data); }
|
||||
|
||||
private:
|
||||
CowData &operator=(const CowData&);
|
||||
|
||||
private:
|
||||
mutable RefCount m_ref;
|
||||
};
|
||||
|
||||
template<typename TData>
|
||||
class CowPtr
|
||||
{
|
||||
public:
|
||||
CowPtr(TData *data = 0)
|
||||
: m_data(0)
|
||||
{
|
||||
if (!data)
|
||||
data = TData::getDefault();
|
||||
if (!data)
|
||||
data = new TData;
|
||||
m_data = data;
|
||||
m_data->ref();
|
||||
mAssert(m_data->refCount() >= 1);
|
||||
}
|
||||
|
||||
CowPtr(const CowPtr &cp)
|
||||
: m_data(0)
|
||||
{
|
||||
m_data = cp.m_data;
|
||||
m_data->ref();
|
||||
mAssert(m_data->refCount() >= 2);
|
||||
}
|
||||
|
||||
CowPtr &operator=(const CowPtr &cp)
|
||||
{
|
||||
if (m_data != cp.m_data)
|
||||
{
|
||||
TData *data = m_data;
|
||||
m_data = cp.m_data;
|
||||
m_data->ref();
|
||||
if (data->unref())
|
||||
delete data;
|
||||
mAssert(m_data->refCount() >= 2);
|
||||
}
|
||||
}
|
||||
|
||||
~CowPtr()
|
||||
{
|
||||
mAssert(m_data->refCount() > 0);
|
||||
if (m_data->unref())
|
||||
delete m_data;
|
||||
}
|
||||
|
||||
TData *get()
|
||||
{
|
||||
if (m_data->refCount() > 1)
|
||||
{
|
||||
TData *old_data = m_data;
|
||||
m_data = TData::dup(*old_data);
|
||||
m_data->ref();
|
||||
old_data->unref();
|
||||
mAssert(m_data->refCount() > 0);
|
||||
mAssert(old_data->refCount() > 0);
|
||||
}
|
||||
|
||||
return m_data;
|
||||
}
|
||||
|
||||
const TData *get() const { return m_data; }
|
||||
const TData *getConst() const { return m_data; }
|
||||
|
||||
MOO_IMPLEMENT_POINTER_TO_MEM(TData, get())
|
||||
|
||||
private:
|
||||
TData *m_data;
|
||||
};
|
||||
|
||||
|
||||
template<typename T> class Set;
|
||||
template<typename T> class List;
|
||||
template<typename T> class Vector;
|
||||
|
||||
|
||||
template<typename T>
|
||||
class List
|
||||
{
|
||||
private:
|
||||
typedef typename std::vector<T> std_vector;
|
||||
typedef typename std::vector<T>::iterator std_iterator;
|
||||
typedef typename std::vector<T>::const_iterator std_const_iterator;
|
||||
|
||||
struct Impl : public CowData<Impl>
|
||||
{
|
||||
std_vector v;
|
||||
};
|
||||
|
||||
CowPtr<Impl> m_impl;
|
||||
|
||||
std_vector &v() { return m_impl->v; }
|
||||
const std_vector &v() const { return m_impl->v; }
|
||||
|
||||
public:
|
||||
class iterator;
|
||||
class const_iterator;
|
||||
friend class iterator;
|
||||
friend class const_iterator;
|
||||
|
||||
class iterator
|
||||
{
|
||||
private:
|
||||
friend class List;
|
||||
typedef List::std_iterator std_iterator;
|
||||
typedef List::std_const_iterator std_const_iterator;
|
||||
|
||||
std_iterator m_si;
|
||||
|
||||
iterator(const std_iterator &si) : m_si(si) {}
|
||||
|
||||
operator std_iterator&() { return m_si; }
|
||||
operator const std_iterator&() const { return m_si; }
|
||||
|
||||
public:
|
||||
T &operator*() const { return *m_si; }
|
||||
};
|
||||
|
||||
class const_iterator
|
||||
{
|
||||
private:
|
||||
friend class List;
|
||||
typedef List::std_iterator std_iterator;
|
||||
typedef List::std_const_iterator std_const_iterator;
|
||||
|
||||
std_const_iterator m_si;
|
||||
|
||||
const_iterator(const std_iterator &si) : m_si(si) {}
|
||||
const_iterator(const std_const_iterator &si) : m_si(si) {}
|
||||
|
||||
operator std_const_iterator&() { return m_si; }
|
||||
operator const std_const_iterator&() const { return m_si; }
|
||||
|
||||
public:
|
||||
const T &operator*() const { return *m_si; }
|
||||
};
|
||||
|
||||
#ifdef MOO_USE_EXCEPTIONS
|
||||
#define _MOO_LIST_CHECK(what) \
|
||||
do { \
|
||||
if (what) \
|
||||
; \
|
||||
else \
|
||||
throw std::runtime_error(); \
|
||||
} while (0)
|
||||
#else
|
||||
#define _MOO_LIST_CHECK mCheck
|
||||
#endif
|
||||
|
||||
inline void checkNonEmpty() { _MOO_LIST_CHECK(!empty()); }
|
||||
inline void checkIndex(int i) { _MOO_LIST_CHECK((i) < size()); }
|
||||
inline void checkIndexE(int i) { _MOO_LIST_CHECK((i) <= size()); }
|
||||
|
||||
#undef _MOO_LIST_CHECK
|
||||
|
||||
public:
|
||||
List() {}
|
||||
|
||||
iterator begin() { return v().begin(); }
|
||||
const_iterator begin() const { return v().begin(); }
|
||||
iterator end() { return v().end(); }
|
||||
const_iterator end() const { return v().end(); }
|
||||
const_iterator constBegin() const { return begin(); }
|
||||
const_iterator constEnd() const { return end(); }
|
||||
|
||||
T &at(int i) { checkIndex(i); return v().at(i); }
|
||||
const T &at(int i) const { checkIndex(i); return v().at(i); }
|
||||
|
||||
T &operator[](int i) { return at(i); }
|
||||
const T &operator[](int i) const { return at(i); }
|
||||
|
||||
T &first() { checkNonEmpty(); return at(0); }
|
||||
const T &first() const { checkNonEmpty(); return at(0); }
|
||||
T &last() { checkNonEmpty(); return at(size() - 1); }
|
||||
const T &last() const { checkNonEmpty(); return at(size() - 1); }
|
||||
T &back() { checkNonEmpty(); return last(); }
|
||||
const T &back() const { checkNonEmpty(); return last(); }
|
||||
T &front() { checkNonEmpty(); return first(); }
|
||||
const T &front() const { checkNonEmpty(); return first(); }
|
||||
|
||||
List mid(int pos, int length = -1) const;
|
||||
|
||||
T value(int i) const { return value(i, T()); }
|
||||
T value(int i, const T &defaultValue) const { return i >= 0 && i < size() ? v()[i] : defaultValue; }
|
||||
|
||||
bool contains(const T &value) const { return indexOf(value) >= 0; }
|
||||
bool endsWith(const T &value) const { int c = v().size(); return c > 0 && v()[c - 1] == value; }
|
||||
int indexOf(const T &value, int from = 0) const { for (int i = from, c = v().size(); i < c; ++i) if (v()[i] == value) return i; return -1; }
|
||||
int lastIndexOf(const T &value, int from = -1) const { for (int c = v().size(), i = (from >= 0 ? from : c - 1); i >= 0 && i < c; --i) if (v()[i] == value) return i; return -1; }
|
||||
bool startsWith(const T &value) const { return v().size() > 0 && v()[0] == value; }
|
||||
int count(const T &value) const { return std::count(v().begin(), v().end(), value); }
|
||||
|
||||
int count() const { return v().size(); }
|
||||
bool isEmpty() const { return v().size() == 0; }
|
||||
|
||||
bool empty() const { return isEmpty(); }
|
||||
int length() const { return count(); }
|
||||
int size() const { return count(); }
|
||||
|
||||
void append(const T &value) { v().push_back(value); }
|
||||
void append(const List &other) { v().insert(v().end(), other.v().begin(), other.v().end()); }
|
||||
void clear() { v().erase(v().begin(), v().end()); }
|
||||
iterator erase(iterator pos) { v().erase(pos); }
|
||||
iterator erase(iterator begin, iterator end) { v().erase(begin, end); }
|
||||
|
||||
void insert(int i, const T &value) { checkIndexE(i); v().insert(v().begin() + i, value); }
|
||||
iterator insert(iterator before, const T &value) { v().insert(before, value); }
|
||||
template<class InputIterator>
|
||||
void insert(iterator before, InputIterator first, InputIterator last) { return v().insert(before, first, last); }
|
||||
|
||||
void pop_back() { checkNonEmpty(); v().pop_back(); }
|
||||
void pop_front() { checkNonEmpty(); v().pop_front(); }
|
||||
void prepend(const T &value) { v().push_front(value); }
|
||||
void push_back(const T &value) { v().push_back(value); }
|
||||
void push_front(const T &value) { v().push_front(value); }
|
||||
int removeAll(const T &value)
|
||||
{
|
||||
int sizeBefore = v().size();
|
||||
if (sizeBefore > 0)
|
||||
std::remove(v().begin(), v().end(), value);
|
||||
return sizeBefore - v().size();
|
||||
}
|
||||
void removeAt(int i) { checkIndex(i); v().erase(v().begin() + i); }
|
||||
void removeFirst() { checkNonEmpty(); v().erase(v().begin()); }
|
||||
void removeLast() { checkNonEmpty(); v().erase(v().end() - 1); }
|
||||
bool removeOne(const T &value) { int idx = indexOf(value); if (idx >= 0) { removeAt(idx); return true; } else { return false; } }
|
||||
void replace(int i, const T &value) { checkIndex(i); (*this)[i] = value; }
|
||||
void swap(int i, int j) { checkIndex(i); checkIndex(j); std::swap((*this)[i], (*this)[j]); }
|
||||
|
||||
T takeAt(int i) { T value = value(i); removeAt(i); return value; }
|
||||
T takeFirst() { return takeAt(0); }
|
||||
T takeLast() { return takeAt(size() - 1); }
|
||||
|
||||
Set<T> toSet() const;
|
||||
Vector<T> toVector() const;
|
||||
|
||||
List operator+(const List &other) const { List result = *this; result += other; return result; }
|
||||
List &operator+=(const List &other) { append(other); return *this; }
|
||||
List &operator+=(const T &value) { append(value); return *this; }
|
||||
List &operator<<(const List &other) { append(other); return *this; }
|
||||
List &operator<<(const T &value) { append(value); return *this; }
|
||||
|
||||
bool operator==(const List &other) const
|
||||
{
|
||||
if (size() == other.size())
|
||||
{
|
||||
std::pair<std_const_iterator, std_const_iterator> itr = std::mismatch(v().begin(), v().end(), other.v().begin());
|
||||
return itr.first == v().end();
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool operator!=(const List &other) const { return !(*this == other); }
|
||||
};
|
||||
|
||||
|
||||
template<typename T>
|
||||
class Vector : public List<T>
|
||||
{
|
||||
Vector(const List<T> &list) : List<T>(list) {}
|
||||
Vector mid(int pos, int length = -1) const { return List<T>::mid(pos, length).toVector(); }
|
||||
Vector operator+(const List<T> &other) const { Vector result = *this; result += other; return result; }
|
||||
Vector &operator+=(const List<T> &other) { append(other); return *this; }
|
||||
Vector &operator+=(const T &value) { append(value); return *this; }
|
||||
Vector &operator<<(const Vector &other) { append(other); return *this; }
|
||||
Vector &operator<<(const T &value) { append(value); return *this; }
|
||||
};
|
||||
|
||||
|
||||
template<typename T>
|
||||
inline Vector<T> List<T>::toVector() const
|
||||
{
|
||||
return Vector<T>(*this);
|
||||
}
|
||||
|
||||
|
||||
} // namespace moo
|
||||
|
||||
#endif /* MOO_CPP_CONT_H */
|
||||
/* -%- strip:true -%- */
|
105
moo/mooutils/moocpp-gobject.cpp
Normal file
105
moo/mooutils/moocpp-gobject.cpp
Normal file
@ -0,0 +1,105 @@
|
||||
#include "moocpp-gobject.h"
|
||||
|
||||
namespace moo {
|
||||
|
||||
struct GObjTypeInfo
|
||||
{
|
||||
GObjectCppProxyImpl*(*createObject)(GObject*);
|
||||
};
|
||||
|
||||
static GQuark moo_gobj_quark()
|
||||
{
|
||||
static GQuark q;
|
||||
if (G_UNLIKELY(!q))
|
||||
q = g_quark_from_static_string("moo-gobject-cpp-proxy");
|
||||
return q;
|
||||
}
|
||||
|
||||
static GObjTypeInfo *peekTypeInfo(GType type)
|
||||
{
|
||||
return static_cast<GObjTypeInfo*>(g_type_get_qdata(type, moo_gobj_quark()));
|
||||
}
|
||||
|
||||
static GObjTypeInfo *getTypeInfo(GType type)
|
||||
{
|
||||
GObjTypeInfo *ti = NULL;
|
||||
|
||||
while (true)
|
||||
{
|
||||
ti = peekTypeInfo(type);
|
||||
if (ti != NULL || type == G_TYPE_OBJECT)
|
||||
break;
|
||||
type = g_type_parent(type);
|
||||
}
|
||||
|
||||
g_return_val_if_fail(ti != NULL, NULL);
|
||||
return ti;
|
||||
}
|
||||
|
||||
static void setTypeInfo(GType type, GObjTypeInfo *ti)
|
||||
{
|
||||
g_type_set_qdata(type, moo_gobj_quark(), ti);
|
||||
}
|
||||
|
||||
GObjectCppProxyImpl::GObjectCppProxyImpl(GObject *gobj)
|
||||
: m_gobj(0)
|
||||
{
|
||||
g_return_if_fail(gobj != NULL && g_object_get_qdata(m_gobj, moo_gobj_quark()) == NULL);
|
||||
m_gobj = gobj;
|
||||
g_object_set_qdata(m_gobj, moo_gobj_quark(), this);
|
||||
g_object_weak_ref(m_gobj, (GWeakNotify) weakNotify, this);
|
||||
}
|
||||
|
||||
GObjectCppProxyImpl::~GObjectCppProxyImpl()
|
||||
{
|
||||
if (m_gobj)
|
||||
{
|
||||
g_critical("%s: oops", G_STRLOC);
|
||||
g_object_set_qdata(m_gobj, moo_gobj_quark(), NULL);
|
||||
g_object_weak_unref(m_gobj, (GWeakNotify) weakNotify, this);
|
||||
m_gobj = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void GObjectCppProxyImpl::weakNotify(void *data, GObject *dead)
|
||||
{
|
||||
GObjectCppProxyImpl *self = static_cast<GObjectCppProxyImpl*>(data);
|
||||
g_return_if_fail(self->m_gobj == dead);
|
||||
self->m_gobj = NULL;
|
||||
self->unref();
|
||||
}
|
||||
|
||||
GObjectCppProxyImpl *GObjectCppProxyImpl::get(GObject *gobj)
|
||||
{
|
||||
GObjectCppProxyImpl *proxy;
|
||||
|
||||
g_return_val_if_fail(gobj != NULL, NULL);
|
||||
|
||||
proxy = static_cast<GObjectCppProxyImpl*>(g_object_get_qdata(gobj, moo_gobj_quark()));
|
||||
|
||||
if (!proxy)
|
||||
{
|
||||
GObjTypeInfo *ti = getTypeInfo(G_OBJECT_TYPE(gobj));
|
||||
g_return_val_if_fail(ti != NULL, NULL);
|
||||
proxy = ti->createObject(gobj);
|
||||
}
|
||||
|
||||
return proxy;
|
||||
}
|
||||
|
||||
void GObjectCppProxyImpl::registerGType(GType type, GObjectCppProxyImpl*(*createFunc)(GObject *gobj))
|
||||
{
|
||||
g_return_if_fail(g_type_is_a(type, G_TYPE_OBJECT));
|
||||
g_return_if_fail(createFunc != NULL);
|
||||
g_return_if_fail(peekTypeInfo(type) == NULL);
|
||||
|
||||
GObjTypeInfo *ti = g_new0(GObjTypeInfo, 1);
|
||||
|
||||
ti->createObject = createFunc;
|
||||
|
||||
setTypeInfo(type, ti);
|
||||
}
|
||||
|
||||
|
||||
} // namespace moo
|
||||
/* -%- strip:true -%- */
|
149
moo/mooutils/moocpp-gobject.h
Normal file
149
moo/mooutils/moocpp-gobject.h
Normal file
@ -0,0 +1,149 @@
|
||||
/*
|
||||
* moocppg-gobject.h
|
||||
*
|
||||
* Copyright (C) 2004-2009 by Yevgen Muntyan <muntyan@tamu.edu>
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef MOO_CPP_GOBJECT_H
|
||||
#define MOO_CPP_GOBJECT_H
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <mooutils/moocpp-macros.h>
|
||||
#include <mooutils/moocpp-refptr.h>
|
||||
|
||||
namespace moo {
|
||||
|
||||
template<typename GObjType> class GObjectTypeHelper;
|
||||
|
||||
class GObjectCppProxyImpl
|
||||
: public RefCounted<GObjectCppProxyImpl>
|
||||
, public WeakRefd<GObjectCppProxyImpl>
|
||||
{
|
||||
private:
|
||||
GObject *m_gobj;
|
||||
|
||||
protected:
|
||||
GObjectCppProxyImpl(GObject *gobj);
|
||||
virtual ~GObjectCppProxyImpl();
|
||||
|
||||
private:
|
||||
MOO_DISABLE_COPY_AND_ASSIGN(GObjectCppProxyImpl)
|
||||
static void weakNotify(void *data, GObject *dead);
|
||||
|
||||
protected:
|
||||
GObject *gobj() { return m_gobj; }
|
||||
|
||||
static GObjectCppProxyImpl *get(GObject *gobj);
|
||||
|
||||
static void registerGType(GType type, GObjectCppProxyImpl*(*createFunc)(GObject *gobj));
|
||||
static void registerGType() {}
|
||||
};
|
||||
|
||||
template<typename GObjTypeParent, typename GObjTypeChild>
|
||||
GObjTypeParent *down_cast(GObjTypeChild *c)
|
||||
{
|
||||
typedef typename GObjectTypeHelper<GObjTypeChild>::TCppClass CppClassC;
|
||||
typedef typename GObjectTypeHelper<GObjTypeParent>::TCppClass CppClassP;
|
||||
mCanCast(CppClassC, CppClassP);
|
||||
return (GObjTypeParent*) c;
|
||||
}
|
||||
|
||||
template<typename GObjTypeChild, typename GObjTypeParent>
|
||||
GObjTypeChild *runtime_cast(GObjTypeParent *p)
|
||||
{
|
||||
typedef typename GObjectTypeHelper<GObjTypeChild>::TCppClass CppClass;
|
||||
if (g_type_is_a(G_OBJECT_TYPE(p), CppClass::gtype()))
|
||||
return (GObjTypeChild*) p;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define MOO_GOBJECT_PROXY_NC(CppClass, ParentCppClass, GObjType, GET_TYPE_MACRO)\
|
||||
private: \
|
||||
static GObjectCppProxyImpl *createObject(GObject *gobj) \
|
||||
{ \
|
||||
return new CppClass(gobj); \
|
||||
} \
|
||||
\
|
||||
public: \
|
||||
GObjType *gobj() \
|
||||
{ \
|
||||
return G_TYPE_CHECK_INSTANCE_CAST( \
|
||||
GObjectCppProxyImpl::gobj(), CppClass::gtype(), GObjType); \
|
||||
} \
|
||||
\
|
||||
const GObjType *gobj() const \
|
||||
{ \
|
||||
return const_cast<CppClass*>(this)->gobj(); \
|
||||
} \
|
||||
\
|
||||
static void registerGType() \
|
||||
{ \
|
||||
static bool beenHere = false; \
|
||||
if (!beenHere) \
|
||||
{ \
|
||||
beenHere = true; \
|
||||
ParentCppClass::registerGType(); \
|
||||
GObjectCppProxyImpl::registerGType(gtype(), createObject); \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
static GType gtype() \
|
||||
{ \
|
||||
registerGType(); \
|
||||
return GET_TYPE_MACRO; \
|
||||
} \
|
||||
\
|
||||
static SharedPtr<CppClass> get(GObjType *gobj) \
|
||||
{ \
|
||||
registerGType(); \
|
||||
return static_cast<CppClass*>(GObjectCppProxyImpl::get(G_OBJECT(gobj)));\
|
||||
} \
|
||||
\
|
||||
template<typename OtherGObjType> \
|
||||
static SharedPtr<CppClass> get(OtherGObjType *gobj) \
|
||||
{ \
|
||||
return GObjectTypeHelper<OtherGObjType>::TCppClass::get(gobj); \
|
||||
}
|
||||
|
||||
#define MOO_GOBJECT_CONSTRUCTOR(CppClass, ParentCppClass) \
|
||||
protected: \
|
||||
CppClass(GObject *gobj) : ParentCppClass(gobj) {}
|
||||
|
||||
#define MOO_GOBJECT_PROXY(CppClass, ParentCppClass, GObjType, G_TYPE_MACRO) \
|
||||
MOO_GOBJECT_PROXY_NC(CppClass, ParentCppClass, GObjType, G_TYPE_MACRO) \
|
||||
MOO_GOBJECT_CONSTRUCTOR(CppClass, ParentCppClass)
|
||||
|
||||
#define MOO_DEFINE_GOBJECT_PROXY_CLASS(CppClass, ParentCppClass, \
|
||||
GObjType, G_TYPE_MACRO) \
|
||||
class CppClass : public ParentCppClass \
|
||||
{ \
|
||||
MOO_GOBJECT_PROXY(CppClass, ParentCppClass, GObjType, G_TYPE_MACRO) \
|
||||
}
|
||||
|
||||
#define MOO_DEFINE_GOBJECT_HELPER_CLASS(CppClass, GObjType) \
|
||||
template<> class GObjectTypeHelper<GObjType> \
|
||||
{ \
|
||||
public: \
|
||||
typedef GObjType TGObjType; \
|
||||
typedef CppClass TCppClass; \
|
||||
}
|
||||
|
||||
namespace G {
|
||||
MOO_DEFINE_GOBJECT_PROXY_CLASS(Object, GObjectCppProxyImpl, GObject, G_TYPE_OBJECT);
|
||||
}
|
||||
MOO_DEFINE_GOBJECT_HELPER_CLASS(G::Object, GObject);
|
||||
|
||||
} // namespace moo
|
||||
|
||||
#endif /* MOO_CPP_GOBJECT_H */
|
||||
/* -%- strip:true -%- */
|
149
moo/mooutils/moocpp-gtk.h
Normal file
149
moo/mooutils/moocpp-gtk.h
Normal file
@ -0,0 +1,149 @@
|
||||
/*
|
||||
* moocppg-gtk.h
|
||||
*
|
||||
* Copyright (C) 2004-2009 by Yevgen Muntyan <muntyan@tamu.edu>
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef MOO_CPP_GTK_H
|
||||
#define MOO_CPP_GTK_H
|
||||
|
||||
#include <mooutils/moocpp-gobject.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
namespace moo {
|
||||
|
||||
#define _MOO_DEFINE_GTK_PROXY_CLASS(Name, Parent, NAME) \
|
||||
namespace Gtk { \
|
||||
MOO_DEFINE_GOBJECT_PROXY_CLASS(Name, Parent, \
|
||||
Gtk##Name, \
|
||||
GTK_TYPE_##NAME); \
|
||||
} \
|
||||
MOO_DEFINE_GOBJECT_HELPER_CLASS(Gtk::Name, Gtk##Name)
|
||||
|
||||
#define MOO_DEFINE_GTK_PROXY_CLASS(Name, Parent, NAME) _MOO_DEFINE_GTK_PROXY_CLASS(Name, Parent, NAME)
|
||||
#define MOO_DEFINE_GTK_PROXY_CLASS_GOBJ(Name, NAME) _MOO_DEFINE_GTK_PROXY_CLASS(Name, G::Object, NAME)
|
||||
|
||||
MOO_DEFINE_GTK_PROXY_CLASS_GOBJ(Object, OBJECT);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(Widget, Object, WIDGET);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(Container, Widget, CONTAINER);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(Bin, Container, BIN);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(Window, Bin, WINDOW);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(Dialog, Window, DIALOG);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(AboutDialog, Dialog, ABOUT_DIALOG);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(FileChooserDialog, Dialog, FILE_CHOOSER_DIALOG);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(FontSelectionDialog, Dialog, FONT_SELECTION_DIALOG);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(MessageDialog, Dialog, MESSAGE_DIALOG);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(Button, Bin, BUTTON);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(ToggleButton, Button, TOGGLE_BUTTON);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(CheckButton, ToggleButton, CHECK_BUTTON);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(RadioButton, CheckButton, RADIO_BUTTON);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(ColorButton, Button, COLOR_BUTTON);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(FontButton, Button, FONT_BUTTON);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(Item, Bin, ITEM);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(MenuItem, Item, MENU_ITEM);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(CheckMenuItem, MenuItem, CHECK_MENU_ITEM);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(RadioMenuItem, CheckMenuItem, RADIO_MENU_ITEM);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(ImageMenuItem, MenuItem, IMAGE_MENU_ITEM);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(SeparatorMenuItem, MenuItem, SEPARATOR_MENU_ITEM);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(ComboBox, Bin, COMBO_BOX);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(ComboBoxEntry, ComboBox, COMBO_BOX_ENTRY);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(EventBox, Bin, EVENT_BOX);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(Expander, Bin, EXPANDER);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(ToolItem, Bin, TOOL_ITEM);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(ToolButton, ToolItem, TOOL_BUTTON);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(MenuToolButton, ToolButton, MENU_TOOL_BUTTON);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(ToggleToolButton, ToolButton, TOGGLE_TOOL_BUTTON);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(RadioToolButton, ToggleToolButton, RADIO_TOOL_BUTTON);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(SeparatorToolItem, ToolItem, SEPARATOR_TOOL_ITEM);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(ScrolledWindow, Bin, SCROLLED_WINDOW);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(Viewport, Bin, VIEWPORT);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(Box, Container, BOX);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(ButtonBox, Box, BUTTON_BOX);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(HButtonBox, ButtonBox, HBUTTON_BOX);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(VButtonBox, ButtonBox, VBUTTON_BOX);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(VBox, Box, VBOX);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(HBox, Box, HBOX);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(Statusbar, HBox, STATUSBAR);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(Paned, Container, PANED);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(HPaned, Paned, HPANED);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(VPaned, Paned, VPANED);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(IconView, Container, ICON_VIEW);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(MenuShell, Container, MENU_SHELL);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(MenuBar, MenuShell, MENU_BAR);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(Menu, MenuShell, MENU);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(Notebook, Container, NOTEBOOK);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(Table, Container, TABLE);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(TextView, Container, TEXT_VIEW);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(Toolbar, Container, TOOLBAR);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(TreeView, Container, TREE_VIEW);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(Misc, Widget, MISC);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(Label, Misc, LABEL);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(AccelLabel, Label, ACCEL_LABEL);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(Image, Misc, IMAGE);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(Calendar, Widget, CALENDAR);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(CellView, Widget, CELL_VIEW);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(DrawingArea, Widget, DRAWING_AREA);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(Entry, Widget, ENTRY);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(SpinButton, Entry, SPIN_BUTTON);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(Range, Widget, RANGE);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(Scale, Range, SCALE);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(HScale, Scale, HSCALE);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(VScale, Scale, VSCALE);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(Scrollbar, Range, SCROLLBAR);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(HScrollbar, Scrollbar, HSCROLLBAR);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(VScrollbar, Scrollbar, VSCROLLBAR);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(Separator, Widget, SEPARATOR);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(HSeparator, Widget, HSEPARATOR);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(VSeparator, Widget, VSEPARATOR);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(Progress, Widget, PROGRESS);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(ProgressBar, Progress, PROGRESS_BAR);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(Adjustment, Object, ADJUSTMENT);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(CellRenderer, Object, CELL_RENDERER);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(CellRendererText, CellRenderer, CELL_RENDERER_TEXT);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(CellRendererAccel, CellRendererText, CELL_RENDERER_ACCEL);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(CellRendererCombo, CellRendererText, CELL_RENDERER_COMBO);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(CellRendererSpin, CellRendererText, CELL_RENDERER_SPIN);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(CellRendererPixbuf, CellRenderer, CELL_RENDERER_PIXBUF);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(CellRendererProgress, CellRenderer, CELL_RENDERER_PROGRESS);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(CellRendererToggle, CellRenderer, CELL_RENDERER_TOGGLE);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(FileFilter, Object, FILE_FILTER);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(ItemFactory, Object, ITEM_FACTORY);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(TreeViewColumn, Object, TREE_VIEW_COLUMN);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS_GOBJ(AccelGroup, ACCEL_GROUP);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS_GOBJ(AccelMap, ACCEL_MAP);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS_GOBJ(Action, ACTION);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(ToggleAction, Action, TOGGLE_ACTION);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS(RadioAction, ToggleAction, RADIO_ACTION);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS_GOBJ(ActionGroup, ACTION_GROUP);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS_GOBJ(Clipboard, CLIPBOARD);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS_GOBJ(IconTheme, ICON_THEME);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS_GOBJ(ListStore, LIST_STORE);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS_GOBJ(Settings, SETTINGS);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS_GOBJ(Style, STYLE);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS_GOBJ(TextBuffer, TEXT_BUFFER);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS_GOBJ(TextChildAnchor, TEXT_CHILD_ANCHOR);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS_GOBJ(TextMark, TEXT_MARK);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS_GOBJ(TextTag, TEXT_TAG);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS_GOBJ(TextTagTable, TEXT_TAG_TABLE);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS_GOBJ(TreeModelFilter, TREE_MODEL_FILTER);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS_GOBJ(TreeModelSort, TREE_MODEL_SORT);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS_GOBJ(TreeSelection, TREE_SELECTION);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS_GOBJ(TreeStore, TREE_STORE);
|
||||
MOO_DEFINE_GTK_PROXY_CLASS_GOBJ(WindowGroup, WINDOW_GROUP);
|
||||
|
||||
#undef MOO_DEFINE_GTK_PROXY_CLASS
|
||||
#undef MOO_DEFINE_GTK_PROXY_CLASS_GOBJ
|
||||
|
||||
} // namespace moo
|
||||
|
||||
#endif /* MOO_CPP_GOBJECT_H */
|
||||
/* -%- strip:true -%- */
|
69
moo/mooutils/moocpp-macros.h
Normal file
69
moo/mooutils/moocpp-macros.h
Normal file
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* moocpp-macros.h
|
||||
*
|
||||
* Copyright (C) 2004-2009 by Yevgen Muntyan <muntyan@tamu.edu>
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef MOO_CPP_MACROS_H
|
||||
#define MOO_CPP_MACROS_H
|
||||
|
||||
#include <mooutils/mooutils-macros.h>
|
||||
|
||||
#define mAssert _MOO_DEBUG_ASSERT
|
||||
#define mCheck _MOO_RELEASE_ASSERT
|
||||
|
||||
#define mStaticAssert MOO_STATIC_ASSERT
|
||||
mStaticAssert(sizeof(char) == 1, "test");
|
||||
|
||||
namespace moo {
|
||||
namespace impl {
|
||||
|
||||
template<typename FromClass, typename ToClass>
|
||||
struct _mCanCast
|
||||
{
|
||||
static void check()
|
||||
{
|
||||
FromClass *p = 0;
|
||||
ToClass &q = *p;
|
||||
(void) q;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace impl
|
||||
} // namespace moo
|
||||
|
||||
#define mCanCast(FromClass, ToClass) moo::impl::_mCanCast<FromClass, ToClass>::check()
|
||||
|
||||
#define MOO_DISABLE_COPY_AND_ASSIGN(Class) \
|
||||
private: \
|
||||
Class(const Class&); \
|
||||
Class &operator=(const Class&);
|
||||
|
||||
#define MOO_IMPLEMENT_POINTER(Class, get_ptr_expr) \
|
||||
operator Class*() const { return get_ptr_expr; } \
|
||||
Class &operator*() const { return *(get_ptr_expr); } \
|
||||
Class *operator->() const { return get_ptr_expr; }
|
||||
|
||||
#define MOO_IMPLEMENT_POINTER_TO_MEM(Class, get_ptr_expr) \
|
||||
operator Class*() { return get_ptr_expr; } \
|
||||
operator const Class*() const { return get_ptr_expr; } \
|
||||
Class &operator*() { return *(get_ptr_expr); } \
|
||||
const Class &operator*() const { return *(get_ptr_expr); } \
|
||||
Class *operator->() { return get_ptr_expr; } \
|
||||
const Class *operator->() const { return get_ptr_expr; }
|
||||
|
||||
#define MOO_IMPLEMENT_BOOL(get_bool_expr) \
|
||||
operator bool() const { return get_bool_expr; } \
|
||||
bool operator !() const { return !(get_bool_expr); }
|
||||
|
||||
#endif /* MOO_CPP_MACROS_H */
|
||||
/* -%- strip:true -%- */
|
374
moo/mooutils/moocpp-refptr.h
Normal file
374
moo/mooutils/moocpp-refptr.h
Normal file
@ -0,0 +1,374 @@
|
||||
/*
|
||||
* moocpp-refptr.h
|
||||
*
|
||||
* Copyright (C) 2004-2009 by Yevgen Muntyan <muntyan@tamu.edu>
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef MOO_CPP_REFPTR_H
|
||||
#define MOO_CPP_REFPTR_H
|
||||
|
||||
#include <mooutils/moocpp-types.h>
|
||||
#include <mooutils/moocpp-cont.h>
|
||||
|
||||
namespace moo {
|
||||
|
||||
template<class T> class List;
|
||||
|
||||
template<class T>
|
||||
class RefCounted
|
||||
{
|
||||
protected:
|
||||
RefCounted() : m_ref(1) {}
|
||||
virtual ~RefCounted() {}
|
||||
|
||||
public:
|
||||
void ref()
|
||||
{
|
||||
m_ref.ref();
|
||||
}
|
||||
|
||||
void unref()
|
||||
{
|
||||
if (m_ref.unref())
|
||||
delete this;
|
||||
}
|
||||
|
||||
private:
|
||||
MOO_DISABLE_COPY_AND_ASSIGN(RefCounted)
|
||||
|
||||
private:
|
||||
RefCount m_ref;
|
||||
};
|
||||
|
||||
namespace impl
|
||||
{
|
||||
|
||||
template<class T>
|
||||
class DeleteObject
|
||||
{
|
||||
public:
|
||||
void operator() (T *p) { delete p; }
|
||||
|
||||
template<class U>
|
||||
operator DeleteObject<U>& () { mCanCast(T, U); return *reinterpret_cast<DeleteObject<U>*>(this); }
|
||||
};
|
||||
|
||||
} // namespace impl
|
||||
|
||||
template<class T, class TDeleter = impl::DeleteObject<T> >
|
||||
class OwningPtr
|
||||
{
|
||||
public:
|
||||
OwningPtr(T *p = 0) : m_p(p) {}
|
||||
~OwningPtr() { unset(); }
|
||||
|
||||
OwningPtr(const OwningPtr &op) : m_p(0) { set(op); }
|
||||
OwningPtr &operator=(const OwningPtr &op) { set(op); }
|
||||
|
||||
template<class U> OwningPtr(const U &u) : m_p(0) { set(u); }
|
||||
template<class U> OwningPtr &operator=(const U &u) { set(u); return *this; }
|
||||
|
||||
template<class U, class V>
|
||||
operator OwningPtr<U, V>& ()
|
||||
{
|
||||
mCanCast(T, U);
|
||||
mCanCast(TDeleter, V);
|
||||
return *reinterpret_cast<OwningPtr<U, V>*>(this);
|
||||
}
|
||||
|
||||
template<class U, class V>
|
||||
operator const OwningPtr<U, V>& () const
|
||||
{
|
||||
return const_cast<OwningPtr*>(this)->operator OwningPtr<U, V>&();
|
||||
}
|
||||
|
||||
MOO_IMPLEMENT_POINTER(T, m_p)
|
||||
MOO_IMPLEMENT_BOOL(m_p)
|
||||
|
||||
template<class U>
|
||||
void set(U *pu)
|
||||
{
|
||||
T *p = pu;
|
||||
if (m_p != p)
|
||||
{
|
||||
T *old = m_p;
|
||||
m_p = p;
|
||||
TDeleter()(old);
|
||||
}
|
||||
}
|
||||
|
||||
template<class U, class V>
|
||||
void set(const OwningPtr<U, V> &op)
|
||||
{
|
||||
mCanCast(U, T);
|
||||
T *p = op.steal();
|
||||
set(p);
|
||||
}
|
||||
|
||||
void unset()
|
||||
{
|
||||
T *p = m_p;
|
||||
m_p = 0;
|
||||
TDeleter()(p);
|
||||
}
|
||||
|
||||
T *get() const { return m_p; }
|
||||
T *steal() { T *p = m_p; m_p = 0; return p; }
|
||||
|
||||
private:
|
||||
T *m_p;
|
||||
};
|
||||
|
||||
namespace impl
|
||||
{
|
||||
|
||||
template<class T>
|
||||
class RefUnrefObject
|
||||
{
|
||||
public:
|
||||
static void ref(T *p) { p->ref(); }
|
||||
static void unref(T *p) { p->unref(); }
|
||||
|
||||
template<class U>
|
||||
operator RefUnrefObject<U>& () { mCanCast(T, U); return *reinterpret_cast<RefUnrefObject<U>*>(this); }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
template<class T, class TRefUnref = impl::RefUnrefObject<T> >
|
||||
class SharedPtr
|
||||
{
|
||||
private:
|
||||
inline static void ref(T *p) { if (p) TRefUnref::ref(p); }
|
||||
inline static void unref(T *p) { if (p) TRefUnref::unref(p); }
|
||||
|
||||
public:
|
||||
static SharedPtr take(T *p) { SharedPtr sp(p); unref(p); return sp; }
|
||||
|
||||
SharedPtr(T *p = 0) : m_p(0) { set(p); }
|
||||
~SharedPtr() { unset(); }
|
||||
|
||||
SharedPtr(const SharedPtr &sp) : m_p(0) { set(sp.m_p); }
|
||||
SharedPtr &operator=(const SharedPtr &sp) { set(sp.m_p); return *this; }
|
||||
|
||||
template<class U> SharedPtr(const U &u) : m_p(0) { set(u); }
|
||||
template<class U> SharedPtr &operator=(const U &u) { set(u); return *this; }
|
||||
|
||||
template<class U, class V>
|
||||
operator SharedPtr<U, V>& ()
|
||||
{
|
||||
mCanCast(T, U);
|
||||
mCanCast(TRefUnref, V);
|
||||
return *reinterpret_cast<SharedPtr<U, V>*>(this);
|
||||
}
|
||||
|
||||
template<class U, class V>
|
||||
operator const SharedPtr<U, V>& () const
|
||||
{
|
||||
return const_cast<SharedPtr*>(this)->operator SharedPtr<U, V>&();
|
||||
}
|
||||
|
||||
MOO_IMPLEMENT_POINTER(T, m_p)
|
||||
MOO_IMPLEMENT_BOOL(m_p)
|
||||
|
||||
template<class U, class V>
|
||||
void set(const SharedPtr<U, V> &sp)
|
||||
{
|
||||
mCanCast(U, T);
|
||||
set(sp.get());
|
||||
}
|
||||
|
||||
template<class U, class V>
|
||||
void set(const OwningPtr<U, V> &op)
|
||||
{
|
||||
mCanCast(U, T);
|
||||
set(op.get());
|
||||
}
|
||||
|
||||
template<class U>
|
||||
void set(U *pu)
|
||||
{
|
||||
if (m_p != pu)
|
||||
{
|
||||
T *old = m_p;
|
||||
m_p = pu;
|
||||
ref(m_p);
|
||||
unref(old);
|
||||
}
|
||||
}
|
||||
|
||||
void unset()
|
||||
{
|
||||
if (m_p != 0)
|
||||
{
|
||||
T *p = m_p;
|
||||
m_p = 0;
|
||||
unref(p);
|
||||
}
|
||||
}
|
||||
|
||||
T *get() const { return m_p; }
|
||||
T *steal() const { T *p = m_p; m_p = 0; return p; }
|
||||
|
||||
private:
|
||||
T *m_p;
|
||||
};
|
||||
|
||||
namespace impl {
|
||||
|
||||
class WeakPtrBase
|
||||
{
|
||||
public:
|
||||
WeakPtrBase() : m_p(0) {}
|
||||
~WeakPtrBase() { mAssert(m_p == 0); }
|
||||
|
||||
void unsetPtrNoNotify()
|
||||
{
|
||||
m_p = 0;
|
||||
}
|
||||
|
||||
protected:
|
||||
void set(void *p) { m_p = p; }
|
||||
|
||||
protected:
|
||||
void *m_p;
|
||||
};
|
||||
|
||||
} // namespace impl
|
||||
|
||||
template<class T>
|
||||
class WeakPtr : public impl::WeakPtrBase
|
||||
{
|
||||
public:
|
||||
WeakPtr(T *p = 0) { set(p); }
|
||||
~WeakPtr() { unset(); }
|
||||
|
||||
WeakPtr(const WeakPtr &op) { set(op); }
|
||||
WeakPtr &operator=(const WeakPtr &op) { set(op); }
|
||||
|
||||
template<class U> WeakPtr(const U &u) { set(u); }
|
||||
template<class U> WeakPtr &operator=(const U &u) { set(u); return *this; }
|
||||
|
||||
template<class U>
|
||||
operator WeakPtr<U>& ()
|
||||
{
|
||||
mCanCast(T, U);
|
||||
return *reinterpret_cast<WeakPtr<U>*>(this);
|
||||
}
|
||||
|
||||
template<class U>
|
||||
operator const WeakPtr<U>& () const
|
||||
{
|
||||
return const_cast<WeakPtr*>(this)->operator WeakPtr<U>&();
|
||||
}
|
||||
|
||||
MOO_IMPLEMENT_POINTER(T, get())
|
||||
MOO_IMPLEMENT_BOOL(get())
|
||||
|
||||
template<class U>
|
||||
void set(U *u)
|
||||
{
|
||||
T *p = u;
|
||||
T *old = get();
|
||||
if (old != p)
|
||||
{
|
||||
if (old)
|
||||
old->removeWeakPtr(*this);
|
||||
m_p = p;
|
||||
if (p)
|
||||
p->addWeakPtr(*this);
|
||||
}
|
||||
}
|
||||
|
||||
template<class U>
|
||||
void set(const WeakPtr<U> &wp)
|
||||
{
|
||||
mCanCast(U, T);
|
||||
T *p = wp.get();
|
||||
set(p);
|
||||
}
|
||||
|
||||
template<class U, class V>
|
||||
void set(const SharedPtr<U, V> &sp)
|
||||
{
|
||||
mCanCast(U, T);
|
||||
T *p = sp.get();
|
||||
set(p);
|
||||
}
|
||||
|
||||
template<class U, class V>
|
||||
void set(const OwningPtr<U, V> &op)
|
||||
{
|
||||
mCanCast(U, T);
|
||||
T *p = op.get();
|
||||
set(p);
|
||||
}
|
||||
|
||||
void unset()
|
||||
{
|
||||
T *old = get();
|
||||
if (old)
|
||||
old->removeWeakPtr(*this);
|
||||
m_p = 0;
|
||||
}
|
||||
|
||||
T *get() const { return static_cast<T*>(m_p); }
|
||||
};
|
||||
|
||||
template<class T>
|
||||
class WeakRefd
|
||||
{
|
||||
protected:
|
||||
WeakRefd()
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~WeakRefd()
|
||||
{
|
||||
notify();
|
||||
}
|
||||
|
||||
void notify()
|
||||
{
|
||||
for (int i = 0, c = m_ptrs.size(); i < c; ++i)
|
||||
m_ptrs[i]->unsetPtrNoNotify();
|
||||
m_ptrs.clear();
|
||||
}
|
||||
|
||||
public:
|
||||
template<class U>
|
||||
void addWeakPtr(WeakPtr<U> &wp)
|
||||
{
|
||||
mCanCast(U, T);
|
||||
mAssert(!m_ptrs.contains(&wp));
|
||||
m_ptrs.append(&wp);
|
||||
}
|
||||
|
||||
template<class U>
|
||||
void removeWeakPtr(WeakPtr<U> &wp)
|
||||
{
|
||||
mCanCast(U, T);
|
||||
mAssert(m_ptrs.contains(&wp));
|
||||
m_ptrs.removeAll(&wp);
|
||||
}
|
||||
|
||||
private:
|
||||
MOO_DISABLE_COPY_AND_ASSIGN(WeakRefd)
|
||||
|
||||
private:
|
||||
List<impl::WeakPtrBase*> m_ptrs;
|
||||
};
|
||||
|
||||
} // namespace moo
|
||||
|
||||
#endif /* MOO_CPP_REFPTR_H */
|
||||
/* -%- strip:true -%- */
|
43
moo/mooutils/moocpp-types.h
Normal file
43
moo/mooutils/moocpp-types.h
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* moocpp-types.h
|
||||
*
|
||||
* Copyright (C) 2004-2009 by Yevgen Muntyan <muntyan@tamu.edu>
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef MOO_CPP_TYPES_H
|
||||
#define MOO_CPP_TYPES_H
|
||||
|
||||
#include <mooutils/moocpp-macros.h>
|
||||
|
||||
namespace moo {
|
||||
|
||||
class RefCount
|
||||
{
|
||||
public:
|
||||
RefCount(int count) : m_count(count) { mCheck(count >= 0); }
|
||||
|
||||
operator int() const;
|
||||
|
||||
void ref();
|
||||
bool unref();
|
||||
|
||||
private:
|
||||
MOO_DISABLE_COPY_AND_ASSIGN(RefCount)
|
||||
|
||||
private:
|
||||
int m_count;
|
||||
};
|
||||
|
||||
} // namespace moo
|
||||
|
||||
#endif /* MOO_CPP_TYPES_H */
|
||||
/* -%- strip:true -%- */
|
71
moo/mooutils/moocpp.cpp
Normal file
71
moo/mooutils/moocpp.cpp
Normal file
@ -0,0 +1,71 @@
|
||||
#include "moocpp.h"
|
||||
|
||||
namespace moo {
|
||||
|
||||
RefCount::operator int() const
|
||||
{
|
||||
return g_atomic_int_get(&m_count);
|
||||
}
|
||||
|
||||
void RefCount::ref()
|
||||
{
|
||||
g_atomic_int_inc(&m_count);
|
||||
}
|
||||
|
||||
bool RefCount::unref()
|
||||
{
|
||||
mAssert(int(*this) > 0);
|
||||
return g_atomic_int_dec_and_test(&m_count) != 0;
|
||||
}
|
||||
|
||||
namespace _test {
|
||||
|
||||
#define MOO_CHECK_ERR 0
|
||||
|
||||
inline void func()
|
||||
{
|
||||
GtkTreeView *tv;
|
||||
GtkWidget *w;
|
||||
SharedPtr<Gtk::TreeView> sptv;
|
||||
SharedPtr<Gtk::Widget> spw;
|
||||
WeakPtr<Gtk::TreeView> wptv;
|
||||
WeakPtr<Gtk::Widget> wpw;
|
||||
|
||||
wptv = sptv;
|
||||
wpw = sptv;
|
||||
wpw = wptv;
|
||||
#if MOO_CHECK_ERR
|
||||
sptv = wptv;
|
||||
wptv = spw;
|
||||
wptv = wpw;
|
||||
#endif
|
||||
|
||||
spw = sptv;
|
||||
#if MOO_CHECK_ERR
|
||||
sptv = spw;
|
||||
#endif
|
||||
|
||||
sptv = Gtk::TreeView::get(tv);
|
||||
spw = Gtk::TreeView::get(tv);
|
||||
spw = Gtk::Widget::get(tv);
|
||||
spw = Gtk::Widget::get(w);
|
||||
#if MOO_CHECK_ERR
|
||||
Gtk::TreeView::get(w);
|
||||
sptv = Gtk::Widget::get(tv);
|
||||
sptv = Gtk::Widget::get(w);
|
||||
#endif
|
||||
|
||||
w = down_cast<GtkWidget>(w);
|
||||
w = runtime_cast<GtkWidget>(w);
|
||||
w = down_cast<GtkWidget>(tv);
|
||||
w = runtime_cast<GtkWidget>(tv);
|
||||
tv = runtime_cast<GtkTreeView>(w);
|
||||
#if MOO_CHECK_ERR
|
||||
tv = down_cast<GtkTreeView>(w);
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} // namespace moo
|
||||
// -%- strip:true -%-
|
31
moo/mooutils/moocpp.h
Normal file
31
moo/mooutils/moocpp.h
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* moocpp.h
|
||||
*
|
||||
* Copyright (C) 2004-2009 by Yevgen Muntyan <muntyan@tamu.edu>
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef MOO_CPP_H
|
||||
#define MOO_CPP_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include <mooutils/moocpp-macros.h>
|
||||
#include <mooutils/moocpp-types.h>
|
||||
#include <mooutils/moocpp-refptr.h>
|
||||
#include <mooutils/moocpp-cont.h>
|
||||
#include <mooutils/moocpp-gobject.h>
|
||||
#include <mooutils/moocpp-gtk.h>
|
||||
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* MOO_CPP_H */
|
||||
/* -%- strip:true -%- */
|
@ -17,36 +17,27 @@
|
||||
#define MOO_UTILS_MACROS_H
|
||||
|
||||
#if defined(__GNUC__)
|
||||
|
||||
#undef MOO_COMPILER_MSVC
|
||||
|
||||
#define MOO_COMPILER_GCC 1
|
||||
#define MOO_GCC_VERSION(maj,min) ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
|
||||
|
||||
# undef MOO_COMPILER_MSVC
|
||||
# define MOO_COMPILER_GCC 1
|
||||
# define MOO_GCC_VERSION(maj,min) ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
|
||||
#elif defined(_MSC_VER)
|
||||
|
||||
#define MOO_COMPILER_MSVC 1
|
||||
|
||||
#undef MOO_COMPILER_GCC
|
||||
#define MOO_GCC_VERSION(maj,min) (0)
|
||||
|
||||
# define MOO_COMPILER_MSVC 1
|
||||
# undef MOO_COMPILER_GCC
|
||||
# define MOO_GCC_VERSION(maj,min) (0)
|
||||
#else /* not gcc, not visual studio */
|
||||
|
||||
#undef MOO_COMPILER_MSVC
|
||||
|
||||
#undef MOO_COMPILER_GCC
|
||||
#define MOO_GCC_VERSION(maj,min) (0)
|
||||
|
||||
# undef MOO_COMPILER_MSVC
|
||||
# undef MOO_COMPILER_GCC
|
||||
# define MOO_GCC_VERSION(maj,min) (0)
|
||||
#endif /* gcc or visual studio */
|
||||
|
||||
#if defined(MOO_COMPILER_GCC)
|
||||
#define MOO_STRFUNC ((const char*) (__PRETTY_FUNCTION__))
|
||||
# define MOO_STRFUNC ((const char*) (__PRETTY_FUNCTION__))
|
||||
#elif defined(MOO_COMPILER_MSVC)
|
||||
#define MOO_STRFUNC ((const char*) (__FUNCTION__))
|
||||
# define MOO_STRFUNC ((const char*) (__FUNCTION__))
|
||||
#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
|
||||
#define MOO_STRFUNC ((const char*) (__func__))
|
||||
# define MOO_STRFUNC ((const char*) (__func__))
|
||||
#else
|
||||
#define MOO_STRFUNC ((const char*) (""))
|
||||
# define MOO_STRFUNC ((const char*) (""))
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
Loading…
x
Reference in New Issue
Block a user