Skip to content

Passing chaiscript::ChaiScript reference to add_class for enumerations #601

@AdrienTD

Description

@AdrienTD
  • Compiler Used: MSVC 2019
  • Operating System: Windows 10
  • Architecture (ARM/x86/32bit/64bit/etc): x86 32-bit

I want to add an enum class to ChaiScript, for this I use chaiscript::utility::add_class.

My first attempt is to simply pass a reference to the chaiscript::ChaiScript class instance as the first argument, like this:

chaiscript::ChaiScript chai;
chaiscript::utility::add_class<MyEnumClass>(chai, "MyEnumClass", {
	{MyEnumClass::Apple, "MyEnumClass_Apple"},
	{MyEnumClass::Banana, "MyEnumClass_Banana"},
	{MyEnumClass::Pear, "MyEnumClass_Pear"}});

However, in the latest version 6.1, this results to a compile error:
image_2022-09-12_001505024
Indeed, if we take a look inside add_class:

template<typename EnumClass, typename ModuleType>
typename std::enable_if<std::is_enum<EnumClass>::value, void>::type
add_class(ModuleType &t_module, const std::string &t_class_name, const std::vector<std::pair<EnumClass, std::string>> &t_constants) {
t_module.add(chaiscript::user_type<EnumClass>(), t_class_name);
t_module.add(chaiscript::constructor<EnumClass()>(), t_class_name);
t_module.add(chaiscript::constructor<EnumClass(const EnumClass &)>(), t_class_name);
using namespace chaiscript::bootstrap::operators;
equal<EnumClass>(t_module);
not_equal<EnumClass>(t_module);
assign<EnumClass>(t_module);
for (const auto &constant : t_constants) {
t_module.add_global_const(chaiscript::const_var(EnumClass(constant.first)), constant.second);
}
}

This is because when calling equal, not_equal and assign methods from the namespace chaiscript::bootstrap::operators, the first argument t_module is required to be of type Module, since the first argument of equal etc. is of type Module&:
template<typename T>
void equal(Module &m) {
m.add(chaiscript::fun([](const T &lhs, const T &rhs) { return lhs == rhs; }), "==");
}

I know that one solution is to create a Module instance, use add_class on the Module instance, and then add the Module instance to the ChaiScript instance. However this feels like additional steps that don't seem to be necessary, especially when the add_class variant for non enum types works with the first argument being a ChaiScript reference fine. Since there is a template argument for the first argument, I do feel that there was intention to make it work with a ChaiScript reference, and maybe other types, though as for enum classes it only works with Module.
I think a good fix would be to give to all functions in chaiscript::bootstrap::operators a second template argument for the first parameter, so they can accept any other type than Module, like this:

  template<typename T, typename M>
  void equal(M &m) {
    m.add(chaiscript::fun([](const T &lhs, const T &rhs) { return lhs == rhs; }), "==");
  }

So when giving M=chaiscript::ChaiScript it should still work as it has the add method, and it will also make add_class work with ChaiScript as first parameter type at the same time. There might be other solutions I don't know, but I think it would be nice if I could just add enums directly to the ChaiScript without having to pass through a Module.

PS: Btw great project! Integrating it to my program was surprisingly very fast, but it does lack a lot of documentation and hasn't been updated very much...

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions