Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

C++20 support #86

Open
nilssonk opened this issue Sep 15, 2024 · 8 comments
Open

C++20 support #86

nilssonk opened this issue Sep 15, 2024 · 8 comments
Labels
c++20 Support for C++20

Comments

@nilssonk
Copy link

nilssonk commented Sep 15, 2024

Hello there,

I just now saw your impressive presentation from cppnow earlier this year and would like to use this in production at my current company. However the C++23 requirement is a big ask for us seeing as we are still only in the very early evaluation stage for C++20 (which itself may be considered early adoption in much the embedded space). So my question is, what C++23 features are actually required for this to work (modulo replacable stdlib components such as expected and optional)? If there are none, maybe we could collaborate on making a C++20 version?

I naively tried a string replace 23->20 in the CMakeLists.txt, but the build chokes on constexpr usage of std::string_view(data, size) and many many lines of other perhaps unrelated stuff, so I thought I'd ask first before putting in more effort.

Many thanks for sharing the project,
Kim

@Bronek
Copy link
Collaborator

Bronek commented Oct 13, 2024

Hi. The problem with C++20 support is that it does not support #include <expected> which we rely on, as a part of the implementation of fn::expected; however there might be a suitable polyfill and also a similar use case which we would like to support, which is clang with -stdlib=libstdc++. So, I am not saying "no" but am also not promising anything. It is a nontrivial amount of work.

Also, this library needs sorting of types which is currently a poor-man emulation in the form of a constexpr algorithm inside functional/detail/meta.hpp, which only handles named types, and not even very well. Sorting of types is a proposed for C++26 P2830 and once it is available, we will likely remove this poor-man emulation and this library will only support C++26. So, assuming that we actually do add support (again, no promises) for C++20, it will be only temporary for few years, and then removed.

@Bronek Bronek added the enhancement New feature or request label Oct 13, 2024
@atomgalaxy
Copy link
Collaborator

We realistically should support an opt-in adaptor where you can plug in your monad types. That's the path to C++20.

@nilssonk
Copy link
Author

nilssonk commented Oct 15, 2024

I sat down with this for an hour or two and here's what I've done:

  1. Introduced a CPP20_COMPAT option to the project which controls the version of CMAKE_CXX_STANDARD and optionally downloads drop-in libraries.
  2. Added a candidate drop-in for expected in the form of https://github.com/TartanLlama/expected .
  3. Added a candidate drop-in for string_view with support for the constexpr version of the constructor basic_string(char*, size_t) in the form of https://github.com/martinmoene/string-view-lite
  4. Introduced a header with compatibility type aliases for the internal expected and related types (e.g. unexpected, in_place).
  5. Introduced a header with compatibility type aliases for the internal string_view.
  6. Replaced many std:: with detail:: .
  7. Worked around _normalized_name::apply() usage of constexpr std::string::append() by having it return a fixed size array together with a size value.
  8. Replaced usage of std::unreachable with the cppreference.com implementation.
  9. Removed static keywords from constexpr lambdas and various operator()s (this seems unsound).
  10. Replaced std::invoke_r with std::__invoke_r.

However now I'm sort of stuck and I think the issue is that the standard library uses a shared type std::in_place for both optional and expected, while my drop in uses its own tl::in_place, thereby creating a schism. It may be possible to work around this by using another drop-in for std::optional (e.g. https://github.com/TartanLlama/optional) and making sure that their notions of in_place are the same. However this whole porting business is getting more dubious by the minute.

Do you think 9 would be a show stopper and do you foresee any other boobytraps?

@atomgalaxy
Copy link
Collaborator

atomgalaxy commented Oct 15, 2024 via email

@Bronek
Copy link
Collaborator

Bronek commented Oct 16, 2024

Note this library is still in a dynamic development stage, e.g. I plan to move the multi-dispatch implementation away from fn::invoke to fn::dispatch (or perhaps fn::apply) #84 , rename fn::sum to fn::copack #83, improve graded monad support #98 and quite possibly other high-churn changes. This means your work on C++20 compatibility will quickly become obsolete/conflict with the state of the world.

@Bronek
Copy link
Collaborator

Bronek commented Oct 16, 2024

I think the approach which will work well is to make separate changes in this library which, when taken individually, will not make it outright compatible with C++20, but will bring it closer by removing individual barriers.

@Bronek Bronek added the c++20 Support for C++20 label Dec 7, 2024
@Bronek
Copy link
Collaborator

Bronek commented Dec 7, 2024

@nilssonk I will try to accommodate C++20 compilers. Created a new label for issues/PRs related to this work. Feel free to create individual issues, so we make this focused.

As for expected polyfill I am not certain that https://github.com/TartanLlama/expected has a compatible license; I will more likely start from https://github.com/XRPLF/rippled/blob/develop/include/xrpl/basics/Expected.h

The goal is for this project to support a wider range of compilers, so C++20 workarounds which only benefit select compiler(s) at the expense of others will not be accepted. Specifically I want this project to work with:

  • gcc-12 and later
  • clang-16 (including on MacOS) and later
  • Visual Studio 2022 (unsure about specific version yet)
  • Visual Studio 2019 *maybe

@Bronek
Copy link
Collaborator

Bronek commented Dec 20, 2024

I started work on expected polyfill, also raised #144

To accommodate it, I will also make the following refactor:

  1. rename directory include/functional to include/fn; everything there stays in namespace fn but now we have directory name match the namespace
  2. add sibling directory include/fnp ("p" for polyfill) as a separate build target, and put expected.hpp there, in namespace fnp

Do not confuse these two "expecteds":

  • fnp::expected : C++23 std::expected polyfill, compatible with projects built as C++20
  • fn::expected : new functionality specific to this library, added on top of fnp::expected, hopefully will be added to the future C++ standards std:expected

The new fn and fnp directories, namespaces and build targets will hopefully help disambiguate these two.

@Bronek Bronek removed the enhancement New feature or request label Dec 20, 2024
@Bronek Bronek pinned this issue Jan 6, 2025
@Bronek Bronek unpinned this issue Jan 6, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c++20 Support for C++20
Projects
None yet
Development

No branches or pull requests

3 participants