Skip to content

Conversation

@pauldreik
Copy link
Collaborator

@pauldreik pauldreik commented Sep 3, 2024

This adds a span based api in addition to the existing.

The original idea was to use std::span, but instead a templated attempt is used, constrained by concepts. (credit: @WojciechMula )

This makes the user's code pretty nice - it is possible to use std::string, std::string_view, std::vector, std::array, std::span etc . Also user supplied types with .data() and .size() will work.

It is also possible to let users use char/unsigned char/std::byte/std::uint8_t/std::int8_t, all is allowed. This is because C++ allows those types to alias anything. The same story is not true for uint16_t and char16_t.

closes: #557

@lemire
Copy link
Member

lemire commented Oct 1, 2024

@pauldreik There might now be a slight conflict.

@WojciechMula
Copy link
Collaborator

How about adding a template, that would be enabled if the argument has methods size() and data()? Then we may use string_view as well as span (and likely some more containers).

@lemire
Copy link
Member

lemire commented Oct 5, 2024

@WojciechMula

How about adding a template, that would be enabled if the argument has methods size() and data()?

template <typename T>
concept spannable = requires(T v) {
                        { v.size() } -> std::convertible_to<size_t>;
                        { v.data() } -> std::convertible_to<const char*>;;
                      };


template <spannable s>
void f(...) {...}

@pauldreik
Copy link
Collaborator Author

@WojciechMula

How about adding a template, that would be enabled if the argument has methods size() and data()?

template <typename T>
concept spannable = requires(T v) {
                        { v.size() } -> std::convertible_to<size_t>;
                        { v.data() } -> std::convertible_to<const char*>;;
                      };


template <spannable s>
void f(...) {...}

I think this is good - but maybe we can pull it further by checking if it is convertible to span.

@pauldreik pauldreik force-pushed the span branch 4 times, most recently from 1d33ca6 to c90edba Compare December 30, 2024 21:20
@pauldreik pauldreik changed the title add std::span based API #557 add span based API #557 Dec 30, 2024
@pauldreik
Copy link
Collaborator Author

@lemire and @WojciechMula : I have now implemented enough of this to get a feel for how it works. I think it would be useful with an early review.

@lemire
Copy link
Member

lemire commented Jan 1, 2025

I think that this is absolutely fantastic work. It will be fun to document it.

I sort of imagined something of the sort, but what you are doing is so much better... :-)

this is enabled in C++20 onwards, since it uses std::span and concepts
@pauldreik pauldreik marked this pull request as ready for review January 4, 2025 20:26
@lemire lemire requested a review from WojciechMula January 4, 2025 22:25
Copy link
Member

@lemire lemire left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is possibly optimistic as far as system support is concerned. Compilers do not support C++20 entirely and here we need concepts and spans.

I recommend guarding with something like this...

#if SIMDUTF_CPLUSPLUS20
#include <version>
#if __cpp_concepts >= 202002L && __cpp_lib_span >= 202002L
#define SIMDUTF_SPAN 1
#endif // __cpp_concepts >= 202002L && __cpp_lib_span >= 202002L
#endif // SIMDUTF_CPLUSPLUS20

And then everywhere, check that SIMDUTF_SPAN is defined.

@lemire
Copy link
Member

lemire commented Jan 4, 2025

@pauldreik I am marking this PR as 'approved' because my objection can be handled as a separate step.

@pauldreik pauldreik merged commit 8afd3f0 into master Jan 5, 2025
84 checks passed
@pauldreik pauldreik deleted the span branch January 5, 2025 00:11
@pauldreik
Copy link
Collaborator Author

This is possibly optimistic as far as system support is concerned. Compilers do not support C++20 entirely and here we need concepts and spans.

I recommend guarding with something like this...

#if SIMDUTF_CPLUSPLUS20
#include <version>
#if __cpp_concepts >= 202002L && __cpp_lib_span >= 202002L
#define SIMDUTF_SPAN 1
#endif // __cpp_concepts >= 202002L && __cpp_lib_span >= 202002L
#endif // SIMDUTF_CPLUSPLUS20

And then everywhere, check that SIMDUTF_SPAN is defined.

sure. do you have an example of such a system?

@pauldreik pauldreik mentioned this pull request Jan 5, 2025
@lemire
Copy link
Member

lemire commented Jan 5, 2025

@pauldreik I do not have a specific example in mind. That's why I wrote that you may have been optimistic. But, as a rule, I am sure you will agree that it is better to be careful... as the consequence otherwise is a broken build... which is not good.

LLVM 10 will report that it supports C++20. The Node.js runtime builds with LLVM/libc++ 12. Yet C++20 is only partially supported even today...

https://libcxx.llvm.org/Status/Cxx20.html

https://clang.llvm.org/cxx_status.html#cxx20

Thus I recommend we check feature macros. That's what the C++ standard people want us to do anyhow.

(I know you are not arguing with me, I am writing this largely for the people might read this exchange and wonder.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

add std::span support (optional, C++20)

4 participants