As long as the solution matches "EditLine *" (C struct type from edit line library) to back to the C++ instance of "Editline" (lower case ell in "line" from LLDB). It should be easy to do with a template.
I am fine with any new solution that makes it easier to add new commands. I would rather have a templated function argument over a template argument if possible. I am thinking of something like: createEditLineCommandDescriptor(“Command1", “Command1 help", &Foo::Foo1); createEditLineCommandDescriptor(“Command2", “Command2 help", &Foo::Bar); as I find it more readable. Greg > On Apr 30, 2021, at 9:35 PM, Neal Sidhwaney via lldb-dev > <lldb-dev@lists.llvm.org> wrote: > > Some comments in > https://reviews.llvm.org/rGfd89af6880f33ead708abe2f7d88ecb687d4e0d2 > <https://reviews.llvm.org/rGfd89af6880f33ead708abe2f7d88ecb687d4e0d2> > prompted me to look more into potential simplifications of our EditLine > wrapper and I wanted to run this by anyone who is interested before making > the changes. > > Right now we set a bunch of callbacks in libedit that are captureless lambdas > implicitly converted to C function pointers. The lambdas look up an instance > of our Editline class and invoke member functions. The boilerplate that > could be generated by templates is something like the following: > > class Foo { // Imagine this is our Editline class that wraps libedit > public: > unsigned char Foo1(int ch) { // These are member functions invoked by > lambdas we pass to libedit > return 'a'; > } > unsigned char Bar(int ch) { > return 'b'; > } > unsigned char Baz(int ch) { > return 'c'; > } > }; > > typedef unsigned char (*elFnPtr)(EditLine*, int); // Signature of callbacks > libedit takes (note Edit__L__ine is libedit, and Edit__l__ine is our wrapper) > typedef unsigned char (Foo::*FooMemPtr)(int ch); // Signature of member > functions invoked > > template<FooMemPtr callback, typename Fn = elFnPtr> > tuple<const char*, const char*, Fn> createEditLineCommandDescriptor(const > char* command, const char* helpText) { > return make_tuple(command, helpText, [] (EditLine*, int ch) { > cout << ch; > Foo foo; > ((&foo)->*callback)('a'); > return (unsigned char) ch; > }); > } > > auto editlineCommands = { > createEditLineCommandDescriptor<&Foo::Foo1>(“Command1", “Command1 help"), > createEditLineCommandDescriptor<&Foo::Bar>(“Command2", “Command2 help") > }; > > for (auto editlineCommand : editLineCommands) { > // call into libedit to add editlineCommand, e.g.: > el_set(EL_ADDFN, editlineCommand.get<0>(), editLineCommand.get<1>(), > editLineCommand.get<2>()); > } > > The pointer to member function is a type parameter because otherwise the > compiler complains about the lambda needing to capture it, in which case we > could not pass it to libedit. > > I also plan to look into the wchar_t/char preprocessor logic that the > original comment brought up but then I got distracted by shiny template stuff > ;-) > > Thanks! > > Neal > _______________________________________________ > lldb-dev mailing list > lldb-dev@lists.llvm.org > https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev
_______________________________________________ lldb-dev mailing list lldb-dev@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev