ponca icon indicating copy to clipboard operation
ponca copied to clipboard

Extend requirement system to optional properties

Open nmellado opened this issue 1 year ago • 3 comments

Right now the provide/requirement system is based on enum check, which fail if Base::PROVIDE_SOMETHING is not defined. It does not allow to check the existence of a given properties, and compile different pieces of code depending on the existence (or not) of the property:

if (EXISTS(Base::PROVIDE_SOMETHING)) 
   /// do something
else
   /// do something else

Any idea on how to do this ?

nmellado avatar Aug 03 '23 15:08 nmellado

One option could be to have a list of constexpr methods in PrimitiveBase (or something else) for all the capabilities. All default implementations return false. Each extension could hide the default implementation to true. The constexpr method could be used in conditional statements. It could be also used in conflict detection: a class redefining a constexpr method could assert for already existing redefinitions.

nmellado avatar Aug 03 '23 15:08 nmellado

There is one solution to check at compile-time if an enum is defined or not using SFINAE. Here is one example where a macro HAS(FEATURE) is used in static_assert(), but also in if constexpr() : https://godbolt.org/z/TdToeqPov. It avoids the need to keep up to date a list of all capabilities in PrimitiveBase which remains as modular as the current implementation with enums.

By going further, we can define another macro PROVIDES(FEATURE) that declares a new capability FEATURE (and assert that it has not already been declared by another base class) : https://godbolt.org/z/d466e5Mnh. The macro REQUIRES(FEATURE) is just a static_assert that uses HAS(FEATURE) and that can replace code like enum{Check = ...}.

We could also rely on this mechanism to ensure at compile time that only one class fits a primitive, in replacement to the current dynamic version that use isValid() and CONFLICT_ERROR_FOUND. Here is one example that defines new macro FITS(FEATURE) and DOES_FIT(FEATURE) to declare and check that only one class fits a given primitive : https://godbolt.org/z/fxbnrsn9a.

On the other hand, the less flexible solution with the list of all capabilities has its advantages : less unsafe macros, and a global view of what capabilities exist.

ThibaultLejemble avatar Aug 25 '23 09:08 ThibaultLejemble

@ThibaultLejemble I like the idea to use SFINAE. Do you think that you could write a first draft ?

I think we could have a macro to declare and collect the capabilities, that could help for the documentation generation for instance.

nmellado avatar Oct 06 '23 13:10 nmellado