BLI: improve implicit conversions of spans
Some conversions that should work did not work before. For example, `MutableSpan<int *> -> MutableSpan<const int *>`.
This commit is contained in:
@@ -132,12 +132,11 @@ template<typename T> class Span {
|
||||
}
|
||||
|
||||
/**
|
||||
* Support implicit conversions like the ones below:
|
||||
* Support implicit conversions like the one below:
|
||||
* Span<T *> -> Span<const T *>
|
||||
*/
|
||||
|
||||
template<typename U, typename std::enable_if_t<is_span_convertible_pointer_v<U, T>> * = nullptr>
|
||||
constexpr Span(Span<U> array) : data_(static_cast<const T *>(array.data())), size_(array.size())
|
||||
constexpr Span(Span<U> span) : data_(static_cast<const T *>(span.data())), size_(span.size())
|
||||
{
|
||||
}
|
||||
|
||||
@@ -467,11 +466,27 @@ template<typename T> class MutableSpan {
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Support implicit conversions like the one below:
|
||||
* MutableSpan<T *> -> MutableSpan<const T *>
|
||||
*/
|
||||
template<typename U, typename std::enable_if_t<is_span_convertible_pointer_v<U, T>> * = nullptr>
|
||||
constexpr MutableSpan(MutableSpan<U> span)
|
||||
: data_(static_cast<T *>(span.data())), size_(span.size())
|
||||
{
|
||||
}
|
||||
|
||||
constexpr operator Span<T>() const
|
||||
{
|
||||
return Span<T>(data_, size_);
|
||||
}
|
||||
|
||||
template<typename U, typename std::enable_if_t<is_span_convertible_pointer_v<T, U>> * = nullptr>
|
||||
constexpr operator Span<U>() const
|
||||
{
|
||||
return Span<U>(static_cast<const U *>(data_), size_);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of elements in the array.
|
||||
*/
|
||||
@@ -653,12 +668,13 @@ template<typename T> class MutableSpan {
|
||||
|
||||
/**
|
||||
* Returns a new span to the same underlying memory buffer. No conversions are done.
|
||||
* The caller is responsible for making sure that the type cast is valid.
|
||||
*/
|
||||
template<typename NewT> constexpr MutableSpan<NewT> cast() const
|
||||
{
|
||||
BLI_assert((size_ * sizeof(T)) % sizeof(NewT) == 0);
|
||||
int64_t new_size = size_ * sizeof(T) / sizeof(NewT);
|
||||
return MutableSpan<NewT>(reinterpret_cast<NewT *>(data_), new_size);
|
||||
return MutableSpan<NewT>((NewT *)data_, new_size);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -392,4 +392,16 @@ TEST(span, Constexpr)
|
||||
EXPECT_EQ(span.slice(1, 2).size(), 2);
|
||||
}
|
||||
|
||||
TEST(span, ImplicitConversions)
|
||||
{
|
||||
BLI_STATIC_ASSERT((std::is_convertible_v<MutableSpan<int>, Span<int>>), "");
|
||||
BLI_STATIC_ASSERT((std::is_convertible_v<Span<int *>, Span<const int *>>), "");
|
||||
BLI_STATIC_ASSERT((std::is_convertible_v<MutableSpan<int *>, Span<int *>>), "");
|
||||
BLI_STATIC_ASSERT((std::is_convertible_v<MutableSpan<int *>, Span<const int *>>), "");
|
||||
BLI_STATIC_ASSERT((std::is_convertible_v<MutableSpan<int *>, MutableSpan<const int *>>), "");
|
||||
BLI_STATIC_ASSERT((!std::is_convertible_v<MutableSpan<const int *>, MutableSpan<int *>>), "");
|
||||
BLI_STATIC_ASSERT((!std::is_convertible_v<Span<const int *>, Span<int *>>), "");
|
||||
BLI_STATIC_ASSERT((!std::is_convertible_v<Span<int *>, MutableSpan<const int *>>), "");
|
||||
}
|
||||
|
||||
} // namespace blender::tests
|
||||
|
||||
Reference in New Issue
Block a user