Bunch of C++ utils

This commit is contained in:
Yevgen Muntyan 2009-11-22 18:11:08 -08:00
parent 7bf6b3d849
commit 5df6c2d0c7
11 changed files with 1348 additions and 22 deletions

View File

@ -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
View 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 -%- */

View 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 -%- */

View 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
View 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 -%- */

View 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 -%- */

View 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 -%- */

View 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
View 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
View 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 -%- */

View File

@ -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