(UFCS backgrounder: https://isocpp.org/files/papers/N4174.pdf )
I have two functions that tell me if a string contains the
characters of a particular integer. They're called
hasInt and intIn. (
intIn is inspired by the python keyword in.)They looks like this:
bool hasInt(const string s, int n)// does s have n?
{
return s.contains(tostring(n));
}
bool intIn(int n, const string s)// is n in s?
{
return s.contains(tostring(n));
}
It would be convenient if I could add
hasInt as a member function to std::string:bool string::hasInt(int n)
{
return ::hasInt(this, n);
}
Then I could use "member syntax" to call the function, like `text.hasInt(123)`.
Of course, that's not possible, because then I'd be changing the header files
in the standard libraries.
Here's an idea for a new language feature:
let's use the `override` keyword to allow us to "inject" member functions
into an existing class, without modifying the class definition. So the code:
override bool string::hasInt(int n)
{
return ::hasInt(this, n);
}
will (in effect) add
hasInt as a member function to string. Thus, this "override member function" feature has a syntax like:
ReturnType ClassName::function(args){...etc...}
HOWEVER..... what if ClassName doesn't necessarily need to be a class, and could be
other types? Then you open the door to override members like:
override bool int::intIn(const string s)
{
return ::intIn(this, s);
}
Which allows code like `(123).intIn(text)`.
This is halfway to UFCS!
Using some macro magic and helper templates, we could define a
MAKE_UFCS macro to convert a non-member function into a member function:
#define MAKE_UFCS(f) \
override \
retType(f) argType1(f)::f(argType2(f) x)\
{ \
return f(this, x); \
}
Thus the non-member functions
hasInt and intIn could be "opted in" to UFCSby the macro calls:
MAKEUFCS(hasInt);
MAKEUFCS(intIn);
Or maybe, if this override-to-UFCS is useful enough, the override feature can be
applied to a collection of functions at once, like:
override hasInt, intIn;
or
override {
#include <cstdlib>
}
To UFCS-ify an entire header file at the same time.
EDIT: this idea would be similar to Scala's "Extension Methods": https://docs.scala-lang.org/scala3/book/ca-extension-methods.html
or C#'s "Extension Members": https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/extension-methods
https://redd.it/1qyikcg
@r_cpp