I want to create a boost::any_collection
of entities that satisfies a custom concept of mine:
#include <Command>
template<typename T>
concept ModelConcept = [] {
return requires (T model) {
{ model.setCommand(Command{}) } -> std::same_as<void>;
};
}();
I've tried different timew but with no success:
boost::any_collection<ModelConcept> entities;
template <ModelConcept T>
struct ModelConceptWrapper {
T obj;
};
boost::any_collection<ModelConceptWrapper> entities2;
boost::any_collection<ModelConceptWrapper<>> entities2;
But with no success. I didn't find anything in the documentation that helps me, since it uses the streamable
of type_erasure.
How can I create it?
Like the commenter said, you need a Boost Type-Erasure concept. E.g.:
#include <boost/type_erasure/member.hpp>
namespace mylib {
struct Command {};
BOOST_TYPE_ERASURE_MEMBER(hasSetCommandConcept, setCommand);
}
using hasSetCommand = mylib::hasSetCommandConcept<void(mylib::Command)>;
// #include <Command>
#include <boost/poly_collection/any_collection.hpp>
#include <boost/type_erasure/member.hpp>
#include <iostream>
namespace mylib {
struct Command {};
BOOST_TYPE_ERASURE_MEMBER(hasSetCommandConcept, setCommand);
}
using hasSetCommand = mylib::hasSetCommandConcept<void(mylib::Command)>;
struct Model1 {
void setCommand(mylib::Command) { std::cout << __PRETTY_FUNCTION__ << std::endl; }
};
struct Model2 {
void setCommand(mylib::Command) { std::cout << __PRETTY_FUNCTION__ << std::endl; }
};
int main() {
boost::poly_collection::any_collection<hasSetCommand> collection;
collection.insert(Model1{});
collection.insert(Model2{});
collection.insert(Model1{});
collection.insert(Model1{});
for (mylib::Command command; auto const& obj : collection)
obj.setCommand(command);
}
Printing
void Model2::setCommand(mylib::Command)
void Model1::setCommand(mylib::Command)
void Model1::setCommand(mylib::Command)
void Model1::setCommand(mylib::Command)