You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
- Introspect a (user defined) class/struct/type, modify objects at run time without dealing with its type at "Compile Time".
5
-
-**Static Library**, core design is to maintain several tables of function/variable pointers, collected at compile time and providing a mechanism to access them in complete absence of their types at run time.
6
-
## Exclusive Features,
7
-
- Pure **Builder Pattern** for manual registration of types, super-easy to understand, No use of any "Mysterious MACROS" at all.</br>Thats Right- **NO MACROS!!**
8
-
- No need to add any bit of a code to any class/struct/type (to be reflected) declaration or to its implementation.</br>Yes, **No Code Littering, Keep it clean!**
9
-
- Manage all the manual registration of any required type in one single implementation unit, away from rest of the code in project.</br>Or in a **Class with Single Responsibility!**
10
-
- Create an Object of **"CxxMirror"**, pass all type information to reflect as constructor parameter and you're good to GO!
2
+
3
+
The **Reflection Template Library for C++** enables introspection of user-defined types, allowing modification of objects at runtime without needing to know their actual types at compile time.
4
+
5
+
Static library, the core design maintains several tables of function pointers(registered by the user) wrapped in lambdas and providing a mechanism to access at runtime.
6
+
7
+
## Key Features
8
+
9
+
-**Builder Pattern**: Manual registration of types is simple and intuitive, with no mysterious macros involved.
10
+
-**Clean Code**: No reflection-related code needs to be added to class, struct, or function declarations or implementations— keeping your codebase clean and free of clutter.
11
+
-**Centralized Registration**: Manage all manual registrations in a single implementation unit, separate from the rest of your project code.
12
+
-**Simple Integration**: Just create an instance of `CxxMirror`, pass all type information to reflect as a constructor parameter, and you’re done!
11
13
```c++
12
-
constrtl::CxxMirror myReflection({/*.. Pass all type information ..*/});
14
+
rtl::CxxMirror cxxReflection({/*.. Pass all type information ..*/});
13
15
```
14
-
- Wrap that powerful object in a singleton and use C++ Reflection with similar features as in Java or C#.
15
-
- *To generate this boilerplate code automatically, can be used **clang-reflect**
16
-
https://github.com/neeraj31285/clang-reflect
17
-
which is under development right now. Once completed, this boilerplate code can be generated automatically for any large projects.*
16
+
The *cxxReflection* object provides interface to query and instantiate registered types.
17
+
- **Thread-Safe & Exception-Safe**: The library is designed to be thread-safe and exception-safe, providing error codes on possible failures to ensure robust operation.
18
+
- **Automatic Code Generation**: To generate manual registration code automatically, `clang-reflect` can be used. It is a work-in-progress tool available here: *https://github.com/ReflectCxx/clang-reflect*. This tool will generate registration code for any large project without requiring changes to your project’s code.
18
19
19
20
## How To build (Windows/Linux),
20
21
@@ -30,129 +31,132 @@ to build, any IDE applicable to the generator can be used or you can also just b
30
31
```sh
31
32
cmake --build .
32
33
```
33
-
Run **CxxReflectionTests** binary, generated in ../bin folder. *(currently tested on windows and Ubuntu-20 only)*
34
+
Run **CxxReflectionTests** binary, generated in ../bin folder. *(tested on windows and Ubuntu-20)*
34
35
## How To Use,
35
-
- Class to reflect - **Person.h***(Independent of any code related to reflection)*
36
+
In this example, we'll reflect a simple Person class. `Person.h`,
36
37
```c++
37
-
#pragma once
38
-
#include<string>
39
-
40
-
classPerson
41
-
{
38
+
classPerson {
42
39
int age;
43
40
std::string name;
41
+
44
42
public:
45
-
Person():name("NULLSTR"), age(-1) {}
46
-
Person(std::string pName, int pAge) : name(pName), age(pAge) {}
43
+
Person();
44
+
Person(std::string, int);
47
45
48
-
int getAge() { return age; }
49
-
void setAge(int pAge) { age = pAge; }
50
-
std::string getName() { return name; }
51
-
void setName(std::string pName) { name = pName; }
46
+
void setAge(int);
47
+
void setName(std::string);
48
+
49
+
int getAge() const;
50
+
std::string getName() const;
52
51
};
53
52
```
54
-
- Do manual registration while creating **CxxMirror** object. *(..somwhere in some far far away .cpp file..)*
53
+
### Step 1: Register the Class with 'CxxMirror'
54
+
Manually register the class and its members when creating a **`CxxMirror`** object.
55
55
```c++
56
-
57
-
#include"CxxMirrorBuilder.h"//Provides interface to RTL
string name = getName(personObj1).invoke<string>();
123
-
cout << "Person : { name : " << name << ", age: " << age << " }"; //Outs- Person : { name : NULLSTR, age: -1 }
124
-
```
125
-
No need to specify RETURN_TYPE if its void,
126
-
```c++
127
-
setAge(personObj1).invoke(23);
128
-
setName(personObj1).invoke(string("Scott"));
129
-
age = getAge(personObj1).invoke<int>();
130
-
name = getName(personObj1).invoke<string>();
131
-
cout << "Person : { name : " << name << ", age: " << age << " }"; //Outs- Person : { name : Scott, age: 23 }
132
-
```
133
-
Create instance using overloaded constructor *(the one registered as **ctorArgs<string, int>**)*,
106
+
-`RStatus` provides an error code `(rtl::Error)` that indicates the success or failure of the reflection call, and it also contains the return value (if any) wrapped in `std::any`.
107
+
-`Instance` holds the created object (with its type erased), managed on the heap using `std::shared_ptr`.
134
108
```c++
135
-
auto personObj2 = classPerson.instance(string("John Doe"), 37);
136
-
age = getAge(personObj2).invoke<int>();
137
-
name = getName(personObj2).invoke<string>();
138
-
cout << "Person : { name : " << name << ", age: " << age << " }"; //Outs- Person : { name : John Doe, age: 37 }
109
+
110
+
/* Create an instance via reflection using a parameterized constructor.
111
+
Argument types/order must match else call will fail, returning error-code in 'status'.
- `std::any_cast` will throw an exception if correct type is not specified.
135
+
- Check, `CxxTypeRegistration/src/MyReflection.cpp` for all sort of type registrations.
136
+
- Check, `CxxReflectionTests/src` for test cases.
137
+
138
+
## Reflection Features
139
+
- ✅ Register and invoke functions, supporting all overloads.
140
+
- ✅ Register classes/structs and reflect their methods, constructors, and destructors.
141
+
- ✅ Invoke the default constructor.
142
+
- ✅ Invoke the copy constructor with a non-const reference argument.
143
+
- ✅ Invoke the copy constructor with a const reference argument.
144
+
- ✅ Invoke any overloaded constructor.
145
+
- ✅ Invoke non-const member functions.
146
+
- ✅ Invoke const member functions.
147
+
- ✅ Invoke static member functions.
148
+
- ✅ Automatically invokes destructor for objects created on the heap via reflection.
149
+
- ❌ Reflect properties of classes/structs, providing getter/setter methods.
150
+
- ❌ Invoke functions with perfect forwarding.
151
+
- ❌ Reflect enums.
152
+
- ❌ Reflect classes with composite types that are also reflected.
153
+
- ❌ Support single, multiple, multilevel, and virtual inheritance.
154
+
155
+
## License
156
+
This project is licensed under the MIT License. See the LICENSE file for more details.
157
+
158
+
## Contributions
159
+
Contributions are welcome! If you find a bug, have a feature request, or want to contribute to the project, feel free to open an issue or submit a pull request on GitHub.
160
+
161
+
## Contact
162
+
For any questions, suggestions, or feedback, you can reach out via GitHub or email at `neeraj.singh31285@outlook.com`.
0 commit comments