mugicpp v1.0.5
mugicpp
Code generation tool for C++
Instalation
npm i mugicpp --saveUsage
Import
const {acc, qt, cpp, sc, st, CppClass, CppSignature, parseClass, parseMethod, ref, constRef, pointer, constp} = require('mugicpp')Class
let foo = new CppClass('Foo')
foo.constructor_()
foo.constructor_('int foo, const QString& bar')
foo.destructor().virtual()This creates class with empty constructor and parametrized constructor and virtual destructor with empty implementation.
Members
foo.member('mBar', cpp.int, 0)
foo.member('mFoo', qt.QString, undefined, {getter: true, setter: false, access: acc.PRIVATE})This creates int member mBar with default value 0, to which it will be initialized in empty constructor, but in parametrized constructor it will be initialized to bar argument value because members bound to constructor args by name. mBar is protected, mFoo is private.
Getters and setters are public by default or have access specified in options, like this: {getter: acc.PROTECTED, setter: acc.PRIVATE} ({getter: true} is the same as {getter: acc.PUBLIC})
Getters and setters
Public getter and setter added for each member unless there is {getter: false, setter: false} in CppClass options or in member options. mBar will have getter function int bar() const and setter void setBar(int value), mFoo will not be initialized in empty constructor and will not have setter.
Getter and setter names can be overriden with style CppClass option.
| style | getter | setter |
|---|---|---|
st.SETTER_SET_NAME (default) | bar() | setBar(int value) |
0 | bar() | bar(int value) |
st.GETTER_GET_NAME + st.SETTER_SET_NAME | getBar() | setBar(int value) |
Methods
foo.method('clearBar', cpp.void, '', 'mBar = 0;').protected()
foo.method('moreThanTen', cpp.bool, 'int a, int b', 'return (a + b) > 10;').static()
foo.method('clicked', cpp.void, '').signal()
foo.method('onClicked', cpp.void, '', 'mBar++;').slot()
foo.method('implementMe', cpp.void, 'int a').pureVirtual()This creates protected method, static method, signal method, slot method and pure virtual method. Signal and slot can be also writen like this:
foo.signal('clicked', '')
foo.slot('onClicked', '', 'mBar++;')Functions
Functions declared just like methods
foo.function_('plusTen', cpp.int, 'int b', 'return b + 10;')Operators
Operator can be declared as method (inside class) or as function (outside class)
foo.methodOperator('+', 'Foo&', 'const Foo& arg', 'mBar += arg.bar(); return *this;')
foo.functionOperator('+', 'Foo', 'const Foo& arg1, const Foo& arg2', 'Foo res(arg1.bar() + arg2.bar()); return res;')Class members (global variables)
foo.global('count', cpp.int, '0')
foo.global('gFoo', 'Foo', 'Foo()').extern()This creates static variable int Foo::count and extern variable Foo gFoo
Forward declarations, enums, typedefs, preprocessor expressions
foo.definition('enum Type {TypeA, TypeB};', sc.CLASS)
foo.definition('class Foo;', sc.GLOBAL)
foo.definition('#define ROUND1(a) round((a) * 10.0) / 10.0', sc.IMPLEMENTATION_GLOBAL)This creates enum in class scope, forward declaration in global scope and definition in cpp file
Includes
All necessary includes added automaticaly if you define classNames in CppClass options, but you can add some manualy.
foo.include('special.h', true, true, false)
foo.include('SomeClass', false, false, true)This adds to header
#include <special.h>
class SomeClass;and to cpp
#include "someclass.h"Inheritance
foo.inherits('BaseFoo')
foo.constructor_('int bar' ,{BaseFoo: 'bar'})This adds inheritance and passes bar arg to base constructor
Namespace
Class and functions will be defined in namespace if namespace specified in CppClass options
Parsers
If you want to extend existing handwriten class you can either create generated class and inherit from handwriten class or move method implementations from cpp to header and use parseClass function. Also there is parseMethod function.
foo = parseClass(
`class Foo {
public:
Foo() : mBar(0) {
}
void test() {
cout << "hello world\\n";
}
protected:
int mBar;
};`)
foo.method(parseMethod(
`int Foo::minusTen(int b) const {
return b - 10;
}`
))Named arguments
If you want to implement "named arguments" pattern, there is CppNamedArgs class for this. It creates two classes - heavy implementation and lightweight stack-friendly proxy with chainable methods that calls implementation methods over a pointer.
Singleton
There is CppClassSingleton for singletons. It is just CppClass with instance() static method and mInstance class variable.
Class group
There is CppClassGroup for creating multiple coupled classes in single pair of source header files.
Only functions
There is CppNoClass for functions-only units.
Signature
Signatures for methods, functions, constructors and operators can be expressed as string or as name: type object. Simple types, references and pointers will be passed by value, all other types (except ones in simpleTypes in CppClass constructor options) will be passed as constant reference.
let foo = new CppClass('Foo', {simpleTypes: ['Bar']})
foo.method('foo', cpp.void, 'int a, const QString& b, Bar c, QString& d')can be writen as
let foo = new CppClass('Foo', {simpleTypes: ['Bar']})
foo.method('foo', cpp.void, {a: cpp.int, b: qt.QString, c: 'Bar', d: ref(qt.QString)})To use later form with optional arguments there is CppSignature class with signature(nameValues, nameOptionals) method
let options = {simpleTypes: ['Bar']}
let m = new CppClass('Model', options)
m.inherits('QStandardItemModel')
let s = new CppSignature(options)
m.constructor_(s.signature({rows: cpp.int, columns: cpp.int, parent: pointer(qt.QObject)},{parent: 0}),{QStandardItemModel: 'rows, columns, parent'})Output
foo.write(__dirname)This outputs generated code to "foo.h" and "foo.cpp" in specified directory.