--- /dev/null
+//d-ptr header
+//
+// (c) Konrad Rosenbaum, 2010
+// protected under the GNU LGPL v3 or at your option any newer
+
+#ifndef DPTR_H
+#define DPTR_H
+
+/**Declares a smart d-pointer, to be used inside class declaration.
+
+It also declares the internal nested classes DPrivate and Private - Private is the actual d-pointer class, while DPrivate is a wrapper that automatically allocates and deallocates the d-pointer.
+
+\param dp name of the d-pointer*/
+#define DECLARE_DPTR(dp) \
+ class Private; \
+ class DPrivate{\
+ public:DPrivate();DPrivate(const DPrivate&);~DPrivate();\
+ DPrivate&operator=(const DPrivate&);\
+ Private*operator->()const{return d;}private:Private*d;\
+ }; \
+ DPrivate dp;
+
+/**Creates definitions for methods of the d-pointer wrapper, to be used in implementation where the actual d-pointer class is implemented.
+
+\param Class the base class within which the d-pointer was declared*/
+#define DEFINE_DPTR(Class) \
+ Class::DPrivate::DPrivate(){d=new Class::Private;};\
+ Class::DPrivate::DPrivate(const Class::DPrivate&dp){d=new Class::Private(*(dp.d));};\
+ Class::DPrivate::~DPrivate(){delete d;}\
+ Class::DPrivate& Class::DPrivate::operator=(const Class::DPrivate&dp){*d=*(dp.d);return *this;}
+
+/**Expands to the fully qualified name of the d-pointer class.
+\param Class the fully qualified name of the class the d-pointer was declared in.*/
+#define DPTR_CLASS_NAME(Class) Class::Private
+///Expands to the local name of d-pointer classes (Private).
+#define DPTR_NAME Private
+
+/**Declares a smart shared d-pointer, to be used inside class declaration.
+
+It also declares the internal nested classes DPrivate and Private - Private is the actual d-pointer class, while DPrivate is a wrapper that automatically allocates and deallocates the d-pointer.
+
+The d-pointer class must be derived from SharedDPtr in order to work with this macro.
+
+\param Class the base class within which the d-pointer was declared
+\param dp name of the d-pointer*/
+//public:\
+// Class& operator=(const Class&c){dp=c.dp;return *this;}
+#define DECLARE_SHARED_DPTR(dp) \
+private:\
+ class Private; \
+ class DPrivate{public:\
+ DPrivate();DPrivate(const DPrivate&);~DPrivate();\
+ Private*operator->()const{return d;}\
+ DPrivate& operator=(const DPrivate&);\
+ private:\
+ Private*d;\
+ }; \
+ DPrivate dp;
+
+/**Base class of shared d-pointers. Use in conjunction with DECLARE_SHARED_DPTR and DEFINE_SHARED_DPTR */
+class SharedDPtr
+{
+ private:
+ int cnt;
+ public:
+ ///instantiates a shared d-pointer
+ SharedDPtr(){cnt=1;}
+ ///deletes a shared d-pointer
+ virtual ~SharedDPtr(){}
+ ///called by the wrapper to attach to a new instance
+ virtual void attach(){cnt++;}
+ ///called by the wrapper to detach from an instance
+ virtual void detach(){cnt--;if(cnt==0)delete this;}
+};
+
+/**Defines the methods of the shared d-pointer wrapper, to be used in implementation where the actual d-pointer class is implemented.
+
+\param Class the base class within which the d-pointer was declared*/
+#define DEFINE_SHARED_DPTR(Class) \
+ Class::DPrivate::DPrivate(){d=new Class::Private;}\
+ Class::DPrivate::DPrivate(const DPrivate&dp){d=dp.d;d->attach();}\
+ Class::DPrivate::~DPrivate(){d->detach();}\
+ Class::DPrivate& Class::DPrivate::operator=(const DPrivate&dp){d->detach();d=dp.d;d->attach();return *this;}
+
+
+#endif
HEADERS += \
+ dptr.h \
elam.h \
elamengine.h \
elamexpression.h \
- elamvalue.h
+ elamvalue.h \
+ elamintengine.h
SOURCES += \
elamvalue.cpp \
- elamengine.cpp
+ elamengine.cpp \
+ elamintengine.cpp
INCLUDEPATH += .
DEPENDPATH += .
#include "elamengine.h"
#include "elamvalue.h"
+class DPTR_CLASS_NAME(ELAMEngine)
+{
+
+};
+
+DEFINE_DPTR(ELAMEngine);
+
ELAMEngine::ELAMEngine(QObject* parent): QObject(parent)
{
/////////////////////////////////////////////////////////////////
// Unary Operator
-class ELAMUnaryOperator::Private
+class DPTR_CLASS_NAME(ELAMUnaryOperator):public SharedDPtr
{
public:
- //memory management
- int ctr;
- Private(){ctr=1;}
- void detach(){ctr--;if(ctr<=0)delete this;}
- void attach(){ctr++;}
- //callback mapping
QMap<int,ELAMUnaryOperatorCall>callmap;
};
+DEFINE_SHARED_DPTR(ELAMUnaryOperator)
+
ELAMUnaryOperator::ELAMUnaryOperator(const ELAMUnaryOperator& op)
+ :d(op.d)
{
- d=0;
- operator=(op);
}
ELAMUnaryOperator::ELAMUnaryOperator()
{
- d=new Private();
}
ELAMUnaryOperator::~ELAMUnaryOperator()
{
- if(d)d->detach();
- d=0;
}
-ELAMUnaryOperator& ELAMUnaryOperator::operator=(const ELAMUnaryOperator& op)
-{
- if(d)d->detach();
- d=op.d;
- if(d)d->attach();
- return *this;
-}
-
QVariant ELAMUnaryOperator::execute(const QVariant& op) const
{
if(d->callmap.size()==0)
{
d->callmap.remove(t);
}
+
+/////////////////////////////////////////////////////////////////
+// Unary Operator
+
+class DPTR_CLASS_NAME(ELAMBinaryOperator):public SharedDPtr
+{
+ public:
+ QMap<QPair<int,int>,ELAMBinaryOperatorCall>callmap;
+};
+DEFINE_SHARED_DPTR(ELAMBinaryOperator)
+
+
+ELAMBinaryOperator::ELAMBinaryOperator(const ELAMBinaryOperator& op)
+ :d(op.d)
+{
+}
+
+ELAMBinaryOperator::ELAMBinaryOperator()
+{
+
+}
+
+ELAMBinaryOperator::~ELAMBinaryOperator()
+{
+
+}
#include "elamexpression.h"
+#include "dptr.h"
+
/**pointer to a function wrapping an unary operator
\param op the operand to be worked on
\returns the result of the operation*/
class ELAMUnaryOperator
{
+ DECLARE_SHARED_DPTR(ELAMUnaryOperator,d);
public:
ELAMUnaryOperator(const ELAMUnaryOperator&);
ELAMUnaryOperator();
~ELAMUnaryOperator();
- ELAMUnaryOperator& operator=(const ELAMUnaryOperator&);
-
/**sets a callback function for the operator and a specific typ
\param callback the function to call, if it is null the type is deleted from this operators type list
\param type the type of variable to work on, this must be a type registered with QVariant, if this type is already known to the operator its callback is replaced
///calls the callback function associated with the type of the argument, throws an exception if there is no callback
QVariant execute(const QVariant&)const;
- private:
- class Private;
- Private *d;
};
/**pointer to a function wrapping a binary operator
\returns the result of the operation*/
typedef QVariant (*ELAMBinaryOperatorCall)(const QVariant&op1,const QVariant&op2);
+class ELAMBinaryOperator
+{
+ DECLARE_SHARED_DPTR(ELAMBinaryOperator,d);
+ public:
+ ELAMBinaryOperator(const ELAMBinaryOperator&);
+ ELAMBinaryOperator();
+ ~ELAMBinaryOperator();
+};
+
/**pointer to a function wrapping a mathematical function
\param args the list of arguments
\returns the result of the function*/
class ELAMEngine:public QObject
{
Q_OBJECT
+ DECLARE_DPTR(d);
public:
///instantiates an engine object
ELAMEngine(QObject*parent=0);
QVariant evaluate(QString);
///evaluates a parsed expression into a final value
QVariant evaluate(ELAMExpression);
-
-
- private:
- class Private;
- Private *d;
};
#endif
--- /dev/null
+// ELAM int engine definition implementation
+//
+// (c) Konrad Rosenbaum, 2010
+// protected under the GNU LGPL v3 or at your option any newer
+
+#include "elamintengine.h"
+
+ELAMIntEngine::ELAMIntEngine()
+{
+ configureIntEngine(*this);
+}
+
+void ELAMIntEngine::configureIntEngine(ELAMEngine& eng)
+{
+ //TODO: implement
+}
--- /dev/null
+//ELAM integer engine header
+//
+// (c) Konrad Rosenbaum, 2010
+// protected under the GNU LGPL v3 or at your option any newer
+
+#ifndef ELAM_INTENGINE_H
+#define ELAM_INTENGINE_H
+
+#include "elamengine.h"
+
+class ELAMIntEngine:public ELAMEngine
+{
+ public:
+ ELAMIntEngine();
+
+ static void configureIntEngine(ELAMEngine&);
+};
+
+#endif
--- /dev/null
+
+#include "dptrtest.h"
+
+#include <QtCore>
+
+class DPTR_CLASS_NAME(ClassWithDptr)
+{
+ public:
+ static int cnt;
+ int num;
+ Private(){num=cnt++;qDebug()<<"creates dptr"<<num;}
+ Private(const Private&p){num=p.num;qDebug()<<"copyconst dptr"<<num;}
+ ~Private(){qDebug()<<"delete dptr"<<num;}
+ Private& operator=(const Private&p){
+ qDebug()<<"copy dptr"<<p.num<<"onto"<<num;
+ num=p.num;
+ return *this;
+ }
+};
+int ClassWithDptr::Private::cnt=0;
+DEFINE_DPTR(ClassWithDptr)
+
+
+QString ClassWithDptr::toString()const
+{
+ return QString("class with dptr %1").arg(d->num);
+}
+
+class DPTR_CLASS_NAME(ClassWithSDptr):public SharedDPtr
+{
+ public:
+ static int cnt;
+ int num;
+ Private(){num=cnt++;qDebug()<<"creates dptr"<<num;}
+ Private(const Private&p){num=p.num;qDebug()<<"copyconst dptr"<<num;}
+ ~Private(){qDebug()<<"delete dptr"<<num;}
+ Private& operator=(const Private&p){
+ qDebug()<<"copy dptr"<<p.num<<"onto"<<num;
+ num=p.num;
+ return *this;
+ }
+};
+int ClassWithSDptr::Private::cnt=0;
+DEFINE_SHARED_DPTR(ClassWithSDptr)
+
+QString ClassWithSDptr::toString()const
+{
+ return QString("class with shared dptr %1").arg(d->num);
+}
--- /dev/null
+
+#include "dptrtest.h"
+
+#include <QtCore>
+#include <QtTest>
+#include <QDebug>
+
+void DPtrTest::simpleDP()
+{
+ qDebug()<<"dynamic"<<ClassWithDptr().toString();
+ qDebug()<<"dynamic"<<ClassWithDptr().toString();
+ ClassWithDptr so;
+ qDebug()<<"static"<<so.toString();
+ ClassWithDptr co(so);
+ qDebug()<<"static copy"<<co.toString();
+ qDebug()<<"dynamic copy"<<ClassWithDptr(so).toString();
+ co=ClassWithDptr();
+ qDebug()<<"overwritten"<<co.toString();
+}
+
+void DPtrTest::sharedDP()
+{
+ qDebug()<<"dynamic"<<ClassWithSDptr().toString();
+ qDebug()<<"dynamic"<<ClassWithSDptr().toString();
+ ClassWithSDptr so;
+ qDebug()<<"static"<<so.toString();
+ ClassWithSDptr co(so);
+ qDebug()<<"static copy"<<co.toString();
+ qDebug()<<"dynamic copy"<<ClassWithSDptr(so).toString();
+ co=ClassWithSDptr();
+ qDebug()<<"overwritten"<<co.toString();
+ so=co;
+ qDebug()<<"overwritten"<<so.toString();
+}
+
+
+QTEST_MAIN(DPtrTest)
\ No newline at end of file
--- /dev/null
+#include "../../src/dptr.h"
+
+#include <QString>
+
+class ClassWithDptr
+{
+ DECLARE_DPTR(d)
+ public:
+ QString toString()const;
+};
+
+class ClassWithSDptr
+{
+ DECLARE_SHARED_DPTR(d)
+ public:
+ QString toString()const;
+};
+
+
+#include <QObject>
+
+class DPtrTest:public QObject
+{
+ Q_OBJECT
+ private slots:
+ void simpleDP();
+ void sharedDP();
+};
--- /dev/null
+TEMPLATE = app
+TARGET = dptrtest
+QT -= gui
+CONFIG += qtestlib debug
+
+SOURCES += dptrtest.cpp dptrpriv.cpp
+HEADERS += dptrtest.h
\ No newline at end of file