ultimatepp/uppsrc/CbGen/CppGen.cpp
mdelfede 263ff5f895 changed svn layout
git-svn-id: svn://ultimatepp.org/upp/trunk@281 f0d560ea-af0d-0410-9eb7-867de7ffcac7
2008-06-07 22:31:27 +00:00

373 lines
14 KiB
C++

#include <Core/Core.h>
using namespace Upp;
String If(String s, String txt)
{
return IsNull(s) ? String() : txt;
}
void CallbackGen(String name, String rettype, int n, String extension, String atest = Null)
{
LOG("// -----------------------------------------------------------");
String classdef, classlist, paramdef, paramlist;
for(int i = 1; i <= n; i++) {
if(i > 1) {
classdef << ", ";
classlist << ", ";
paramdef << ", ";
paramlist << ", ";
}
classdef << Format("class P%d", i);
classlist << Format("P%d", i);
paramdef << Format("P%d p%d", i, i);
paramlist << Format("p%d", i);
}
String cl_list = If(classlist, "<" + classlist + ">");
String cl_temp = String("template <class OBJECT, class METHOD") << If(classdef, ", " + classdef) << ">";
String return_ = rettype == "void" ? "" : "return ";
String name_cl = name + cl_list;
LOG("");
if(!IsNull(classdef))
LOG("template <" << classdef << ">");
LOG("struct " << name << "Action {");
LOGBEGIN();
LOG("Atomic count;");
LOG("");
LOG("virtual " << rettype << " Execute(" + paramdef + ") = 0;");
LOG("virtual bool IsValid() const { return true; }");
// LOG("virtual bool IsEqual(const " << name << "Action *other) const = 0;");
// LOG("virtual unsigned GetHashValue() const = 0;");
LOG("");
LOG(name << "Action() { count = 1; }");
LOG("virtual ~" << name << "Action() {}");
LOGEND();
LOG("};");
LOG("");
LOG(cl_temp);
LOG("struct " << name << "MethodActionPte : public " << name << "Action" << cl_list + " {");
LOGBEGIN();
LOG("Ptr<OBJECT> object;");
LOG("METHOD method;");
LOG("");
if(rettype == "void")
LOG(rettype << " Execute(" << paramdef << ") { if(object) (object->*method)(" << paramlist << "); }");
else
LOG(rettype << " Execute(" << paramdef << ") { return object ? (object->*method)(" << paramlist << ") : false; }");
LOG("bool IsValid() const { return object; }");
// LOG("bool IsEqual(const " << name << "Action" << cl_list << " *other) const {");
// LOGBEGIN();
// LOG("const " << name << "MethodActionPte *q = dynamic_cast<const " << name <<
// "MethodActionPte *>(other);");
// LOG("return q ? q->object == object && q->method == method : false;");
// LOGEND();
// LOG("}");
// LOG("unsigned GetHashValue() const {");
// LOG("\treturn (unsigned)(uintptr_t)~object ^ (unsigned)brutal_cast<uintptr_t>(method);");
// LOG("}");
LOG("");
LOG(name << "MethodActionPte(OBJECT *object, METHOD method) "
": object(object), method(method) {}");
LOGEND();
LOG("};");
LOG("");
LOG(cl_temp);
LOG("struct " << name << "MethodAction : public " << name << "Action" << cl_list + " {");
LOGBEGIN();
LOG("OBJECT *object;");
LOG("METHOD method;");
LOG("");
LOG(rettype << " Execute(" << paramdef << ") { " <<
return_ << "(object->*method)(" << paramlist << "); }");
/* LOG("bool IsEqual(const " << name << "Action" << cl_list << " *other) const {");
LOGBEGIN();
LOG("const " << name << "MethodAction *q = dynamic_cast<const " << name <<
"MethodAction *>(other);");
LOG("return q ? q->object == object && q->method == method : false;");
LOGEND();
LOG("}");
LOG("unsigned GetHashValue() const {");
LOG("\treturn (unsigned)(uintptr_t)object ^ (unsigned)brutal_cast<uintptr_t>(method);");
LOG("}");
*/ LOG("");
LOG(name << "MethodAction(OBJECT *object, METHOD method) "
": object(object), method(method) {}");
LOGEND();
LOG("};");
LOG("");
if(!IsNull(classdef))
LOG("template <" << classdef << ">");
LOG("struct " << name << "FnAction : public " << name << "Action" << cl_list << " {");
LOGBEGIN();
LOG(rettype << " (*fn)(" << paramdef << ");");
LOG("");
LOG(rettype << " Execute(" << paramdef << ") { " << return_ << "(*fn)(" <<
paramlist << "); }");
/* LOG("bool IsEqual(const " << name << "Action" << cl_list << " *other) const {");
LOGBEGIN();
LOG("const " << name << "FnAction *q = dynamic_cast<const " << name <<
"FnAction *>(other);");
LOG("return q ? q->fn == fn : false;");
LOGEND();
LOG("}");
LOG("unsigned GetHashValue() const {");
LOG("\treturn (unsigned)(uintptr_t)fn;");
LOG("}");
*/ LOG("");
LOG(name << "FnAction(" << rettype << " (*fn)(" << paramdef << ")) : fn(fn) {}");
LOGEND();
LOG("};");
LOG("");
if(!IsNull(classdef))
LOG("template <" << classdef << ">");
LOG("class " << name << " : Moveable< " << name_cl << " > {");
LOGBEGIN();
LOG(name << "Action" << cl_list << " *action;");
LOG("");
LOG("void Retain() const { if(action " << atest << ") AtomicInc(action->count); }");
LOG("void Release() { if(action " << atest << " && AtomicDec(action->count) == 0) delete action; }");
LOG("");
LOG("bool operator==(const " << name << "&);");
LOG("bool operator!=(const " << name << "&);");
LOG("");
LOGEND();
LOG("public:");
LOGBEGIN();
LOG("typedef " << name << " CLASSNAME;");
LOG("");
LOG(name << "& operator=(const " << name << "& c);");
LOG(name << "(const " << name << "& c);");
LOG("void Clear() { Release(); action = NULL; }");
LOG("");
// LOG("unsigned GetHashValue() const { return action->GetHashValue(); }");
LOG("");
LOG(extension);
LOG("");
LOG("explicit " << name << "(" << name << "Action " << cl_list <<
" *newaction) { action = newaction; }");
// LOG(name << "& operator=(" << name << "Action" << cl_list <<
// " *newaction) { action = newaction; return *this; }");
LOG(name << "() { action = NULL; }");
LOG(name << "(_CNULL) { action = NULL; }");
LOG("~" << name << "();");
LOG("");
LOG("static " << name << " Empty() { return CNULL; }");
LOG("");
// LOG("friend bool operator==(const " << name << "& a, const " << name << "& b)");
// LOG("\t{ return a.action ? a.action->IsEqual(b.action) : !b.action; }");
// LOG("friend bool operator!=(const " << name << "& a, const " << name << " & b)");
// LOG("\t{ return !(a == b); }");
LOGEND();
LOG("};");
LOG("");
LOG(cl_temp);
LOG(name_cl << " pteback(OBJECT *object, " << rettype <<
" (METHOD::*method)(" << paramdef << ")) {");
LOG("\treturn " << name_cl <<
"(new " << name << "MethodActionPte<OBJECT, " << rettype << " (METHOD::*)(" <<
paramdef << ")" << If(classlist, ", " + classlist) << ">(object, method));");
LOG("}");
LOG("");
LOG(cl_temp);
LOG(name_cl << " callback(OBJECT *object, " << rettype <<
" (METHOD::*method)(" << paramdef << ")) {");
LOG("\treturn " << name_cl <<
"(new " << name << "MethodAction<OBJECT, " << rettype << " (METHOD::*)(" <<
paramdef << ")" << If(classlist, ", " + classlist) << ">(object, method));");
LOG("}");
LOG("");
LOG(cl_temp);
LOG(name_cl << " callback(const OBJECT *object, " << rettype <<
" (METHOD::*method)(" << paramdef << ") const) {");
LOG("\treturn " << name_cl <<
"(new " << name << "MethodAction<const OBJECT, " << rettype << " (METHOD::*)("
<< paramdef << ") const" << If(classlist, ", " + classlist) << ">(object, method));");
LOG("}");
LOG("");
if(!IsNull(classdef))
LOG("template <" << classdef << ">");
LOG("inline " << name_cl << " callback(" << rettype << " (*fn)(" << paramdef << ")) {");
LOG("\treturn " << name_cl << "(new " << name << "FnAction " << cl_list << "(fn));");
LOG("}");
LOG("");
if(!IsNull(classdef))
LOG("template <" << classdef << ">");
LOG("struct " << name << "ForkAction : public " << name << "Action" << cl_list << " {");
LOGBEGIN();
LOG(name_cl << " cb1, cb2;");
LOG("");
LOG(rettype << " Execute(" << paramdef << ") { cb1(" << paramlist <<
"); " << return_ << "cb2(" << paramlist << "); }");
// LOG("bool IsEqual(const " << name << "Action " << cl_list << " *other) const {");
// LOG("\tconst " << name << "ForkAction *q = dynamic_cast<const " << name
// << "ForkAction *>(other);");
// LOG("\treturn q ? q->cb1 == cb1 && q->cb2 == cb2 : false;");
// LOG("}");
// LOG("unsigned GetHashValue() const {");
// LOG("\treturn ::GetHashValue(cb1) ^ ::GetHashValue(cb2);");
// LOG("}");
LOG("");
LOG(name << "ForkAction(" << name_cl << " cb1, " << name_cl << " cb2)"
"\n\t : cb1(cb1), cb2(cb2) {}");
LOGEND();
LOG("};");
LOG("");
if(!IsNull(classdef))
LOG("template <" << classdef << ">");
LOG("inline " << name_cl << " Proxy(" << name_cl << "& cb)");
LOG("{");
LOG("\treturn callback(&cb, &" << name_cl << "::Execute);");
LOG("}");
LOG("");
if(IsNull(classdef)) {
LOG(name_cl << " callback(" << name_cl << " cb1, " << name_cl << " cb2);");
LOG(name_cl << "& operator<<(" << name_cl << "& a, " << name_cl << " b);");
LOG("");
LOG("#endif");
LOG("#ifdef CPP_PART__");
LOG("");
}
if(!IsNull(classdef))
LOG("template <" << classdef << ">");
LOG(name_cl << " callback(" << name_cl << " cb1, " << name_cl << " cb2)");
LOG("{");
LOG("\treturn " << name_cl << "(new " << name << "ForkAction " << cl_list << "(cb1, cb2));");
LOG("}");
LOG("");
if(!IsNull(classdef))
LOG("template <" << classdef << ">");
LOG(name_cl << "& operator<<(" << name_cl << "& a, " << name_cl << " b)");
LOG("{");
LOG("\tif(a)");
LOG("\t\ta = callback(a, b);");
LOG("\telse");
LOG("\t\ta = b;");
LOG("\treturn a;");
LOG("}");
LOG("");
if(!IsNull(classdef))
LOG("template <" << classdef << ">");
LOG(name_cl << "& " << name_cl << "::operator=(const " << name << "& c)");
LOG("{");
LOG("\tc.Retain();");
LOG("\tRelease();");
LOG("\taction = c.action;");
LOG("\treturn *this;");
LOG("}");
LOG("");
if(!IsNull(classdef))
LOG("template <" << classdef << ">");
LOG(name_cl << "::" << name << "(const " << name << "& c)");
LOG("{");
LOG("\taction = c.action;");
LOG("\tRetain();");
LOG("}");
LOG("");
if(!IsNull(classdef))
LOG("template <" << classdef << ">");
LOG(name_cl << "::~" << name << "()");
LOG("{");
LOG("\tRelease();");
LOG("}");
LOG("");
if(IsNull(classdef)) {
LOG("#endif");
LOG("#ifndef CPP_PART__");
LOG("");
}
};
CONSOLE_APP_MAIN
{
LOG("#ifndef CPP_PART__");
LOG("");
CallbackGen("Callback", "void", 0,
"operator bool() const { return action && action->IsValid(); }\n"
"void Execute() const;\n"
"void operator()() const { Execute(); }"
);
CallbackGen("Callback1", "void", 1,
"operator bool() const { return action && action->IsValid(); }\n"
"void Execute(P1 p1) const { if(action) action->Execute(p1); }\n"
"void operator()(P1 p1) const { Execute(p1); }"
);
CallbackGen("Callback2", "void", 2,
"operator bool() const { return action && action->IsValid(); }\n"
"void Execute(P1 p1, P2 p2) const { if(action) action->Execute(p1, p2); }\n"
"void operator()(P1 p1, P2 p2) const { Execute(p1, p2); }"
);
CallbackGen("Callback3", "void", 3,
"operator bool() const { return action && action->IsValid(); }\n"
"void Execute(P1 p1, P2 p2, P3 p3) const { if(action) action->Execute(p1, p2, p3); }\n"
"void operator()(P1 p1, P2 p2, P3 p3) const { Execute(p1, p2, p3); }"
);
CallbackGen("Callback4", "void", 4,
"operator bool() const { return action && action->IsValid(); }\n"
"void Execute(P1 p1, P2 p2, P3 p3, P4 p4) const { if(action) action->Execute(p1, p2, p3, p4); }\n"
"void operator()(P1 p1, P2 p2, P3 p3, P4 p4) const { Execute(p1, p2, p3, p4); }"
);
CallbackGen("Gate", "bool", 0,
"operator bool() const { return (void *)action != (void *)1 && action && action->IsValid(); }\n"
"bool Execute() const;\n"
"bool operator()() const { return Execute(); }\n"
"void ClearTrue() { Clear(); action = (GateAction *)1; }\n"
"void ClearFalse() { Clear(); }\n\n"
"Gate(bool b) { action = (GateAction *)(int)b; }",
"&& (void *)action != (void *)1"
);
CallbackGen("Gate1", "bool", 1,
"operator bool() const { return (void *)action != (void *)1 && action && action->IsValid(); }\n"
"bool Execute(P1 p1) const;\n"
"bool operator()(P1 p1) const { return Execute(p1); }\n"
"void ClearTrue() { Clear(); action = (Gate1Action<P1> *)1; }\n"
"void ClearFalse() { Clear(); }\n\n"
"Gate1(bool b) { action = (Gate1Action<P1> *)(uintptr_t)b; }",
"&& (void *)action != (void *)1"
);
CallbackGen("Gate2", "bool", 2,
"operator bool() const { return (void *)action != (void *)1 && action && action->IsValid(); }\n"
"bool Execute(P1 p1, P2 p2) const;\n"
"bool operator()(P1 p1, P2 p2) const { return Execute(p1, p2); }\n"
"void ClearTrue() { Clear(); action = (Gate2Action<P1, P2> *)1; }\n"
"void ClearFalse() { Clear(); }\n\n"
"Gate2(bool b) { action = (Gate2Action<P1, P2> *)(uintptr_t)b; }",
"&& (void *)action != (void *)1"
);
CallbackGen("Gate3", "bool", 3,
"operator bool() const { return (void *)action != (void *)1 && action && action->IsValid(); }\n"
"bool Execute(P1 p1, P2 p2, P3 p3) const;\n"
"bool operator()(P1 p1, P2 p2, P3 p3) const { return Execute(p1, p2, p3); }\n"
"void ClearTrue() { Clear(); action = (Gate3Action<P1, P2, P3> *)1; }\n"
"void ClearFalse() { Clear(); }\n\n"
"Gate3(bool b) { action = (Gate3Action<P1, P2, P3> *)(uintptr_t)b; }",
"&& (void *)action != (void *)1"
);
CallbackGen("Gate4", "bool", 4,
"operator bool() const { return (void *)action != (void *)1 && action && action->IsValid(); }\n"
"bool Execute(P1 p1, P2 p2, P3 p3, P4 p4) const;\n"
"bool operator()(P1 p1, P2 p2, P3 p3, P4 p4) const { return Execute(p1, p2, p3, p4); }\n"
"void ClearTrue() { Clear(); action = (Gate4Action<P1, P2, P3, P4> *)1; }\n"
"void ClearFalse() { Clear(); }\n\n"
"Gate4(bool b) { action = (Gate4Action<P1, P2, P3, P4> *)(uintptr_t)b; }",
"&& (void *)action != (void *)1"
);
LOG("");
LOG("#endif");
}