diff --git a/wpiutil/src/main/native/include/wpi/ArrayRef.h b/wpiutil/src/main/native/include/wpi/ArrayRef.h index c94312ebfd..3aa8e4179e 100644 --- a/wpiutil/src/main/native/include/wpi/ArrayRef.h +++ b/wpiutil/src/main/native/include/wpi/ArrayRef.h @@ -14,6 +14,7 @@ #include "wpi/SmallVector.h" #include "wpi/STLExtras.h" #include "wpi/Compiler.h" +#include "wpi/span.h" #include #include #include @@ -24,6 +25,9 @@ #include #include #include +#if __has_include() +#include +#endif namespace wpi { @@ -126,6 +130,24 @@ namespace wpi { std::is_convertible::value>::type* = 0) : Data(Vec.data()), Length(Vec.size()) {} +#ifdef __cpp_lib_span + /// Construct an ArrayRef from std::span + /*implicit*/ ArrayRef(std::span Span) + : Data(Span.data()), Length(Span.size()) {} + + /// Construct an ArrayRef from std::span + /*implicit*/ ArrayRef(std::span Span) + : Data(Span.data()), Length(Span.size()) {} +#endif + + /// Construct an ArrayRef from wpi::span + /*implicit*/ ArrayRef(span Span) + : Data(Span.data()), Length(Span.size()) {} + + /// Construct an ArrayRef from wpi::span + /*implicit*/ ArrayRef(span Span) + : Data(Span.data()), Length(Span.size()) {} + /// @} /// @name Simple Operations /// @{ @@ -268,6 +290,15 @@ namespace wpi { return std::vector(Data, Data+Length); } +#ifdef __cpp_lib_span + operator std::span() const { + return std::span(Data, Length); + } +#endif + + operator span() const { + return span(Data, Length); + } /// @} }; @@ -322,6 +353,14 @@ namespace wpi { template /*implicit*/ constexpr MutableArrayRef(T (&Arr)[N]) : ArrayRef(Arr) {} +#ifdef __cpp_lib_span + /// Construct an ArrayRef from std::span + /*implicit*/ MutableArrayRef(std::span Span) : ArrayRef(Span) {} +#endif + + /// Construct an ArrayRef from wpi::span + /*implicit*/ MutableArrayRef(span Span) : ArrayRef(Span) {} + T *data() const { return const_cast(ArrayRef::data()); } iterator begin() const { return data(); } @@ -414,6 +453,16 @@ namespace wpi { assert(Index < this->size() && "Invalid index!"); return data()[Index]; } + +#ifdef __cpp_lib_span + operator std::span() const { + return std::span(data(), this->size()); + } +#endif + + operator span() const { + return span(data(), this->size()); + } }; /// This is a MutableArrayRef that owns its array. diff --git a/wpiutil/src/main/native/include/wpi/span.h b/wpiutil/src/main/native/include/wpi/span.h index 74aa17ef75..479b98d9d2 100644 --- a/wpiutil/src/main/native/include/wpi/span.h +++ b/wpiutil/src/main/native/include/wpi/span.h @@ -17,6 +17,9 @@ http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/n4820.pdf #include #include #include +#if __has_include() +#include +#endif namespace wpi { @@ -219,6 +222,12 @@ public: : storage_(other.data(), other.size()) {} +#ifdef __cpp_lib_span + constexpr span(std::span other) noexcept + : storage_(other.data(), other.size()) + {} +#endif + ~span() noexcept = default; constexpr span& @@ -327,6 +336,15 @@ public: return reverse_iterator(begin()); } +#ifdef __cpp_lib_span + constexpr operator auto() const { + return std::span < ElementType, + (Extent == dynamic_extent) + ? std::dynamic_extent + : Extent > (storage_.ptr, storage_.size); + } +#endif + private: storage_type storage_{}; }; diff --git a/wpiutil/src/test/native/cpp/span/test_conversions.cpp b/wpiutil/src/test/native/cpp/span/test_conversions.cpp new file mode 100644 index 0000000000..7f72b8dc89 --- /dev/null +++ b/wpiutil/src/test/native/cpp/span/test_conversions.cpp @@ -0,0 +1,74 @@ +#if __has_include() +#include +#endif +#include "wpi/ArrayRef.h" + +#include "gtest/gtest.h" + +void func1(wpi::span x) {} +#ifdef __cpp_lib_span +void func2(std::span x) {} +#endif +void func3(wpi::ArrayRef x) {} + +void func4(wpi::span x) {} +#ifdef __cpp_lib_span +void func5(std::span x) {} +#endif +void func6(wpi::MutableArrayRef x) {} + +TEST(Span, ConvertArrayRefStdSpan) { + func1(wpi::ArrayRef{}); + func1(wpi::MutableArrayRef{}); + func1(wpi::span{}); + func1(wpi::span{}); +#ifdef __cpp_lib_span + func1(std::span{}); + func1(std::span{}); +#endif + +#ifdef __cpp_lib_span + func2(wpi::ArrayRef{}); + func2(wpi::MutableArrayRef{}); + func2(wpi::span{}); + func2(wpi::span{}); + func2(std::span{}); + func2(std::span{}); +#endif + + func3(wpi::ArrayRef{}); + func3(wpi::MutableArrayRef{}); + func3(wpi::span{}); + func3(wpi::span{}); +#ifdef __cpp_lib_span + func3(std::span{}); + func3(std::span{}); +#endif + + //func4(wpi::ArrayRef{}); + func4(wpi::MutableArrayRef{}); + //func4(wpi::span{}); + func4(wpi::span{}); +#ifdef __cpp_lib_span + //func4(std::span{}); + func4(std::span{}); +#endif + +#ifdef __cpp_lib_span + //func5(wpi::ArrayRef{}); + func5(wpi::MutableArrayRef{}); + //func5(wpi::span{}); + func5(wpi::span{}); + //func5(std::span{}); + func5(std::span{}); +#endif + + //func6(wpi::ArrayRef{}); + func6(wpi::MutableArrayRef{}); + //func6(wpi::span{}); + func6(wpi::span{}); +#ifdef __cpp_lib_span + //func6(std::span{}); + func6(std::span{}); +#endif +}