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

new paper: consider a sub-namespace for non-member functions (or everything as hidden friends) #80

Open
mattkretz opened this issue Jun 16, 2023 · 2 comments
Assignees
Labels
exploration New feature or request to be explored

Comments

@mattkretz
Copy link
Owner

LEWG wanted to see a paper that explores placing all simd non-member functions into a sub-namespace on 2023-06-16, while discussing permute, expand, and compress.

@mattkretz mattkretz added the exploration New feature or request to be explored label Jun 16, 2023
@mattkretz mattkretz self-assigned this Jun 16, 2023
@mattkretz mattkretz moved this to Todo in std::simd in C++26 Jun 16, 2023
@mattkretz mattkretz added this to the P1928R4 (TS merge) milestone Jun 16, 2023
@mattkretz
Copy link
Owner Author

I find it hard to come up with good solutions here.

Some ideas, using permute as the canonical example

std::simd_permute(x, std::simd_permutation_shift<1>)

std::simd<float> x = 1.f;
std::simd_permute(x, std::simd_permutation_shift<1>);

std::SIMD::permute(x, std::SIMD::shift<1>)

  • Don't rename std::simd<T, N>.
  • Don't rename std::simd_mask<T, N>.
  • Rename std::basic_simd<T, Abi> to std::SIMD::basic_simd<T, Abi>.
  • Rename std::basic_simd_mask<T, Abi> to std::SIMD::basic_mask<T, Abi>.
std::simd<float> x = 1.f;
permute(x, std::SIMD::shift<1>);

or

namespace SIMD = std::SIMD;
std::simd<float> x = 1.f;
SIMD::permute(x, SIMD::shift<1>);

std::simd::permute(x, std::simd::shift<1>)

  • Rename std::simd<T, N> to std::simd::simd<T, N>.
  • Rename std::simd_mask<T, N> to std::simd::mask<T, N>.
  • Rename std::basic_simd<T, Abi> to std::simd::basic_simd<T, Abi>.
  • Rename std::basic_simd_mask<T, Abi> to std::simd::basic_mask<T, Abi>.
std::simd::simd<float> x = 1.f;
permute(x, std::simd::shift<1>);

or

namespace simd = std::simd;
simd::simd<float> x = 1.f;
simd::permute(x, simd::shift<1>);

std::simd_operations::permute(x, std::simd_operations::shift<1>)

  • Keep simd, simd_mask, basic_simd, and basic_simd_mask in namespace std.
std::simd<float> x = 1.f;
std::simd_operations::permute(x, std::simd_operations::shift<1>)

or

namespace simd = std::simd_operations;
std::simd<float> x = 1.f;
simd::permute(x, simd::shift<1>);

Hidden friends: permute(x, std::simd_permutations::shift<1>)

  • Move all non-member functions from namespace std into basic_simd/basic_simd_mask as hidden friends.
std::simd<float> x = 1.f;
// ERROR: std::permute(x, std::simd_permutations::shift<1>);
permute(x, std::simd_permutations::shift<1>);

@mattkretz
Copy link
Owner Author

The use of hidden friends is a problem for generic code. Consider all_of.
Status quo:

void f(auto x) // std::simd<int> or int
{
  if (std::all_of(x > 0))

If all_of is a hidden friend of basic_simd_mask, where does the bool overload go? In namespace std, right? Then:

void f(auto x) // std::simd<int> or int
{
  if constexpr(std::is_arithmetic<decltype(x)>) {
    if (std::all_of(x > 0)) ...
  } else {
    if (all_of(x > 0)) ...

I.e. one must be called unqualified and the other must be called qualified. There's no common way to call either generically. No-go...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
exploration New feature or request to be explored
Projects
Development

No branches or pull requests

1 participant