FCF_SPECIFIER_REGISTRATION_FORCE
(TYPE a_type, TYPE a_specifier)
Package: fcfBasis
File: macro.hpp
Available from version: 1.0.1
Forces registration of a specifier implementation for a type, ensuring it is added to the global registry regardless of the implementation macro state.
This macro is used to explicitly bind a specifier (such as fcf::LessSpecifier, fcf::AddSpecifier, etc.) to a type that has already been registered via FCF_TYPE_REGISTRATION.
Unlike the standard FCF_SPECIFIER_REGISTRATION macro, FCF_SPECIFIER_REGISTRATION_FORCE performs the registration unconditionally. It does not depend on whether the FCF_BASIS_IMPLEMENTATION macro is defined.
This is particularly useful in complex build systems or when the specifier implementation is located in a translation unit where the implementation macro is not present, but you still need the runtime registry to be populated.
When you use this macro, the framework:
- Retrieves the fcf::TypeInfo for the specified type.
- Finds the specialized implementation of the specifier (usually defined via a fcf::Type template specialization).
- Stores a pointer to the universal call function and specialized call function in the type's specifier map.
Arguments
TYPE a_type
- The C++ type to which the specifier will be bound.
TYPE a_specifier
- The specifier type (e.g., fcf::LessSpecifier) that you are registering for this type.
Example: Forced specifier registration
#include <iostream>
#include <string>
// Note: We are NOT defining FCF_BASIS_IMPLEMENTATION here.
// This simulates a scenario where the macro is missing in this translation unit.
#include <fcfBasis/basis.hpp>
// 1. Define a custom structure for demonstration
struct Person {
int age;
std::string name;
};
// 2. Register the type in the fcf system.
// This is mandatory for the type to exist in the registry.
FCF_TYPE_REGISTRATION(Person, "Person", 0);
// 3. Implement the comparison logic (LessSpecifier)
// Even though FCF_BASIS_IMPLEMENTATION is not defined in this file,
// the specialization below is still visible to the compiler.
namespace fcf {
template<> struct Type<Person, LessSpecifier> : public TypeImpl<Person, LessSpecifier> {
inline bool operator()(const Person* a_left, const Person* a_right) {
return a_left->age < a_right->age;
}
};
}
// 4. Bind the specifier to the type using the FORCE macro.
// Because we use FCF_SPECIFIER_REGISTRATION_FORCE, the registration
// will happen even though FCF_BASIS_IMPLEMENTATION is not defined in this file.
FCF_SPECIFIER_REGISTRATION_FORCE(Person, fcf::LessSpecifier);
int main() {
// 5. Create instances of the type
Person p1{25, "Alice"};
Person p2{30, "Bob"};
// 6. Wrap the objects in fcf::Variant
fcf::Variant v1(p1);
fcf::Variant v2(p2);
// 7. Perform comparison using the standard '<' operator.
// This works because the specifier was successfully registered.
if (v1 < v2) {
std::cout << "Alice is younger than Bob" << std::endl;
} else {
std::cout << "Alice is not younger than Bob" << std::endl;
}
return 0;
}
impl.cpp file:
// Define an implementation macro to include the implementation section in header files.
#define FCF_BASIS_IMPLEMENTATION
#include <fcfBasis/basis.hpp>
CMakeLists.txt file:
add_executable(app main.cpp impl.cpp)
target_include_directories(app PRIVATE ../../..)
Output:
Alice is younger than Bob