1 | /* Just some code meant to be snipets on |
2 | * http://woboq.com/blog/reflection-in-cpp-and-qt-moc.html */ |
3 | |
4 | #include <QtCore/QObject> |
5 | |
6 | #if 0 |
7 | class MyObject : public QObject { |
8 | Q_OBJECT |
9 | public [[qt::slot]]: |
10 | void fooBar(); |
11 | void otherSlot(int); |
12 | public [[qt::signal]]: |
13 | void mySignal(int param); |
14 | public: |
15 | enum [[qt::enum]] Foobar { Value1, Value2 }; |
16 | }; |
17 | #endif |
18 | |
19 | /*************************************************************************************************/ |
20 | |
21 | #undef Q_PROPERTY |
22 | |
23 | template<typename... Fs> struct QPropertyHolder { template<Fs... Types> struct Property {}; }; |
24 | template<typename... Fs> QPropertyHolder<Fs...> qPropertyGenerator(Fs...); |
25 | |
26 | #define WRITE , &ThisType:: |
27 | #define READ , &ThisType:: |
28 | #define NOTIFY , &ThisType:: |
29 | #define MEMBER , &ThisType:: |
30 | |
31 | #define Q_PROPERTY(A) Q_PROPERTY_IMPL(A) /* expands the WRITE and READ macro */ |
32 | |
33 | #define Q_PROPERTY_IMPL(Prop, ...) static void qt_property_ ## __COUNTER__(\ |
34 | Prop, decltype(qPropertyGenerator(__VA_ARGS__))::Property<__VA_ARGS__>) = delete; |
35 | |
36 | class MyPropObject : public QObject { |
37 | Q_OBJECT |
38 | typedef MyPropObject ThisType; // FIXME: how do do that automatically |
39 | // from within the Q_OBJECT macro? |
40 | |
41 | signals: // would expand to public [[qt::signal]]: |
42 | void fooChanged(); |
43 | public: |
44 | QString foo() const; |
45 | void setFoo(const QString&); |
46 | |
47 | Q_PROPERTY(QString foo READ foo WRITE setFoo NOTIFY fooChanged) |
48 | |
49 | }; |
50 | |
51 | /*************************************************************************************************/ |
52 | |
53 | struct Obj { void func(); }; |
54 | template<void (Obj::*)()> struct Trait {}; |
55 | int main() { |
56 | Trait<&Obj::func> t1; //Ok. The function is directly written |
57 | |
58 | constexpr auto var = &Obj::func; |
59 | Trait<var> t2; //Error: var is not a function directly written. |
60 | } |
61 | |
62 | /*************************************************************************************************/ |
63 | |
64 | using namespace std; |
65 | |
66 | /* Given a simple class */ |
67 | class SomeClass { |
68 | public: |
69 | int foo(); |
70 | void bar(int x); |
71 | }; |
72 | |
73 | #if 0 |
74 | /* The new typename<>... and typedef<>... 'operators' : */ |
75 | vector<string> names = { typename<SomeClass>... } ; |
76 | auto members = std::make_tuple(typedef<SomeClass>...) ; |
77 | #else |
78 | /* Would be expanded to something equivalent to: */ |
79 | vector<string> names = { "SomeClass" , "foo" , "bar" }; |
80 | auto members = std::make_tuple(static_cast<SomeClass*>(nullptr), |
81 | &SomeClass::foo, &SomeClass::bar); |
82 | #endif |
83 | |
84 | /*************************************************************************************************/ |
85 | |
86 | #if 0 |
87 | int signalId=0; |
88 | /* Somehow loop over all the signals to implement them (made up syntax) */ |
89 | for(auto signal : {typedef<MyObject requires has_attribute("qt::signal" )>... }) { |
90 | signalId++; |
91 | signal(auto... arguments) = { |
92 | SignalImplementation<decltype(signal), signalId>::impl(this, arguments...); |
93 | } |
94 | } |
95 | #endif |
96 | |