| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Sorry, something went wrong.
|
Ah... the change works in if statements but it is not working yet with inspect - the patch to cppfront is needed not to perceive the syntax as an error. |
Sorry, something went wrong.
|
On the last push I have added support for using id-expression ( expression-list ) as alternative in the inspect expression. |
Sorry, something went wrong.
|
I have noticed that my other PRs regarding using is() with multiple types/templates interfere with this PR and I need to update it. Currently, I am not able to allow generic lambda use as I don't know how to write requires clause for lambda_wrapper that will match them. Now it matches types that matches: template <typename F, typename Capture = std::monostate>
requires (
requires { &F::operator(); }
)
struct lambda_wrapper;What is currently possible is visible here: #include <utility>
#include <tuple>
#include <iostream>
#include <vector>
#include <span>
constexpr auto less_then = [](int value) {
return cpp2::lambda_wrapper([](int x, int capture) { return x < capture;}, value);
};
constexpr auto in = [](auto min, auto max) {
return cpp2::lambda_wrapper([](int x, std::pair<int,int> capture) {
return std::get<0>(capture) <= x && x <= std::get<1>(capture);
}, std::pair(min,max));
};
constexpr auto empty = cpp2::lambda_wrapper([](std::span<const int> x){
return std::empty(x);
});
main: () -> int = {
i := 15;
if i is less_then(20) {
std::cout << "less than 20" << std::endl;
}
if i is in(10,30) {
std::cout << "i is between 10 and 30" << std::endl;
}
std::cout << inspect i -> std::string {
is less_then(10) = "i less than 10";
is in(11,20) = "i is between 11 and 20";
is _ = "i is out of our interest";
} << std::endl;
v : std::vector<int> = ();
if v is empty {
std::cout << "v is empty" << std::endl;
}
}The feature is less generic but still useful. |
Sorry, something went wrong.
|
Rebase to main. Make is() function constexpr |
Sorry, something went wrong.
|
Might require #86 for some use cases. |
Sorry, something went wrong.
|
It could be merged. I was not sure if you would be willing to merge all functionalities. |
Sorry, something went wrong.
Can you give an example of what doesn't work? |
Sorry, something went wrong.
|
The goal was to have each functionality separate. |
Sorry, something went wrong.
|
NP - if they don't conflict I'll plan to look at them individually for now. Thx! |
Sorry, something went wrong.
|
@JohelEGP labda_wrapper requires requires { &F::operator(); }It means that the below code will work in the is statement: constexpr auto in = [](auto min, auto max) {
return cpp2::lambda_wrapper([](int x, std::pair<int,int> capture) { // <--- explicit type int
return std::get<0>(capture) <= x && x <= std::get<1>(capture);
}, std::pair(min,max));
};But this will not: constexpr auto in = [](auto min, auto max) {
return cpp2::lambda_wrapper([](auto x, auto capture) { // <--- generic lambda
return std::get<0>(capture) <= x && x <= std::get<1>(capture);
}, std::pair(min,max));
}; |
Sorry, something went wrong.
|
You could move the constraint to the point where you actually have the argument type X with which to call F. Then you could use std::invocable<lambda_wrapper<F, Capture>, X> if the call operator of lambda_wrapper and F are likewise appropriately constrained: https://compiler-explorer.com/z/s3cbfccnh. |
Sorry, something went wrong.
|
I will test that direction. Unfortunately, std::tuple cannot be used. As I described in the PR description:
|
Sorry, something went wrong.
|
Thanks! Implemented as a separate commit along the lines discussed in #79. |
Sorry, something went wrong.
|
@hsutter, your change enables using lambda in inspect expressions but not in if statements. My solution worked for both cases ;) #include <iostream>
#include <vector>
constexpr auto less_then = [](int value) {
return [=](auto x) { return x < value;};
};
constexpr auto in = [](auto min, auto max) {
return [=](auto x) {
return min <= x && x <= max;
};
};
constexpr auto empty = [](auto&& x){
return std::empty(x);
};
main: () -> int = {
i := 15;
std::cout << inspect i -> std::string {
is (less_then(10)) = "i less than 10"; // works
is (in(11,20)) = "i is between 11 and 20"; // works
is _ = "i is out of our interest";
} << std::endl;
if i is (less_then(20)) { // not working
std::cout << "less than 20" << std::endl;
}
if i is (in(10,30)) { // not working
std::cout << "i is between 10 and 30" << std::endl;
}
v : std::vector<int> = ();
if empty(v) { // works
std::cout << "v is empty" << std::endl;
}
if v is (empty) { // not working
std::cout << "v is empty" << std::endl;
}
} |
Sorry, something went wrong.
|
Ah, you noticed that. :) That was next on my to-do list, and I just checked it in... the above code now works with commit 327ceeb . |
Sorry, something went wrong.
| Back | FazBrowse Home | New Git URL |
In https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2392r0.pdf there is an example that uses lambda with is keyword.
cout << inspect i -> std::string { is in(1,2) = "1 or 2"; is in(2,3) = "3"; is _ = "something else"; };or
I started to experiment with current implementation to achieve the same functionality and I came up with implementation that you can check here: https://godbolt.org/z/464PP7bW6 (working prototype).
Unfortunately lambda with the capture list cannot be argument of the template (only gcc supports that). So, I have created a wrapper that stores a lambda and the arguments that normally will go to the capture list.
lambda_wrapper shall use std::tuple to store arguments that shall go to capture list but std::tuple is not structural type and cannot be used in that context. There are possible workarounds (https://stackoverflow.com/questions/69194075/structural-tuple-like-wrapping-a-variadic-set-of-template-parameters-values-in) but I decided to propose something simple.
The current implementation can handle lambda that captures:
If more captured values will be needed we need to add tuple-like structure that will be structural type.
On the last push I have made possible using lambda_wrapper in inspect alternatives (by making id-expression ( expression-list ) an valid alternative syntax.
That makes this code works:
std::cout << inspect i -> std::string { is less_than(10) = "i less than 10"; is in(11,20) = "i is between 11 and 20"; is _ = "i is out of our interest"; } << std::endl;