ricejasonf / parametric_expressions Goto Github PK
View Code? Open in Web Editor NEWParametric Expressions (P1221)
Home Page: https://ricejasonf.github.io/parametric_expressions/
Parametric Expressions (P1221)
Home Page: https://ricejasonf.github.io/parametric_expressions/
Add some basic description and code blocks to README, something about P1221R0 etc
With operator->
, a parmexpr can be called with the "self" parameter as a pointer which is not well suited for generic code.
If obj->my_parmexpr()
is to be supported, the base of the member expression should probably be implicitly dereferenced.
struct foo {
int storage;
using get(auto self) {
return self.storage;
}
};
struct smart_ptr {
foo* value;
using operator->(auto self) {
return self.value;
}
};
int main() {
int x = foo{42}.get();
smart_ptr s{new foo{42}};
int y = s->get();
}
Note that this is unrelated to operator->
itself.
From Slack by Ben Craig:
this instruction in the macro version looks like a mis-compile though...
movabs rax, 8022916924116329800
#include "ctre.hpp"
#include <string_view>
using match(using auto x, constexpr auto sv) {
static constexpr auto pattern = ctll::basic_fixed_string{ x };
constexpr auto re = ctre::re<pattern>();
return re.match(sv);
}
int main() {
#ifdef MACRO
return match("Hello.*", "Hello World");
#else
using namespace ctre::literals;
return "Hello.*"_ctre.match("Hello World");
#endif
}
main: # @main
sub rsp, 40
movabs rax, 8022916924116329800
mov qword ptr [rsp], rax
mov dword ptr [rsp + 8], 6581362
lea rdi, [rsp + 16]
mov rsi, rsp
call auto ctre::match_re<char const*, ctre::zero_terminated_string_end_iterator, ctre::sequence<ctre::character<(char)72>, ctre::character<(char)101>, ctre::character<(char)108>, ctre::character<(char)108>, ctre::character<(char)111>, ctre::star<ctre::any> > >(char const*, ctre::zero_terminated_string_end_iterator, ctre::sequence<ctre::character<(char)72>, ctre::character<(char)101>, ctre::character<(char)108>, ctre::character<(char)108>, ctre::character<(char)111>, ctre::star<ctre::any> >)
movzx eax, byte ptr [rsp + 32]
add rsp, 40
ret
Static operators are kind of cool, but a few cases such as operator[]
and operator->
are still called with a "self" parameter even when declared static. It's questionable if operator->
should be banned from being declared static
.
struct foo {
int storage;
using operator[](auto self, using auto idx) {
return self.storage;
}
};
struct bar {
static using operator[](auto idx) {
return idx;
}
};
int main() {
int x = foo{42}[0];
int y = bar{}[0];
}
In a dependent context, a parametric expression parameter is somehow being treated as a using
parameter upon instantiation.
template <typename T>
struct foo {
T t;
};
template <typename T>
struct bar {
static using apply(auto fn) {
return foo<decltype(fn)>{fn};
}
};
int main() {
auto x = bar<int>::apply([&](auto x) { });
}
<source>:14:28: error: lambda expression in an unevaluated operand
auto x = bar<int>::apply([&](auto x) { });
^
<source>:14:27: note: in instantiation of parametric expression 'apply' requested here
auto x = bar<int>::apply([&](auto x) { });
^
Generic lambdas are not able to instantiate within a parmexpr under any circumstance.
As reported on slack by Barry Revzin: https://godbolt.org/z/iYm5a6
using compose(using auto f, using auto g) {
return [=](auto x){ return f(g(x)); };
}
int dbl(int i) { return i*2; }
int next(int i) { return ++i; }
auto z = compose(dbl, next)(1);
It compiles if the lambda parameter specifies a type like int
.
Currently the compiler eagerly fails if a dependent expression tries to expand a parameter pack if it can't detect an unexpanded pack.
Is it going too far to defer this check for dependent expressions?
template <auto ...i>
struct iota_
{
static using apply() {
return i;
}
};
template <auto N>
struct test {
void run() {
(iota_<N>::apply(), ...);
}
};
<source>:12:29: error: pack expansion does not contain any unexpanded parameter packs
(iota_<N>::apply(), ...);
~~~~~~~~~~~~~~~~~ ^
Apparently all function calls are broken when the arguments have a "resolved pack". This will have to be fixed with operators like subscript as well.
This is probably because Clang relies on "type dependence" and never checks "contains unexpanded pack" independently.
#include <utility>
#include <array>
template <typename>
struct int_seq_;
template <typename T, T ...i>
struct int_seq_<std::integer_sequence<T, i...>> {
static using apply() {
return i;
}
};
using int_seq(using auto i) {
return int_seq_<std::make_index_sequence<i>>::apply();
}
int main() {
{
int sum = (int_seq(5) + ...);
}
{
std::array<int, 5> xs = {1, 2, 3, 4, 5};
int sum = (xs[int_seq(5)] + ...);
}
{
int xs[] = {1, 2, 3, 4, 5};
int sum = (xs[int_seq(5)] + ...);
}
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.