When developers are evaluating CopperSpice the subject of the Verdigris project is sometimes mentioned. So let’s talk about what Verdigris is, what it does, and what it can not do.
In a nutshell, Verdigris is a third party system that allows you to write macros in your C++ header files which are preprocessed at compile time. These macros are used by the compiler to generate a
moc table which is compatible with Qt. That is all Verdigris can do.
There is nothing in the Verdigris library that implements Signal / Slot delivery. It does not implement reflection any more than
moc does. All of the functionality to handle Signals and Slots resides in the Qt framework and can not be changed or overridden by any front end library.
The output that
moc or Verdigris create consists of mostly string tables and is used at run time. Look ups and comparisons are done to implement reflection and recover Signal / Slot data types which are lost at compile time.
Verdigris makes heavy use of templates in its design. If you are interested in template meta programming then it might be worth looking at to understand the implementation. As per their documentation, Verdigris was inspired by CopperSpice.
CopperSpice is a set of libraries derived from the Qt framework. A major goal has been redesigning the internals to remove undefined behavior and align the code with current coding practices, especially in the Core library. One particular area we wanted to renovate was the Signal / Slot delivery system. Our implementation is type safe, which is a significant and notable improvement.
Our implementation preserves the data types through the entire Signal / Slot process. We did this by moving the heavy lifting of argument handling into the core C++ language. The design we use lets the compiler do what it is good at, which is processing data types.
The old design, which Qt still uses, erases all information about argument data types by using
void** as the data type for every signal and slot parameter. This approach requires extensive use of a
reinterpret_cast at runtime, when it is too late for proper type checking. There is no way to check or test if this type conversion is invalid so relying on a
reinterpret_cast is dangerous. CopperSpice uses a different approach to avoid these potential bugs.
We use templates to preserve the data types of all signal parameters and accurately compare them with the arguments the slot is expecting. Doing this at compile time is the right solution so type mismatches can be reported to the developer. CopperSpice is based on standard C++ and can support every data type automatically. There is no need to add any special handling for typedefs or compound types in CopperSpice.
Both CopperSpice and the Verdigris library allow the creation of a templated class which inherits from QObject. There are however some limitations in the way a template can be declared in Verdigris. CopperSpice does not have these limitations.
CopperSpice does not need
moc or the tables that it generates, everything required for reflection is built into our Core library. Verdigris solves the build problems but it still needs to generate the tables Qt requires. CopperSpice, unlike Verdigris, is able to resolve the issues inherent with using generated string tables. This give CopperSpice the advantage and means our library can correct the way Signals and Slots are processed at runtime.