Giter Site home page Giter Site logo

ricejasonf / parametric_expressions Goto Github PK

View Code? Open in Web Editor NEW
7.0 7.0 0.0 254 KB

Parametric Expressions (P1221)

Home Page: https://ricejasonf.github.io/parametric_expressions/

Makefile 1.01% C++ 10.40% Dockerfile 0.79% CMake 10.32% HTML 76.76% Shell 0.72%

parametric_expressions's People

Contributors

ricejasonf avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

parametric_expressions's Issues

Docs

Add some basic description and code blocks to README, something about P1221R0 etc

Self Parameter Should not be Pointer

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.

https://godbolt.org/z/vQ2V5N

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.

Investigate Suspicious Code Generation

From Slack by Ben Craig:

this instruction in the macro version looks like a mis-compile though...
movabs rax, 8022916924116329800

https://godbolt.org/z/1a7DIB

#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 Operator Weirdness

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.

https://godbolt.org/z/6djjlD

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];
}

Parameter Not Instantiating Properly

In a dependent context, a parametric expression parameter is somehow being treated as a using parameter upon instantiation.

https://godbolt.org/z/ZSegdp

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 Lambda Broken

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.

Returning Dependent Pack Expansions

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?

https://godbolt.org/z/S5lxNj

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(), ...);

         ~~~~~~~~~~~~~~~~~  ^

Resolved Packs Break Function Overload Resolution

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.

https://godbolt.org/z/Qy7lbS

#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)] + ...);
  }
} 

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.