From c9b2fda4fb3b784ad4787f89ce603ab80e114059 Mon Sep 17 00:00:00 2001 From: Jos van den Oever Date: Fri, 1 Sep 2017 22:00:24 +0200 Subject: [PATCH] Do not use templated types in c bindings --- demo/src/Bindings.cpp | 104 +++++++++++++++++++------------ src/cpp.cpp | 80 ++++++++++++++---------- src/structs.h | 46 ++++++++++++++ tests/test_list_rust.cpp | 34 +++------- tests/test_object_rust.cpp | 43 ++----------- tests/test_object_types_rust.cpp | 59 +++++++----------- tests/test_objects_rust.cpp | 43 ++----------- tests/test_tree_rust.cpp | 42 ++++--------- 8 files changed, 211 insertions(+), 240 deletions(-) diff --git a/demo/src/Bindings.cpp b/demo/src/Bindings.cpp index a0142f0..45e8f65 100644 --- a/demo/src/Bindings.cpp +++ b/demo/src/Bindings.cpp @@ -2,10 +2,10 @@ #include "Bindings.h" namespace { - template - struct option { + + struct option_quintptr { public: - T value; + quintptr value; bool some; operator QVariant() const { if (some) { @@ -14,19 +14,31 @@ namespace { return QVariant(); } }; - struct qbytearray_t { - private: - const char* data; - int len; + + struct option_QString { public: - qbytearray_t(const QByteArray& v): - data(v.data()), - len(v.size()) { - } - operator QByteArray() const { - return QByteArray(data, len); + QString value; + bool some; + operator QVariant() const { + if (some) { + return QVariant(value); + } + return QVariant(); } }; + + struct option_quint64 { + public: + quint64 value; + bool some; + operator QVariant() const { + if (some) { + return QVariant(value); + } + return QVariant(); + } + }; + struct qstring_t { private: const void* data; @@ -40,6 +52,29 @@ namespace { return QString::fromUtf8(static_cast(data), len); } }; + typedef void (*qstring_set)(QString*, qstring_t*); + void set_qstring(QString* v, qstring_t* val) { + *v = *val; + } + + struct qbytearray_t { + private: + const char* data; + int len; + public: + qbytearray_t(const QByteArray& v): + data(v.data()), + len(v.size()) { + } + operator QByteArray() const { + return QByteArray(data, len); + } + }; + typedef void (*qbytearray_set)(QByteArray*, qbytearray_t*); + void set_qbytearray(QByteArray* v, qbytearray_t* val) { + *v = *val; + } + struct qmodelindex_t { int row; quintptr id; @@ -60,15 +95,6 @@ namespace { { emit o->activeChanged(); } - -} -typedef void (*qstring_set)(QString*, qstring_t*); -void set_qstring(QString* v, qstring_t* val) { - *v = *val; -} -typedef void (*qbytearray_set)(QByteArray*, qbytearray_t*); -void set_qbytearray(QByteArray* v, qbytearray_t* val) { - *v = *val; } extern "C" { Demo::Private* demo_new(Demo*, Fibonacci*, void (*)(Fibonacci*), void (*)(Fibonacci*), FibonacciList*, @@ -84,17 +110,17 @@ extern "C" { void (*)(FileSystemTree*, quintptr, quintptr), void (*)(FileSystemTree*), void (*)(FileSystemTree*), - void (*)(FileSystemTree*, option, int, int), + void (*)(FileSystemTree*, option_quintptr, int, int), void (*)(FileSystemTree*), - void (*)(FileSystemTree*, option, int, int), + void (*)(FileSystemTree*, option_quintptr, int, int), void (*)(FileSystemTree*), Processes*, void (*)(Processes*), void (*)(const Processes*, quintptr, bool), void (*)(Processes*, quintptr, quintptr), void (*)(Processes*), void (*)(Processes*), - void (*)(Processes*, option, int, int), + void (*)(Processes*, option_quintptr, int, int), void (*)(Processes*), - void (*)(Processes*, option, int, int), + void (*)(Processes*, option_quintptr, int, int), void (*)(Processes*), TimeSeries*, void (*)(const TimeSeries*), void (*)(TimeSeries*, quintptr, quintptr), @@ -239,7 +265,7 @@ extern "C" { void file_system_tree_data_file_name(const FileSystemTree::Private*, quintptr, QString*, qstring_set); void file_system_tree_data_file_path(const FileSystemTree::Private*, quintptr, QString*, qstring_set); qint32 file_system_tree_data_file_permissions(const FileSystemTree::Private*, quintptr); - option file_system_tree_data_file_size(const FileSystemTree::Private*, quintptr); + option_quint64 file_system_tree_data_file_size(const FileSystemTree::Private*, quintptr); qint32 file_system_tree_data_file_type(const FileSystemTree::Private*, quintptr); void file_system_tree_sort(FileSystemTree::Private*, unsigned char column, Qt::SortOrder order = Qt::AscendingOrder); @@ -445,9 +471,9 @@ extern "C" { void (*)(FileSystemTree*, quintptr, quintptr), void (*)(FileSystemTree*), void (*)(FileSystemTree*), - void (*)(FileSystemTree*, option, int, int), + void (*)(FileSystemTree*, option_quintptr, int, int), void (*)(FileSystemTree*), - void (*)(FileSystemTree*, option, int, int), + void (*)(FileSystemTree*, option_quintptr, int, int), void (*)(FileSystemTree*)); void file_system_tree_free(FileSystemTree::Private*); void file_system_tree_path_get(const FileSystemTree::Private*, QString*, qstring_set); @@ -663,9 +689,9 @@ extern "C" { void (*)(Processes*, quintptr, quintptr), void (*)(Processes*), void (*)(Processes*), - void (*)(Processes*, option, int, int), + void (*)(Processes*, option_quintptr, int, int), void (*)(Processes*), - void (*)(Processes*, option, int, int), + void (*)(Processes*, option_quintptr, int, int), void (*)(Processes*)); void processes_free(Processes::Private*); bool processes_active_get(const Processes::Private*); @@ -922,7 +948,7 @@ Demo::Demo(QObject *parent): [](FileSystemTree* o) { o->endResetModel(); }, - [](FileSystemTree* o, option id, int first, int last) { + [](FileSystemTree* o, option_quintptr id, int first, int last) { if (id.some) { int row = file_system_tree_row(o->m_d, id.value); o->beginInsertRows(o->createIndex(row, 0, id.value), first, last); @@ -933,7 +959,7 @@ Demo::Demo(QObject *parent): [](FileSystemTree* o) { o->endInsertRows(); }, - [](FileSystemTree* o, option id, int first, int last) { + [](FileSystemTree* o, option_quintptr id, int first, int last) { if (id.some) { int row = file_system_tree_row(o->m_d, id.value); o->beginRemoveRows(o->createIndex(row, 0, id.value), first, last); @@ -966,7 +992,7 @@ Demo::Demo(QObject *parent): [](Processes* o) { o->endResetModel(); }, - [](Processes* o, option id, int first, int last) { + [](Processes* o, option_quintptr id, int first, int last) { if (id.some) { int row = processes_row(o->m_d, id.value); o->beginInsertRows(o->createIndex(row, 0, id.value), first, last); @@ -977,7 +1003,7 @@ Demo::Demo(QObject *parent): [](Processes* o) { o->endInsertRows(); }, - [](Processes* o, option id, int first, int last) { + [](Processes* o, option_quintptr id, int first, int last) { if (id.some) { int row = processes_row(o->m_d, id.value); o->beginRemoveRows(o->createIndex(row, 0, id.value), first, last); @@ -1198,7 +1224,7 @@ FileSystemTree::FileSystemTree(QObject *parent): [](FileSystemTree* o) { o->endResetModel(); }, - [](FileSystemTree* o, option id, int first, int last) { + [](FileSystemTree* o, option_quintptr id, int first, int last) { if (id.some) { int row = file_system_tree_row(o->m_d, id.value); o->beginInsertRows(o->createIndex(row, 0, id.value), first, last); @@ -1209,7 +1235,7 @@ FileSystemTree::FileSystemTree(QObject *parent): [](FileSystemTree* o) { o->endInsertRows(); }, - [](FileSystemTree* o, option id, int first, int last) { + [](FileSystemTree* o, option_quintptr id, int first, int last) { if (id.some) { int row = file_system_tree_row(o->m_d, id.value); o->beginRemoveRows(o->createIndex(row, 0, id.value), first, last); @@ -1286,7 +1312,7 @@ Processes::Processes(QObject *parent): [](Processes* o) { o->endResetModel(); }, - [](Processes* o, option id, int first, int last) { + [](Processes* o, option_quintptr id, int first, int last) { if (id.some) { int row = processes_row(o->m_d, id.value); o->beginInsertRows(o->createIndex(row, 0, id.value), first, last); @@ -1297,7 +1323,7 @@ Processes::Processes(QObject *parent): [](Processes* o) { o->endInsertRows(); }, - [](Processes* o, option id, int first, int last) { + [](Processes* o, option_quintptr id, int first, int last) { if (id.some) { int row = processes_row(o->m_d, id.value); o->beginRemoveRows(o->createIndex(row, 0, id.value), first, last); diff --git a/src/cpp.cpp b/src/cpp.cpp index 45bbad4..b3d5b37 100644 --- a/src/cpp.cpp +++ b/src/cpp.cpp @@ -7,7 +7,7 @@ template QString cppSetType(const T& p) { if (p.optional) { - return "option<" + p.type.cppSetType + ">"; + return "option_" + p.type.cppSetType; } return p.type.cppSetType; } @@ -507,9 +507,9 @@ void constructorArgsDecl(QTextStream& cpp, const Object& o, const Configuration& void (*)(%1*, quintptr, quintptr), void (*)(%1*), void (*)(%1*), - void (*)(%1*, option, int, int), + void (*)(%1*, option_quintptr, int, int), void (*)(%1*), - void (*)(%1*, option, int, int), + void (*)(%1*, option_quintptr, int, int), void (*)(%1*))").arg(o.name); } } @@ -580,7 +580,7 @@ void constructorArgs(QTextStream& cpp, const QString& prefix, const Object& o, c [](%1* o) { o->endResetModel(); }, - [](%1* o, option id, int first, int last) { + [](%1* o, option_quintptr id, int first, int last) { if (id.some) { int row = %2_row(o->m_d, id.value); o->beginInsertRows(o->createIndex(row, 0, id.value), first, last); @@ -591,7 +591,7 @@ void constructorArgs(QTextStream& cpp, const QString& prefix, const Object& o, c [](%1* o) { o->endInsertRows(); }, - [](%1* o, option id, int first, int last) { + [](%1* o, option_quintptr id, int first, int last) { if (id.some) { int row = %2_row(o->m_d, id.value); o->beginRemoveRows(o->createIndex(row, 0, id.value), first, last); @@ -799,10 +799,12 @@ void writeCpp(const Configuration& conf) { #include "%1" namespace { - template - struct option { +)").arg(conf.hFile.fileName()); + for (auto option: conf.optionalTypes()) { + cpp << QString(R"( + struct option_%1 { public: - T value; + %1 value; bool some; operator QVariant() const { if (some) { @@ -811,19 +813,10 @@ namespace { return QVariant(); } }; - struct qbytearray_t { - private: - const char* data; - int len; - public: - qbytearray_t(const QByteArray& v): - data(v.data()), - len(v.size()) { - } - operator QByteArray() const { - return QByteArray(data, len); - } - }; +)").arg(option); + } + if (conf.types().contains("QString")) { + cpp << R"( struct qstring_t { private: const void* data; @@ -837,11 +830,41 @@ namespace { return QString::fromUtf8(static_cast(data), len); } }; + typedef void (*qstring_set)(QString*, qstring_t*); + void set_qstring(QString* v, qstring_t* val) { + *v = *val; + } +)"; + } + if (conf.types().contains("QByteArray")) { + cpp << R"( + struct qbytearray_t { + private: + const char* data; + int len; + public: + qbytearray_t(const QByteArray& v): + data(v.data()), + len(v.size()) { + } + operator QByteArray() const { + return QByteArray(data, len); + } + }; + typedef void (*qbytearray_set)(QByteArray*, qbytearray_t*); + void set_qbytearray(QByteArray* v, qbytearray_t* val) { + *v = *val; + } +)"; + } + if (conf.hasListOrTree()) { + cpp << R"( struct qmodelindex_t { int row; quintptr id; }; -)").arg(conf.hFile.fileName()); +)"; + } for (auto o: conf.objects) { for (auto p: o.properties) { @@ -852,18 +875,7 @@ namespace { cpp << " {\n emit o->" << p.name << "Changed();\n }\n"; } } - - cpp << R"( -} -typedef void (*qstring_set)(QString*, qstring_t*); -void set_qstring(QString* v, qstring_t* val) { - *v = *val; -} -typedef void (*qbytearray_set)(QByteArray*, qbytearray_t*); -void set_qbytearray(QByteArray* v, qbytearray_t* val) { - *v = *val; -} -)"; + cpp << "}\n"; for (auto object: conf.objects) { if (object.type != ObjectType::Object) { diff --git a/src/structs.h b/src/structs.h index 80c4d34..1af89da 100644 --- a/src/structs.h +++ b/src/structs.h @@ -34,6 +34,14 @@ struct BindingTypeProperties { bool isComplex() const { return name.startsWith("Q"); } + bool operator==(const BindingTypeProperties& other) { + return type == other.type + && name == other.name + && cppSetType == other.cppSetType + && cSetType == other.cSetType + && rustType == other.rustType + && rustTypeInit == other.rustTypeInit; + } }; struct Property { @@ -89,5 +97,43 @@ struct Configuration { err.flush(); exit(1); } + QList types() const { + QList ops; + for (auto o: objects) { + for (auto ip: o.properties) { + if (!ops.contains(ip.type.name)) { + ops.append(ip.type.name); + } + } + for (auto ip: o.itemProperties) { + if (!ops.contains(ip.type.name)) { + ops.append(ip.type.name); + } + } + } + return ops; + } + QList optionalTypes() const { + QList ops; + for (auto o: objects) { + for (auto ip: o.itemProperties) { + if (ip.optional && !ops.contains(ip.type.name)) { + ops.append(ip.type.name); + } + } + if (o.type != ObjectType::Object && !ops.contains("quintptr")) { + ops.append("quintptr"); + } + } + return ops; + } + bool hasListOrTree() const { + for (auto o: objects) { + if (o.type == ObjectType::List || o.type == ObjectType::UniformTree) { + return true; + } + } + return false; + } }; diff --git a/tests/test_list_rust.cpp b/tests/test_list_rust.cpp index f0d8beb..25e8dc6 100644 --- a/tests/test_list_rust.cpp +++ b/tests/test_list_rust.cpp @@ -2,10 +2,10 @@ #include "test_list_rust.h" namespace { - template - struct option { + + struct option_quintptr { public: - T value; + quintptr value; bool some; operator QVariant() const { if (some) { @@ -14,19 +14,7 @@ namespace { return QVariant(); } }; - struct qbytearray_t { - private: - const char* data; - int len; - public: - qbytearray_t(const QByteArray& v): - data(v.data()), - len(v.size()) { - } - operator QByteArray() const { - return QByteArray(data, len); - } - }; + struct qstring_t { private: const void* data; @@ -40,19 +28,15 @@ namespace { return QString::fromUtf8(static_cast(data), len); } }; + typedef void (*qstring_set)(QString*, qstring_t*); + void set_qstring(QString* v, qstring_t* val) { + *v = *val; + } + struct qmodelindex_t { int row; quintptr id; }; - -} -typedef void (*qstring_set)(QString*, qstring_t*); -void set_qstring(QString* v, qstring_t* val) { - *v = *val; -} -typedef void (*qbytearray_set)(QByteArray*, qbytearray_t*); -void set_qbytearray(QByteArray* v, qbytearray_t* val) { - *v = *val; } extern "C" { void persons_data_user_name(const Persons::Private*, int, QString*, qstring_set); diff --git a/tests/test_object_rust.cpp b/tests/test_object_rust.cpp index bbd6987..cba4e3a 100644 --- a/tests/test_object_rust.cpp +++ b/tests/test_object_rust.cpp @@ -2,31 +2,7 @@ #include "test_object_rust.h" namespace { - template - struct option { - public: - T value; - bool some; - operator QVariant() const { - if (some) { - return QVariant(value); - } - return QVariant(); - } - }; - struct qbytearray_t { - private: - const char* data; - int len; - public: - qbytearray_t(const QByteArray& v): - data(v.data()), - len(v.size()) { - } - operator QByteArray() const { - return QByteArray(data, len); - } - }; + struct qstring_t { private: const void* data; @@ -40,23 +16,14 @@ namespace { return QString::fromUtf8(static_cast(data), len); } }; - struct qmodelindex_t { - int row; - quintptr id; - }; + typedef void (*qstring_set)(QString*, qstring_t*); + void set_qstring(QString* v, qstring_t* val) { + *v = *val; + } inline void personUserNameChanged(Person* o) { emit o->userNameChanged(); } - -} -typedef void (*qstring_set)(QString*, qstring_t*); -void set_qstring(QString* v, qstring_t* val) { - *v = *val; -} -typedef void (*qbytearray_set)(QByteArray*, qbytearray_t*); -void set_qbytearray(QByteArray* v, qbytearray_t* val) { - *v = *val; } extern "C" { Person::Private* person_new(Person*, void (*)(Person*)); diff --git a/tests/test_object_types_rust.cpp b/tests/test_object_types_rust.cpp index 779053e..1f7e27b 100644 --- a/tests/test_object_types_rust.cpp +++ b/tests/test_object_types_rust.cpp @@ -2,31 +2,7 @@ #include "test_object_types_rust.h" namespace { - template - struct option { - public: - T value; - bool some; - operator QVariant() const { - if (some) { - return QVariant(value); - } - return QVariant(); - } - }; - struct qbytearray_t { - private: - const char* data; - int len; - public: - qbytearray_t(const QByteArray& v): - data(v.data()), - len(v.size()) { - } - operator QByteArray() const { - return QByteArray(data, len); - } - }; + struct qstring_t { private: const void* data; @@ -40,10 +16,28 @@ namespace { return QString::fromUtf8(static_cast(data), len); } }; - struct qmodelindex_t { - int row; - quintptr id; + typedef void (*qstring_set)(QString*, qstring_t*); + void set_qstring(QString* v, qstring_t* val) { + *v = *val; + } + + struct qbytearray_t { + private: + const char* data; + int len; + public: + qbytearray_t(const QByteArray& v): + data(v.data()), + len(v.size()) { + } + operator QByteArray() const { + return QByteArray(data, len); + } }; + typedef void (*qbytearray_set)(QByteArray*, qbytearray_t*); + void set_qbytearray(QByteArray* v, qbytearray_t* val) { + *v = *val; + } inline void objectBooleanChanged(Object* o) { emit o->booleanChanged(); @@ -76,15 +70,6 @@ namespace { { emit o->uintegerChanged(); } - -} -typedef void (*qstring_set)(QString*, qstring_t*); -void set_qstring(QString* v, qstring_t* val) { - *v = *val; -} -typedef void (*qbytearray_set)(QByteArray*, qbytearray_t*); -void set_qbytearray(QByteArray* v, qbytearray_t* val) { - *v = *val; } extern "C" { Object::Private* object_new(Object*, void (*)(Object*), void (*)(Object*), void (*)(Object*), void (*)(Object*), void (*)(Object*), void (*)(Object*), void (*)(Object*), void (*)(Object*)); diff --git a/tests/test_objects_rust.cpp b/tests/test_objects_rust.cpp index 4f95ba4..92db53e 100644 --- a/tests/test_objects_rust.cpp +++ b/tests/test_objects_rust.cpp @@ -2,31 +2,7 @@ #include "test_objects_rust.h" namespace { - template - struct option { - public: - T value; - bool some; - operator QVariant() const { - if (some) { - return QVariant(value); - } - return QVariant(); - } - }; - struct qbytearray_t { - private: - const char* data; - int len; - public: - qbytearray_t(const QByteArray& v): - data(v.data()), - len(v.size()) { - } - operator QByteArray() const { - return QByteArray(data, len); - } - }; + struct qstring_t { private: const void* data; @@ -40,23 +16,14 @@ namespace { return QString::fromUtf8(static_cast(data), len); } }; - struct qmodelindex_t { - int row; - quintptr id; - }; + typedef void (*qstring_set)(QString*, qstring_t*); + void set_qstring(QString* v, qstring_t* val) { + *v = *val; + } inline void innerObjectDescriptionChanged(InnerObject* o) { emit o->descriptionChanged(); } - -} -typedef void (*qstring_set)(QString*, qstring_t*); -void set_qstring(QString* v, qstring_t* val) { - *v = *val; -} -typedef void (*qbytearray_set)(QByteArray*, qbytearray_t*); -void set_qbytearray(QByteArray* v, qbytearray_t* val) { - *v = *val; } extern "C" { Group::Private* group_new(Group*, Person*, InnerObject*, void (*)(InnerObject*)); diff --git a/tests/test_tree_rust.cpp b/tests/test_tree_rust.cpp index 0c57c56..e04e121 100644 --- a/tests/test_tree_rust.cpp +++ b/tests/test_tree_rust.cpp @@ -2,10 +2,10 @@ #include "test_tree_rust.h" namespace { - template - struct option { + + struct option_quintptr { public: - T value; + quintptr value; bool some; operator QVariant() const { if (some) { @@ -14,19 +14,7 @@ namespace { return QVariant(); } }; - struct qbytearray_t { - private: - const char* data; - int len; - public: - qbytearray_t(const QByteArray& v): - data(v.data()), - len(v.size()) { - } - operator QByteArray() const { - return QByteArray(data, len); - } - }; + struct qstring_t { private: const void* data; @@ -40,19 +28,15 @@ namespace { return QString::fromUtf8(static_cast(data), len); } }; + typedef void (*qstring_set)(QString*, qstring_t*); + void set_qstring(QString* v, qstring_t* val) { + *v = *val; + } + struct qmodelindex_t { int row; quintptr id; }; - -} -typedef void (*qstring_set)(QString*, qstring_t*); -void set_qstring(QString* v, qstring_t* val) { - *v = *val; -} -typedef void (*qbytearray_set)(QByteArray*, qbytearray_t*); -void set_qbytearray(QByteArray* v, qbytearray_t* val) { - *v = *val; } extern "C" { void persons_data_user_name(const Persons::Private*, quintptr, QString*, qstring_set); @@ -206,9 +190,9 @@ extern "C" { void (*)(Persons*, quintptr, quintptr), void (*)(Persons*), void (*)(Persons*), - void (*)(Persons*, option, int, int), + void (*)(Persons*, option_quintptr, int, int), void (*)(Persons*), - void (*)(Persons*, option, int, int), + void (*)(Persons*, option_quintptr, int, int), void (*)(Persons*)); void persons_free(Persons::Private*); }; @@ -244,7 +228,7 @@ Persons::Persons(QObject *parent): [](Persons* o) { o->endResetModel(); }, - [](Persons* o, option id, int first, int last) { + [](Persons* o, option_quintptr id, int first, int last) { if (id.some) { int row = persons_row(o->m_d, id.value); o->beginInsertRows(o->createIndex(row, 0, id.value), first, last); @@ -255,7 +239,7 @@ Persons::Persons(QObject *parent): [](Persons* o) { o->endInsertRows(); }, - [](Persons* o, option id, int first, int last) { + [](Persons* o, option_quintptr id, int first, int last) { if (id.some) { int row = persons_row(o->m_d, id.value); o->beginRemoveRows(o->createIndex(row, 0, id.value), first, last);