BLI: rename ArrayRef to Span
This also renames `MutableArrayRef` to `MutableSpan`. The name "Span" works better, because `std::span` will provide similar functionality in C++20. Furthermore, a shorter, more concise name for a common data structure is nice.
This commit is contained in:
parent
7d2b4ae9c6
commit
f7c0f1b8b8
|
@ -27,11 +27,11 @@
|
|||
#include "DNA_scene_types.h"
|
||||
#include "DNA_simulation_types.h"
|
||||
|
||||
#include "BLI_array_ref.hh"
|
||||
#include "BLI_compiler_compat.h"
|
||||
#include "BLI_float3.hh"
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_span.hh"
|
||||
#include "BLI_string.h"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
|
@ -54,9 +54,9 @@
|
|||
#include "DEG_depsgraph.h"
|
||||
#include "DEG_depsgraph_query.h"
|
||||
|
||||
using blender::ArrayRef;
|
||||
using blender::float3;
|
||||
using blender::MutableArrayRef;
|
||||
using blender::MutableSpan;
|
||||
using blender::Span;
|
||||
|
||||
static void simulation_init_data(ID *id)
|
||||
{
|
||||
|
@ -168,9 +168,9 @@ void *BKE_simulation_add(Main *bmain, const char *name)
|
|||
return simulation;
|
||||
}
|
||||
|
||||
static MutableArrayRef<float3> get_particle_positions(ParticleSimulationState *state)
|
||||
static MutableSpan<float3> get_particle_positions(ParticleSimulationState *state)
|
||||
{
|
||||
return MutableArrayRef<float3>(
|
||||
return MutableSpan<float3>(
|
||||
(float3 *)CustomData_get_layer_named(&state->attributes, CD_LOCATION, "Position"),
|
||||
state->tot_particles);
|
||||
}
|
||||
|
@ -239,7 +239,7 @@ void BKE_simulation_data_update(Depsgraph *depsgraph, Scene *scene, Simulation *
|
|||
CustomData_realloc(&state_orig->attributes, state_orig->tot_particles);
|
||||
ensure_attributes_exist(state_orig);
|
||||
|
||||
MutableArrayRef<float3> positions = get_particle_positions(state_orig);
|
||||
MutableSpan<float3> positions = get_particle_positions(state_orig);
|
||||
for (uint i : positions.index_range()) {
|
||||
positions[i] = {i / 10.0f, 0, 0};
|
||||
}
|
||||
|
@ -250,7 +250,7 @@ void BKE_simulation_data_update(Depsgraph *depsgraph, Scene *scene, Simulation *
|
|||
else if (current_frame == state_orig->current_frame + 1) {
|
||||
state_orig->current_frame = current_frame;
|
||||
ensure_attributes_exist(state_orig);
|
||||
MutableArrayRef<float3> positions = get_particle_positions(state_orig);
|
||||
MutableSpan<float3> positions = get_particle_positions(state_orig);
|
||||
for (float3 &position : positions) {
|
||||
position.z += 0.1f;
|
||||
}
|
||||
|
|
|
@ -39,9 +39,9 @@
|
|||
*/
|
||||
|
||||
#include "BLI_allocator.hh"
|
||||
#include "BLI_array_ref.hh"
|
||||
#include "BLI_index_range.hh"
|
||||
#include "BLI_memory_utils.hh"
|
||||
#include "BLI_span.hh"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
namespace blender {
|
||||
|
@ -90,7 +90,7 @@ class Array {
|
|||
/**
|
||||
* Create a new array that contains copies of all values.
|
||||
*/
|
||||
Array(ArrayRef<T> values)
|
||||
Array(Span<T> values)
|
||||
{
|
||||
m_size = values.size();
|
||||
m_data = this->get_buffer_for_size(values.size());
|
||||
|
@ -100,7 +100,7 @@ class Array {
|
|||
/**
|
||||
* Create a new array that contains copies of all values.
|
||||
*/
|
||||
Array(const std::initializer_list<T> &values) : Array(ArrayRef<T>(values))
|
||||
Array(const std::initializer_list<T> &values) : Array(Span<T>(values))
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -184,22 +184,22 @@ class Array {
|
|||
return *this;
|
||||
}
|
||||
|
||||
operator ArrayRef<T>() const
|
||||
operator Span<T>() const
|
||||
{
|
||||
return ArrayRef<T>(m_data, m_size);
|
||||
return Span<T>(m_data, m_size);
|
||||
}
|
||||
|
||||
operator MutableArrayRef<T>()
|
||||
operator MutableSpan<T>()
|
||||
{
|
||||
return MutableArrayRef<T>(m_data, m_size);
|
||||
return MutableSpan<T>(m_data, m_size);
|
||||
}
|
||||
|
||||
ArrayRef<T> as_ref() const
|
||||
Span<T> as_span() const
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
MutableArrayRef<T> as_mutable_ref()
|
||||
MutableSpan<T> as_mutable_span()
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
@ -243,9 +243,9 @@ class Array {
|
|||
/**
|
||||
* Copies the value to the given indices in the array.
|
||||
*/
|
||||
void fill_indices(ArrayRef<uint> indices, const T &value)
|
||||
void fill_indices(Span<uint> indices, const T &value)
|
||||
{
|
||||
MutableArrayRef<T>(*this).fill_indices(indices, value);
|
||||
MutableSpan<T>(*this).fill_indices(indices, value);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -267,8 +267,8 @@ class NodeWithSocketsRef {
|
|||
public:
|
||||
NodeWithSocketsRef(Node &node,
|
||||
StringRef name,
|
||||
ArrayRef<std::string> input_names,
|
||||
ArrayRef<std::string> output_names);
|
||||
Span<std::string> input_names,
|
||||
Span<std::string> output_names);
|
||||
|
||||
NodePort input(uint index) const
|
||||
{
|
||||
|
|
|
@ -38,15 +38,15 @@
|
|||
* same time.
|
||||
*/
|
||||
|
||||
#include "BLI_array_ref.hh"
|
||||
#include "BLI_index_range.hh"
|
||||
#include "BLI_span.hh"
|
||||
|
||||
namespace blender {
|
||||
|
||||
class IndexMask {
|
||||
private:
|
||||
/* The underlying reference to sorted integers. */
|
||||
ArrayRef<uint> m_indices;
|
||||
Span<uint> m_indices;
|
||||
|
||||
public:
|
||||
/* Creates an IndexMask that contains no indices. */
|
||||
|
@ -57,7 +57,7 @@ class IndexMask {
|
|||
* This constructor asserts that the given integers are in ascending order and that there are no
|
||||
* duplicates.
|
||||
*/
|
||||
IndexMask(ArrayRef<uint> indices) : m_indices(indices)
|
||||
IndexMask(Span<uint> indices) : m_indices(indices)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
for (uint i = 1; i < indices.size(); i++) {
|
||||
|
@ -70,7 +70,7 @@ class IndexMask {
|
|||
* Use this method when you know that no indices are skipped. It is more efficient than preparing
|
||||
* an integer array all the time.
|
||||
*/
|
||||
IndexMask(IndexRange range) : m_indices(range.as_array_ref())
|
||||
IndexMask(IndexRange range) : m_indices(range.as_span())
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -84,7 +84,7 @@ class IndexMask {
|
|||
* Do this:
|
||||
* do_something_with_an_index_mask({3, 4, 5});
|
||||
*/
|
||||
IndexMask(const std::initializer_list<uint> &indices) : IndexMask(ArrayRef<uint>(indices))
|
||||
IndexMask(const std::initializer_list<uint> &indices) : IndexMask(Span<uint>(indices))
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -95,7 +95,7 @@ class IndexMask {
|
|||
{
|
||||
}
|
||||
|
||||
operator ArrayRef<uint>() const
|
||||
operator Span<uint>() const
|
||||
{
|
||||
return m_indices;
|
||||
}
|
||||
|
@ -133,7 +133,7 @@ class IndexMask {
|
|||
}
|
||||
}
|
||||
|
||||
ArrayRef<uint> indices() const
|
||||
Span<uint> indices() const
|
||||
{
|
||||
return m_indices;
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@
|
|||
* Ideally this could be could be even closer to Python's enumerate(). We might get that in the
|
||||
* future with newer C++ versions.
|
||||
*
|
||||
* One other important feature is the as_array_ref method. This method returns an ArrayRef<uint>
|
||||
* One other important feature is the as_span method. This method returns an Span<uint>
|
||||
* that contains the interval as individual numbers.
|
||||
*/
|
||||
|
||||
|
@ -66,7 +66,7 @@ template<typename Value> class blocked_range;
|
|||
|
||||
namespace blender {
|
||||
|
||||
template<typename T> class ArrayRef;
|
||||
template<typename T> class Span;
|
||||
|
||||
class IndexRange {
|
||||
private:
|
||||
|
@ -227,7 +227,7 @@ class IndexRange {
|
|||
/**
|
||||
* Get read-only access to a memory buffer that contains the range as actual numbers.
|
||||
*/
|
||||
ArrayRef<uint> as_array_ref() const;
|
||||
Span<uint> as_span() const;
|
||||
|
||||
friend std::ostream &operator<<(std::ostream &stream, IndexRange range)
|
||||
{
|
||||
|
|
|
@ -35,7 +35,7 @@ template<typename Allocator = GuardedAllocator> class LinearAllocator : NonCopya
|
|||
private:
|
||||
Allocator m_allocator;
|
||||
Vector<void *> m_owned_buffers;
|
||||
Vector<ArrayRef<char>> m_unused_borrowed_buffers;
|
||||
Vector<Span<char>> m_unused_borrowed_buffers;
|
||||
|
||||
uintptr_t m_current_begin;
|
||||
uintptr_t m_current_end;
|
||||
|
@ -104,9 +104,9 @@ template<typename Allocator = GuardedAllocator> class LinearAllocator : NonCopya
|
|||
*
|
||||
* This method only allocates memory and does not construct the instance.
|
||||
*/
|
||||
template<typename T> MutableArrayRef<T> allocate_array(uint size)
|
||||
template<typename T> MutableSpan<T> allocate_array(uint size)
|
||||
{
|
||||
return MutableArrayRef<T>((T *)this->allocate(sizeof(T) * size, alignof(T)), size);
|
||||
return MutableSpan<T>((T *)this->allocate(sizeof(T) * size, alignof(T)), size);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -127,9 +127,9 @@ template<typename Allocator = GuardedAllocator> class LinearAllocator : NonCopya
|
|||
/**
|
||||
* Copy the given array into a memory buffer provided by this allocator.
|
||||
*/
|
||||
template<typename T> MutableArrayRef<T> construct_array_copy(ArrayRef<T> src)
|
||||
template<typename T> MutableSpan<T> construct_array_copy(Span<T> src)
|
||||
{
|
||||
MutableArrayRef<T> dst = this->allocate_array<T>(src.size());
|
||||
MutableSpan<T> dst = this->allocate_array<T>(src.size());
|
||||
uninitialized_copy_n(src.data(), src.size(), dst.data());
|
||||
return dst;
|
||||
}
|
||||
|
@ -146,14 +146,14 @@ template<typename Allocator = GuardedAllocator> class LinearAllocator : NonCopya
|
|||
return StringRefNull((const char *)buffer);
|
||||
}
|
||||
|
||||
MutableArrayRef<void *> allocate_elements_and_pointer_array(uint element_amount,
|
||||
uint element_size,
|
||||
uint element_alignment)
|
||||
MutableSpan<void *> allocate_elements_and_pointer_array(uint element_amount,
|
||||
uint element_size,
|
||||
uint element_alignment)
|
||||
{
|
||||
void *pointer_buffer = this->allocate(element_amount * sizeof(void *), alignof(void *));
|
||||
void *elements_buffer = this->allocate(element_amount * element_size, element_alignment);
|
||||
|
||||
MutableArrayRef<void *> pointers((void **)pointer_buffer, element_amount);
|
||||
MutableSpan<void *> pointers((void **)pointer_buffer, element_amount);
|
||||
void *next_element_buffer = elements_buffer;
|
||||
for (uint i : IndexRange(element_amount)) {
|
||||
pointers[i] = next_element_buffer;
|
||||
|
@ -164,11 +164,11 @@ template<typename Allocator = GuardedAllocator> class LinearAllocator : NonCopya
|
|||
}
|
||||
|
||||
template<typename T, typename... Args>
|
||||
ArrayRef<T *> construct_elements_and_pointer_array(uint n, Args &&... args)
|
||||
Span<T *> construct_elements_and_pointer_array(uint n, Args &&... args)
|
||||
{
|
||||
MutableArrayRef<void *> void_pointers = this->allocate_elements_and_pointer_array(
|
||||
MutableSpan<void *> void_pointers = this->allocate_elements_and_pointer_array(
|
||||
n, sizeof(T), alignof(T));
|
||||
MutableArrayRef<T *> pointers = void_pointers.cast<T *>();
|
||||
MutableSpan<T *> pointers = void_pointers.cast<T *>();
|
||||
|
||||
for (uint i : IndexRange(n)) {
|
||||
new (pointers[i]) T(std::forward<Args>(args)...);
|
||||
|
@ -183,7 +183,7 @@ template<typename Allocator = GuardedAllocator> class LinearAllocator : NonCopya
|
|||
*/
|
||||
void provide_buffer(void *buffer, uint size)
|
||||
{
|
||||
m_unused_borrowed_buffers.append(ArrayRef<char>((char *)buffer, size));
|
||||
m_unused_borrowed_buffers.append(Span<char>((char *)buffer, size));
|
||||
}
|
||||
|
||||
template<size_t Size, size_t Alignment>
|
||||
|
@ -196,7 +196,7 @@ template<typename Allocator = GuardedAllocator> class LinearAllocator : NonCopya
|
|||
void allocate_new_buffer(uint min_allocation_size)
|
||||
{
|
||||
for (uint i : m_unused_borrowed_buffers.index_range()) {
|
||||
ArrayRef<char> buffer = m_unused_borrowed_buffers[i];
|
||||
Span<char> buffer = m_unused_borrowed_buffers[i];
|
||||
if (buffer.size() >= min_allocation_size) {
|
||||
m_unused_borrowed_buffers.remove_and_reorder(i);
|
||||
m_current_begin = (uintptr_t)buffer.begin();
|
||||
|
|
|
@ -276,7 +276,7 @@ class Set {
|
|||
* We might be able to make this faster than sequentially adding all keys, but that is not
|
||||
* implemented yet.
|
||||
*/
|
||||
void add_multiple(ArrayRef<Key> keys)
|
||||
void add_multiple(Span<Key> keys)
|
||||
{
|
||||
for (const Key &key : keys) {
|
||||
this->add(key);
|
||||
|
@ -287,7 +287,7 @@ class Set {
|
|||
* Convenience function to add many new keys to the set at once. The keys must not exist in the
|
||||
* set before and there must not be duplicates in the array.
|
||||
*/
|
||||
void add_multiple_new(ArrayRef<Key> keys)
|
||||
void add_multiple_new(Span<Key> keys)
|
||||
{
|
||||
for (const Key &key : keys) {
|
||||
this->add_new(key);
|
||||
|
@ -726,7 +726,7 @@ template<typename Key> class StdUnorderedSetWrapper {
|
|||
return m_set.insert(std::move(key)).second;
|
||||
}
|
||||
|
||||
void add_multiple(ArrayRef<Key> keys)
|
||||
void add_multiple(Span<Key> keys)
|
||||
{
|
||||
for (const Key &key : keys) {
|
||||
m_set.insert(key);
|
||||
|
|
|
@ -14,44 +14,59 @@
|
|||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef __BLI_ARRAY_REF_HH__
|
||||
#define __BLI_ARRAY_REF_HH__
|
||||
#ifndef __BLI_SPAN_HH__
|
||||
#define __BLI_SPAN_HH__
|
||||
|
||||
/** \file
|
||||
* \ingroup bli
|
||||
*
|
||||
* An `blender::ArrayRef<T>` references an array that is owned by someone else. It is just a
|
||||
* pointer and a size. Since the memory is not owned, ArrayRef should not be used to transfer
|
||||
* ownership. The array cannot be modified through the ArrayRef. However, if T is a non-const
|
||||
* An `blender::Span<T>` references an array that is owned by someone else. It is just a
|
||||
* pointer and a size. Since the memory is not owned, Span should not be used to transfer
|
||||
* ownership. The array cannot be modified through the Span. However, if T is a non-const
|
||||
* pointer, the pointed-to elements can be modified.
|
||||
*
|
||||
* There is also `blender::MutableArrayRef<T>`. It is mostly the same as ArrayRef, but allows the
|
||||
* There is also `blender::MutableSpan<T>`. It is mostly the same as Span, but allows the
|
||||
* array to be modified.
|
||||
*
|
||||
* An (Mutable)ArrayRef can refer to data owned by many different data structures including
|
||||
* A (Mutable)Span can refer to data owned by many different data structures including
|
||||
* blender::Vector, blender::Array, blender::VectorSet, std::vector, std::array, std::string,
|
||||
* std::initializer_list and c-style array.
|
||||
*
|
||||
* `blender::ArrayRef<T>` should be your default choice when you have to pass a read-only array
|
||||
* `blender::Span` is very similar to `std::span` (C++20). However, there are a few differences:
|
||||
* - `blender::Span` is const by default. This is to avoid making things mutable when they don't
|
||||
* have to be. To get a non-const span, you need to use `blender::MutableSpan`. Below is a list
|
||||
* of const-behavior-equivalent pairs of data structures:
|
||||
* - std::span<int> <==> blender::MutableSpan<int>
|
||||
* - std::span<const int> <==> blender::Span<int>
|
||||
* - std::span<int *> <==> blender::MutableSpan<int *>
|
||||
* - std::span<const int *> <==> blender::MutableSpan<const int *>
|
||||
* - std::span<int * const> <==> blender::Span<int *>
|
||||
* - std::span<const int * const> <==> blender::Span<const int *>
|
||||
* - `blender::Span` always has a dynamic extent, while `std::span` can have a size that is
|
||||
* determined at compile time. I did not have a use case for that yet. If we need it, we can
|
||||
* decide to add this functionality to `blender::Span` or introduce a new type like
|
||||
* `blender::FixedSpan<T, N>`.
|
||||
*
|
||||
* `blender::Span<T>` should be your default choice when you have to pass a read-only array
|
||||
* into a function. It is better than passing a `const Vector &`, because then the function only
|
||||
* works for vectors and not for e.g. arrays. Using ArrayRef as function parameter makes it usable
|
||||
* works for vectors and not for e.g. arrays. Using Span as function parameter makes it usable
|
||||
* in more contexts, better expresses the intent and does not sacrifice performance. It is also
|
||||
* better than passing a raw pointer and size separately, because it is more convenient and safe.
|
||||
*
|
||||
* `blender::MutableArrayRef<T>` can be used when a function is supposed to return an array, the
|
||||
* `blender::MutableSpan<T>` can be used when a function is supposed to return an array, the
|
||||
* size of which is known before the function is called. One advantage of this approach is that the
|
||||
* caller is responsible for allocation and deallocation. Furthermore, the function can focus on
|
||||
* its task, without having to worry about memory allocation. Alternatively, a function could
|
||||
* return an Array or Vector.
|
||||
*
|
||||
* Note: When a function has a MutableArrayRef<T> output parameter and T is not a trivial type,
|
||||
* Note: When a function has a MutableSpan<T> output parameter and T is not a trivial type,
|
||||
* then the function has to specify whether the referenced array is expected to be initialized or
|
||||
* not.
|
||||
*
|
||||
* Since the arrays are only referenced, it is generally unsafe to store an ArrayRef. When you
|
||||
* Since the arrays are only referenced, it is generally unsafe to store an Span. When you
|
||||
* store one, you should know who owns the memory.
|
||||
*
|
||||
* Instances of ArrayRef and MutableArrayRef are small and should be passed by value.
|
||||
* Instances of Span and MutableSpan are small and should be passed by value.
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
|
@ -70,7 +85,7 @@ namespace blender {
|
|||
* References an array of type T that is owned by someone else. The data in the array cannot be
|
||||
* modified.
|
||||
*/
|
||||
template<typename T> class ArrayRef {
|
||||
template<typename T> class Span {
|
||||
private:
|
||||
const T *m_start = nullptr;
|
||||
uint m_size = 0;
|
||||
|
@ -79,9 +94,9 @@ template<typename T> class ArrayRef {
|
|||
/**
|
||||
* Create a reference to an empty array.
|
||||
*/
|
||||
ArrayRef() = default;
|
||||
Span() = default;
|
||||
|
||||
ArrayRef(const T *start, uint size) : m_start(start), m_size(size)
|
||||
Span(const T *start, uint size) : m_start(start), m_size(size)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -93,29 +108,29 @@ template<typename T> class ArrayRef {
|
|||
* call_function_with_array({1, 2, 3, 4});
|
||||
*
|
||||
* Don't:
|
||||
* ArrayRef<int> ref = {1, 2, 3, 4};
|
||||
* call_function_with_array(ref);
|
||||
* Span<int> span = {1, 2, 3, 4};
|
||||
* call_function_with_array(span);
|
||||
*/
|
||||
ArrayRef(const std::initializer_list<T> &list) : ArrayRef(list.begin(), (uint)list.size())
|
||||
Span(const std::initializer_list<T> &list) : Span(list.begin(), (uint)list.size())
|
||||
{
|
||||
}
|
||||
|
||||
ArrayRef(const std::vector<T> &vector) : ArrayRef(vector.data(), (uint)vector.size())
|
||||
Span(const std::vector<T> &vector) : Span(vector.data(), (uint)vector.size())
|
||||
{
|
||||
}
|
||||
|
||||
template<std::size_t N> ArrayRef(const std::array<T, N> &array) : ArrayRef(array.data(), N)
|
||||
template<std::size_t N> Span(const std::array<T, N> &array) : Span(array.data(), N)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Support implicit conversions like the ones below:
|
||||
* ArrayRef<T *> -> ArrayRef<const T *>
|
||||
* ArrayRef<Derived *> -> ArrayRef<Base *>
|
||||
* Span<T *> -> Span<const T *>
|
||||
* Span<Derived *> -> Span<Base *>
|
||||
*/
|
||||
template<typename U,
|
||||
typename std::enable_if<std::is_convertible<U *, T>::value>::type * = nullptr>
|
||||
ArrayRef(ArrayRef<U *> array) : ArrayRef((T *)array.data(), array.size())
|
||||
Span(Span<U *> array) : Span((T *)array.data(), array.size())
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -123,52 +138,52 @@ template<typename T> class ArrayRef {
|
|||
* Returns a contiguous part of the array. This invokes undefined behavior when the slice does
|
||||
* not stay within the bounds of the array.
|
||||
*/
|
||||
ArrayRef slice(uint start, uint size) const
|
||||
Span slice(uint start, uint size) const
|
||||
{
|
||||
BLI_assert(start + size <= this->size() || size == 0);
|
||||
return ArrayRef(m_start + start, size);
|
||||
return Span(m_start + start, size);
|
||||
}
|
||||
|
||||
ArrayRef slice(IndexRange range) const
|
||||
Span slice(IndexRange range) const
|
||||
{
|
||||
return this->slice(range.start(), range.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new ArrayRef with n elements removed from the beginning. This invokes undefined
|
||||
* Returns a new Span with n elements removed from the beginning. This invokes undefined
|
||||
* behavior when the array is too small.
|
||||
*/
|
||||
ArrayRef drop_front(uint n) const
|
||||
Span drop_front(uint n) const
|
||||
{
|
||||
BLI_assert(n <= this->size());
|
||||
return this->slice(n, this->size() - n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new ArrayRef with n elements removed from the beginning. This invokes undefined
|
||||
* Returns a new Span with n elements removed from the beginning. This invokes undefined
|
||||
* behavior when the array is too small.
|
||||
*/
|
||||
ArrayRef drop_back(uint n) const
|
||||
Span drop_back(uint n) const
|
||||
{
|
||||
BLI_assert(n <= this->size());
|
||||
return this->slice(0, this->size() - n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new ArrayRef that only contains the first n elements. This invokes undefined
|
||||
* Returns a new Span that only contains the first n elements. This invokes undefined
|
||||
* behavior when the array is too small.
|
||||
*/
|
||||
ArrayRef take_front(uint n) const
|
||||
Span take_front(uint n) const
|
||||
{
|
||||
BLI_assert(n <= this->size());
|
||||
return this->slice(0, n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new ArrayRef that only contains the last n elements. This invokes undefined
|
||||
* Returns a new Span that only contains the last n elements. This invokes undefined
|
||||
* behavior when the array is too small.
|
||||
*/
|
||||
ArrayRef take_back(uint n) const
|
||||
Span take_back(uint n) const
|
||||
{
|
||||
BLI_assert(n <= this->size());
|
||||
return this->slice(this->size() - n, n);
|
||||
|
@ -220,7 +235,7 @@ template<typename T> class ArrayRef {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the number of bytes referenced by this ArrayRef.
|
||||
* Returns the number of bytes referenced by this Span.
|
||||
*/
|
||||
uint size_in_bytes() const
|
||||
{
|
||||
|
@ -323,7 +338,7 @@ template<typename T> class ArrayRef {
|
|||
* called on small arrays, because it has a running time of O(n*m) where n and m are the sizes of
|
||||
* the arrays.
|
||||
*/
|
||||
bool intersects__linear_search(ArrayRef other) const
|
||||
bool intersects__linear_search(Span other) const
|
||||
{
|
||||
/* The size should really be smaller than that. If it is not, the calling code should be
|
||||
* changed. */
|
||||
|
@ -372,22 +387,22 @@ template<typename T> class ArrayRef {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns a new ArrayRef to the same underlying memory buffer. No conversions are done.
|
||||
* Returns a new Span to the same underlying memory buffer. No conversions are done.
|
||||
*/
|
||||
template<typename NewT> ArrayRef<NewT> cast() const
|
||||
template<typename NewT> Span<NewT> cast() const
|
||||
{
|
||||
BLI_assert((m_size * sizeof(T)) % sizeof(NewT) == 0);
|
||||
uint new_size = m_size * sizeof(T) / sizeof(NewT);
|
||||
return ArrayRef<NewT>(reinterpret_cast<const NewT *>(m_start), new_size);
|
||||
return Span<NewT>(reinterpret_cast<const NewT *>(m_start), new_size);
|
||||
}
|
||||
|
||||
/**
|
||||
* A debug utility to print the content of the ArrayRef. Every element will be printed on a
|
||||
* A debug utility to print the content of the Span. Every element will be printed on a
|
||||
* separate line using the given callback.
|
||||
*/
|
||||
template<typename PrintLineF> void print_as_lines(std::string name, PrintLineF print_line) const
|
||||
{
|
||||
std::cout << "ArrayRef: " << name << " \tSize:" << m_size << '\n';
|
||||
std::cout << "Span: " << name << " \tSize:" << m_size << '\n';
|
||||
for (const T &value : *this) {
|
||||
std::cout << " ";
|
||||
print_line(value);
|
||||
|
@ -396,7 +411,7 @@ template<typename T> class ArrayRef {
|
|||
}
|
||||
|
||||
/**
|
||||
* A debug utility to print the content of the array ref. Every element be printed on a separate
|
||||
* A debug utility to print the content of the span. Every element be printed on a separate
|
||||
* line.
|
||||
*/
|
||||
void print_as_lines(std::string name) const
|
||||
|
@ -406,18 +421,18 @@ template<typename T> class ArrayRef {
|
|||
};
|
||||
|
||||
/**
|
||||
* Mostly the same as ArrayRef, except that one can change the array elements through a
|
||||
* MutableArrayRef.
|
||||
* Mostly the same as Span, except that one can change the array elements through a
|
||||
* MutableSpan.
|
||||
*/
|
||||
template<typename T> class MutableArrayRef {
|
||||
template<typename T> class MutableSpan {
|
||||
private:
|
||||
T *m_start;
|
||||
uint m_size;
|
||||
|
||||
public:
|
||||
MutableArrayRef() = default;
|
||||
MutableSpan() = default;
|
||||
|
||||
MutableArrayRef(T *start, uint size) : m_start(start), m_size(size)
|
||||
MutableSpan(T *start, uint size) : m_start(start), m_size(size)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -429,25 +444,24 @@ template<typename T> class MutableArrayRef {
|
|||
* call_function_with_array({1, 2, 3, 4});
|
||||
*
|
||||
* Don't:
|
||||
* MutableArrayRef<int> ref = {1, 2, 3, 4};
|
||||
* call_function_with_array(ref);
|
||||
* MutableSpan<int> span = {1, 2, 3, 4};
|
||||
* call_function_with_array(span);
|
||||
*/
|
||||
MutableArrayRef(std::initializer_list<T> &list) : MutableArrayRef(list.begin(), list.size())
|
||||
MutableSpan(std::initializer_list<T> &list) : MutableSpan(list.begin(), list.size())
|
||||
{
|
||||
}
|
||||
|
||||
MutableArrayRef(std::vector<T> &vector) : MutableArrayRef(vector.data(), vector.size())
|
||||
MutableSpan(std::vector<T> &vector) : MutableSpan(vector.data(), vector.size())
|
||||
{
|
||||
}
|
||||
|
||||
template<std::size_t N>
|
||||
MutableArrayRef(std::array<T, N> &array) : MutableArrayRef(array.data(), N)
|
||||
template<std::size_t N> MutableSpan(std::array<T, N> &array) : MutableSpan(array.data(), N)
|
||||
{
|
||||
}
|
||||
|
||||
operator ArrayRef<T>() const
|
||||
operator Span<T>() const
|
||||
{
|
||||
return ArrayRef<T>(m_start, m_size);
|
||||
return Span<T>(m_start, m_size);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -470,7 +484,7 @@ template<typename T> class MutableArrayRef {
|
|||
* Replace a subset of all elements with the given value. This invokes undefined behavior when
|
||||
* one of the indices is out of bounds.
|
||||
*/
|
||||
void fill_indices(ArrayRef<uint> indices, const T &value)
|
||||
void fill_indices(Span<uint> indices, const T &value)
|
||||
{
|
||||
for (uint i : indices) {
|
||||
BLI_assert(i < m_size);
|
||||
|
@ -507,59 +521,59 @@ template<typename T> class MutableArrayRef {
|
|||
* Returns a contiguous part of the array. This invokes undefined behavior when the slice would
|
||||
* go out of bounds.
|
||||
*/
|
||||
MutableArrayRef slice(uint start, uint length) const
|
||||
MutableSpan slice(uint start, uint length) const
|
||||
{
|
||||
BLI_assert(start + length <= this->size());
|
||||
return MutableArrayRef(m_start + start, length);
|
||||
return MutableSpan(m_start + start, length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new MutableArrayRef with n elements removed from the beginning. This invokes
|
||||
* Returns a new MutableSpan with n elements removed from the beginning. This invokes
|
||||
* undefined behavior when the array is too small.
|
||||
*/
|
||||
MutableArrayRef drop_front(uint n) const
|
||||
MutableSpan drop_front(uint n) const
|
||||
{
|
||||
BLI_assert(n <= this->size());
|
||||
return this->slice(n, this->size() - n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new MutableArrayRef with n elements removed from the end. This invokes undefined
|
||||
* Returns a new MutableSpan with n elements removed from the end. This invokes undefined
|
||||
* behavior when the array is too small.
|
||||
*/
|
||||
MutableArrayRef drop_back(uint n) const
|
||||
MutableSpan drop_back(uint n) const
|
||||
{
|
||||
BLI_assert(n <= this->size());
|
||||
return this->slice(0, this->size() - n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new MutableArrayRef that only contains the first n elements. This invokes undefined
|
||||
* Returns a new MutableSpan that only contains the first n elements. This invokes undefined
|
||||
* behavior when the array is too small.
|
||||
*/
|
||||
MutableArrayRef take_front(uint n) const
|
||||
MutableSpan take_front(uint n) const
|
||||
{
|
||||
BLI_assert(n <= this->size());
|
||||
return this->slice(0, n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a new MutableArrayRef that only contains the last n elements. This invokes undefined
|
||||
* Return a new MutableSpan that only contains the last n elements. This invokes undefined
|
||||
* behavior when the array is too small.
|
||||
*/
|
||||
MutableArrayRef take_back(uint n) const
|
||||
MutableSpan take_back(uint n) const
|
||||
{
|
||||
BLI_assert(n <= this->size());
|
||||
return this->slice(this->size() - n, n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an (immutable) ArrayRef that references the same array. This is usually not needed,
|
||||
* Returns an (immutable) Span that references the same array. This is usually not needed,
|
||||
* due to implicit conversions. However, sometimes automatic type deduction needs some help.
|
||||
*/
|
||||
ArrayRef<T> as_ref() const
|
||||
Span<T> as_span() const
|
||||
{
|
||||
return ArrayRef<T>(m_start, m_size);
|
||||
return Span<T>(m_start, m_size);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -582,22 +596,22 @@ template<typename T> class MutableArrayRef {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns a new array ref to the same underlying memory buffer. No conversions are done.
|
||||
* Returns a new span to the same underlying memory buffer. No conversions are done.
|
||||
*/
|
||||
template<typename NewT> MutableArrayRef<NewT> cast() const
|
||||
template<typename NewT> MutableSpan<NewT> cast() const
|
||||
{
|
||||
BLI_assert((m_size * sizeof(T)) % sizeof(NewT) == 0);
|
||||
uint new_size = m_size * sizeof(T) / sizeof(NewT);
|
||||
return MutableArrayRef<NewT>(reinterpret_cast<NewT *>(m_start), new_size);
|
||||
return MutableSpan<NewT>(reinterpret_cast<NewT *>(m_start), new_size);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Shorthand to make use of automatic template parameter deduction.
|
||||
*/
|
||||
template<typename T> ArrayRef<T> ref_c_array(const T *array, uint size)
|
||||
template<typename T> Span<T> ref_c_array(const T *array, uint size)
|
||||
{
|
||||
return ArrayRef<T>(array, size);
|
||||
return Span<T>(array, size);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -627,4 +641,4 @@ void assert_same_size(const T1 &v1, const T2 &v2, const T3 &v3)
|
|||
|
||||
} /* namespace blender */
|
||||
|
||||
#endif /* __BLI_ARRAY_REF_HH__ */
|
||||
#endif /* __BLI_SPAN_HH__ */
|
|
@ -41,8 +41,8 @@
|
|||
*/
|
||||
|
||||
#include "BLI_allocator.hh"
|
||||
#include "BLI_array_ref.hh"
|
||||
#include "BLI_memory_utils.hh"
|
||||
#include "BLI_span.hh"
|
||||
|
||||
namespace blender {
|
||||
|
||||
|
@ -139,7 +139,7 @@ class Stack {
|
|||
* Create a new stack that contains the given elements. The values are pushed to the stack in
|
||||
* the order they are in the array.
|
||||
*/
|
||||
Stack(ArrayRef<T> values) : Stack()
|
||||
Stack(Span<T> values) : Stack()
|
||||
{
|
||||
this->push_multiple(values);
|
||||
}
|
||||
|
@ -153,7 +153,7 @@ class Stack {
|
|||
* assert(stack.pop() == 6);
|
||||
* assert(stack.pop() == 5);
|
||||
*/
|
||||
Stack(const std::initializer_list<T> &values) : Stack(ArrayRef<T>(values))
|
||||
Stack(const std::initializer_list<T> &values) : Stack(Span<T>(values))
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -162,7 +162,7 @@ class Stack {
|
|||
for (const Chunk *chunk = &other.m_inline_chunk; chunk; chunk = chunk->above) {
|
||||
const T *begin = chunk->begin;
|
||||
const T *end = (chunk == other.m_top_chunk) ? other.m_top : chunk->capacity_end;
|
||||
this->push_multiple(ArrayRef<T>(begin, end - begin));
|
||||
this->push_multiple(Span<T>(begin, end - begin));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -289,9 +289,9 @@ class Stack {
|
|||
* This method is more efficient than pushing multiple elements individually and might cause less
|
||||
* heap allocations.
|
||||
*/
|
||||
void push_multiple(ArrayRef<T> values)
|
||||
void push_multiple(Span<T> values)
|
||||
{
|
||||
ArrayRef<T> remaining_values = values;
|
||||
Span<T> remaining_values = values;
|
||||
while (!remaining_values.is_empty()) {
|
||||
if (m_top == m_top_chunk->capacity_end) {
|
||||
this->activate_next_chunk(remaining_values.size());
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#include "BLI_array_ref.hh"
|
||||
#include "BLI_span.hh"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
namespace blender {
|
||||
|
@ -83,9 +83,9 @@ class StringRefBase {
|
|||
return m_data;
|
||||
}
|
||||
|
||||
operator ArrayRef<char>() const
|
||||
operator Span<char>() const
|
||||
{
|
||||
return ArrayRef<char>(m_data, m_size);
|
||||
return Span<char>(m_data, m_size);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -44,11 +44,11 @@
|
|||
#include <memory>
|
||||
|
||||
#include "BLI_allocator.hh"
|
||||
#include "BLI_array_ref.hh"
|
||||
#include "BLI_index_range.hh"
|
||||
#include "BLI_listbase_wrapper.hh"
|
||||
#include "BLI_math_base.h"
|
||||
#include "BLI_memory_utils.hh"
|
||||
#include "BLI_span.hh"
|
||||
#include "BLI_string.h"
|
||||
#include "BLI_string_ref.hh"
|
||||
#include "BLI_utildefines.h"
|
||||
|
@ -152,14 +152,14 @@ class Vector {
|
|||
* This allows you to write code like:
|
||||
* Vector<int> vec = {3, 4, 5};
|
||||
*/
|
||||
Vector(const std::initializer_list<T> &values) : Vector(ArrayRef<T>(values))
|
||||
Vector(const std::initializer_list<T> &values) : Vector(Span<T>(values))
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a vector from an array ref. The values in the vector are copy constructed.
|
||||
*/
|
||||
Vector(ArrayRef<T> values) : Vector()
|
||||
Vector(Span<T> values) : Vector()
|
||||
{
|
||||
uint size = values.size();
|
||||
this->reserve(size);
|
||||
|
@ -263,22 +263,22 @@ class Vector {
|
|||
}
|
||||
}
|
||||
|
||||
operator ArrayRef<T>() const
|
||||
operator Span<T>() const
|
||||
{
|
||||
return ArrayRef<T>(m_begin, this->size());
|
||||
return Span<T>(m_begin, this->size());
|
||||
}
|
||||
|
||||
operator MutableArrayRef<T>()
|
||||
operator MutableSpan<T>()
|
||||
{
|
||||
return MutableArrayRef<T>(m_begin, this->size());
|
||||
return MutableSpan<T>(m_begin, this->size());
|
||||
}
|
||||
|
||||
ArrayRef<T> as_ref() const
|
||||
Span<T> as_span() const
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
MutableArrayRef<T> as_mutable_ref()
|
||||
MutableSpan<T> as_mutable_span()
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
@ -478,7 +478,7 @@ class Vector {
|
|||
*
|
||||
* This can be used to emulate parts of std::vector::insert.
|
||||
*/
|
||||
void extend(ArrayRef<T> array)
|
||||
void extend(Span<T> array)
|
||||
{
|
||||
this->extend(array.data(), array.size());
|
||||
}
|
||||
|
@ -493,7 +493,7 @@ class Vector {
|
|||
* operation when the vector is large, but can be very cheap when it is known that the vector is
|
||||
* small.
|
||||
*/
|
||||
void extend_non_duplicates(ArrayRef<T> array)
|
||||
void extend_non_duplicates(Span<T> array)
|
||||
{
|
||||
for (const T &value : array) {
|
||||
this->append_non_duplicates(value);
|
||||
|
@ -504,7 +504,7 @@ class Vector {
|
|||
* Extend the vector without bounds checking. It is assumed that enough memory has been reserved
|
||||
* beforehand. Only use this in performance critical code.
|
||||
*/
|
||||
void extend_unchecked(ArrayRef<T> array)
|
||||
void extend_unchecked(Span<T> array)
|
||||
{
|
||||
this->extend_unchecked(array.data(), array.size());
|
||||
}
|
||||
|
@ -542,9 +542,9 @@ class Vector {
|
|||
/**
|
||||
* Copy the value to all positions specified by the indices array.
|
||||
*/
|
||||
void fill_indices(ArrayRef<uint> indices, const T &value)
|
||||
void fill_indices(Span<uint> indices, const T &value)
|
||||
{
|
||||
MutableArrayRef<T>(*this).fill_indices(indices, value);
|
||||
MutableSpan<T>(*this).fill_indices(indices, value);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
* - The insertion order is important.
|
||||
* - Iteration over all keys has to be fast.
|
||||
* - The keys in the set are supposed to be passed to a function that does not have to know that
|
||||
* the keys are stored in a set. With a VectorSet, one can get an ArrayRef containing all keys
|
||||
* the keys are stored in a set. With a VectorSet, one can get a Span containing all keys
|
||||
* without additional copies.
|
||||
*
|
||||
* blender::VectorSet is implemented using open addressing in a slot array with a power-of-two
|
||||
|
@ -279,7 +279,7 @@ class VectorSet {
|
|||
* We might be able to make this faster than sequentially adding all keys, but that is not
|
||||
* implemented yet.
|
||||
*/
|
||||
void add_multiple(ArrayRef<Key> keys)
|
||||
void add_multiple(Span<Key> keys)
|
||||
{
|
||||
for (const Key &key : keys) {
|
||||
this->add(key);
|
||||
|
@ -411,18 +411,18 @@ class VectorSet {
|
|||
return m_keys[index];
|
||||
}
|
||||
|
||||
operator ArrayRef<Key>() const
|
||||
operator Span<Key>() const
|
||||
{
|
||||
return ArrayRef<Key>(m_keys, this->size());
|
||||
return Span<Key>(m_keys, this->size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an ArrayRef referencing the keys vector. The referenced memory buffer is only valid as
|
||||
* Get an Span referencing the keys vector. The referenced memory buffer is only valid as
|
||||
* long as the vector set is not changed.
|
||||
*
|
||||
* The keys must not be changed, because this would change their hash value.
|
||||
*/
|
||||
ArrayRef<Key> as_ref() const
|
||||
Span<Key> as_span() const
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
@ -432,7 +432,7 @@ class VectorSet {
|
|||
*/
|
||||
void print_stats(StringRef name = "") const
|
||||
{
|
||||
HashTableStats stats(*this, this->as_ref());
|
||||
HashTableStats stats(*this, this->as_span());
|
||||
stats.print();
|
||||
}
|
||||
|
||||
|
|
|
@ -144,7 +144,6 @@ set(SRC
|
|||
BLI_args.h
|
||||
BLI_array.h
|
||||
BLI_array.hh
|
||||
BLI_array_ref.hh
|
||||
BLI_array_store.h
|
||||
BLI_array_store_utils.h
|
||||
BLI_array_utils.h
|
||||
|
@ -240,6 +239,7 @@ set(SRC
|
|||
BLI_smallhash.h
|
||||
BLI_sort.h
|
||||
BLI_sort_utils.h
|
||||
BLI_span.hh
|
||||
BLI_stack.h
|
||||
BLI_stack.hh
|
||||
BLI_strict_flags.h
|
||||
|
|
|
@ -18,8 +18,8 @@
|
|||
#include <mutex>
|
||||
|
||||
#include "BLI_array.hh"
|
||||
#include "BLI_array_ref.hh"
|
||||
#include "BLI_index_range.hh"
|
||||
#include "BLI_span.hh"
|
||||
#include "BLI_vector.hh"
|
||||
|
||||
namespace blender {
|
||||
|
@ -29,18 +29,18 @@ static uint current_array_size = 0;
|
|||
static uint *current_array = nullptr;
|
||||
static std::mutex current_array_mutex;
|
||||
|
||||
ArrayRef<uint> IndexRange::as_array_ref() const
|
||||
Span<uint> IndexRange::as_span() const
|
||||
{
|
||||
uint min_required_size = m_start + m_size;
|
||||
|
||||
if (min_required_size <= current_array_size) {
|
||||
return ArrayRef<uint>(current_array + m_start, m_size);
|
||||
return Span<uint>(current_array + m_start, m_size);
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(current_array_mutex);
|
||||
|
||||
if (min_required_size <= current_array_size) {
|
||||
return ArrayRef<uint>(current_array + m_start, m_size);
|
||||
return Span<uint>(current_array + m_start, m_size);
|
||||
}
|
||||
|
||||
uint new_size = std::max<uint>(1000, power_of_2_max_u(min_required_size));
|
||||
|
@ -54,7 +54,7 @@ ArrayRef<uint> IndexRange::as_array_ref() const
|
|||
std::atomic_thread_fence(std::memory_order_seq_cst);
|
||||
current_array_size = new_size;
|
||||
|
||||
return ArrayRef<uint>(current_array + m_start, m_size);
|
||||
return Span<uint>(current_array + m_start, m_size);
|
||||
}
|
||||
|
||||
} // namespace blender
|
||||
|
|
|
@ -250,8 +250,8 @@ std::string color_attr_from_hsv(float h, float s, float v)
|
|||
|
||||
NodeWithSocketsRef::NodeWithSocketsRef(Node &node,
|
||||
StringRef name,
|
||||
ArrayRef<std::string> input_names,
|
||||
ArrayRef<std::string> output_names)
|
||||
Span<std::string> input_names,
|
||||
Span<std::string> output_names)
|
||||
: m_node(&node)
|
||||
{
|
||||
std::stringstream ss;
|
||||
|
|
|
@ -49,7 +49,7 @@ void unregister_graph(Depsgraph *depsgraph)
|
|||
}
|
||||
}
|
||||
|
||||
ArrayRef<Depsgraph *> get_all_registered_graphs(Main *bmain)
|
||||
Span<Depsgraph *> get_all_registered_graphs(Main *bmain)
|
||||
{
|
||||
VectorSet<Depsgraph *> *graphs = g_graph_registry.lookup_ptr(bmain);
|
||||
if (graphs != nullptr) {
|
||||
|
|
|
@ -33,6 +33,6 @@ struct Depsgraph;
|
|||
|
||||
void register_graph(Depsgraph *depsgraph);
|
||||
void unregister_graph(Depsgraph *depsgraph);
|
||||
ArrayRef<Depsgraph *> get_all_registered_graphs(Main *bmain);
|
||||
Span<Depsgraph *> get_all_registered_graphs(Main *bmain);
|
||||
|
||||
} // namespace DEG
|
||||
|
|
|
@ -53,9 +53,9 @@ struct CustomData_MeshMasks;
|
|||
namespace DEG {
|
||||
|
||||
/* Commonly used types. */
|
||||
using blender::ArrayRef;
|
||||
using blender::Map;
|
||||
using blender::Set;
|
||||
using blender::Span;
|
||||
using blender::StringRef;
|
||||
using blender::StringRefNull;
|
||||
using blender::Vector;
|
||||
|
|
|
@ -67,10 +67,10 @@
|
|||
#include "BLI_vector.hh"
|
||||
|
||||
using blender::Array;
|
||||
using blender::ArrayRef;
|
||||
using blender::IndexRange;
|
||||
using blender::ListBaseWrapper;
|
||||
using blender::MutableArrayRef;
|
||||
using blender::MutableSpan;
|
||||
using blender::Span;
|
||||
using blender::Vector;
|
||||
|
||||
static void requiredDataMask(Object *UNUSED(ob),
|
||||
|
@ -104,7 +104,7 @@ static void compute_vertex_mask__armature_mode(MDeformVert *dvert,
|
|||
Object *ob,
|
||||
Object *armature_ob,
|
||||
float threshold,
|
||||
MutableArrayRef<bool> r_vertex_mask)
|
||||
MutableSpan<bool> r_vertex_mask)
|
||||
{
|
||||
/* Element i is true if there is a selected bone that uses vertex group i. */
|
||||
Vector<bool> selected_bone_uses_group;
|
||||
|
@ -115,10 +115,10 @@ static void compute_vertex_mask__armature_mode(MDeformVert *dvert,
|
|||
selected_bone_uses_group.append(bone_for_group_exists);
|
||||
}
|
||||
|
||||
ArrayRef<bool> use_vertex_group = selected_bone_uses_group;
|
||||
Span<bool> use_vertex_group = selected_bone_uses_group;
|
||||
|
||||
for (int i : r_vertex_mask.index_range()) {
|
||||
ArrayRef<MDeformWeight> weights(dvert[i].dw, dvert[i].totweight);
|
||||
Span<MDeformWeight> weights(dvert[i].dw, dvert[i].totweight);
|
||||
r_vertex_mask[i] = false;
|
||||
|
||||
/* check the groups that vertex is assigned to, and see if it was any use */
|
||||
|
@ -137,7 +137,7 @@ static void compute_vertex_mask__armature_mode(MDeformVert *dvert,
|
|||
static void compute_vertex_mask__vertex_group_mode(MDeformVert *dvert,
|
||||
int defgrp_index,
|
||||
float threshold,
|
||||
MutableArrayRef<bool> r_vertex_mask)
|
||||
MutableSpan<bool> r_vertex_mask)
|
||||
{
|
||||
for (int i : r_vertex_mask.index_range()) {
|
||||
const bool found = BKE_defvert_find_weight(&dvert[i], defgrp_index) > threshold;
|
||||
|
@ -145,15 +145,15 @@ static void compute_vertex_mask__vertex_group_mode(MDeformVert *dvert,
|
|||
}
|
||||
}
|
||||
|
||||
static void invert_boolean_array(MutableArrayRef<bool> array)
|
||||
static void invert_boolean_array(MutableSpan<bool> array)
|
||||
{
|
||||
for (bool &value : array) {
|
||||
value = !value;
|
||||
}
|
||||
}
|
||||
|
||||
static void compute_masked_vertices(ArrayRef<bool> vertex_mask,
|
||||
MutableArrayRef<int> r_vertex_map,
|
||||
static void compute_masked_vertices(Span<bool> vertex_mask,
|
||||
MutableSpan<int> r_vertex_map,
|
||||
uint *r_num_masked_vertices)
|
||||
{
|
||||
BLI_assert(vertex_mask.size() == r_vertex_map.size());
|
||||
|
@ -173,8 +173,8 @@ static void compute_masked_vertices(ArrayRef<bool> vertex_mask,
|
|||
}
|
||||
|
||||
static void computed_masked_edges(const Mesh *mesh,
|
||||
ArrayRef<bool> vertex_mask,
|
||||
MutableArrayRef<int> r_edge_map,
|
||||
Span<bool> vertex_mask,
|
||||
MutableSpan<int> r_edge_map,
|
||||
uint *r_num_masked_edges)
|
||||
{
|
||||
BLI_assert(mesh->totedge == r_edge_map.size());
|
||||
|
@ -197,7 +197,7 @@ static void computed_masked_edges(const Mesh *mesh,
|
|||
}
|
||||
|
||||
static void computed_masked_polygons(const Mesh *mesh,
|
||||
ArrayRef<bool> vertex_mask,
|
||||
Span<bool> vertex_mask,
|
||||
Vector<int> &r_masked_poly_indices,
|
||||
Vector<int> &r_loop_starts,
|
||||
uint *r_num_masked_polys,
|
||||
|
@ -213,7 +213,7 @@ static void computed_masked_polygons(const Mesh *mesh,
|
|||
const MPoly &poly_src = mesh->mpoly[i];
|
||||
|
||||
bool all_verts_in_mask = true;
|
||||
ArrayRef<MLoop> loops_src(&mesh->mloop[poly_src.loopstart], poly_src.totloop);
|
||||
Span<MLoop> loops_src(&mesh->mloop[poly_src.loopstart], poly_src.totloop);
|
||||
for (const MLoop &loop : loops_src) {
|
||||
if (!vertex_mask[loop.v]) {
|
||||
all_verts_in_mask = false;
|
||||
|
@ -234,7 +234,7 @@ static void computed_masked_polygons(const Mesh *mesh,
|
|||
|
||||
static void copy_masked_vertices_to_new_mesh(const Mesh &src_mesh,
|
||||
Mesh &dst_mesh,
|
||||
ArrayRef<int> vertex_map)
|
||||
Span<int> vertex_map)
|
||||
{
|
||||
BLI_assert(src_mesh.totvert == vertex_map.size());
|
||||
for (const int i_src : vertex_map.index_range()) {
|
||||
|
@ -253,8 +253,8 @@ static void copy_masked_vertices_to_new_mesh(const Mesh &src_mesh,
|
|||
|
||||
static void copy_masked_edges_to_new_mesh(const Mesh &src_mesh,
|
||||
Mesh &dst_mesh,
|
||||
ArrayRef<int> vertex_map,
|
||||
ArrayRef<int> edge_map)
|
||||
Span<int> vertex_map,
|
||||
Span<int> edge_map)
|
||||
{
|
||||
BLI_assert(src_mesh.totvert == vertex_map.size());
|
||||
BLI_assert(src_mesh.totedge == edge_map.size());
|
||||
|
@ -276,10 +276,10 @@ static void copy_masked_edges_to_new_mesh(const Mesh &src_mesh,
|
|||
|
||||
static void copy_masked_polys_to_new_mesh(const Mesh &src_mesh,
|
||||
Mesh &dst_mesh,
|
||||
ArrayRef<int> vertex_map,
|
||||
ArrayRef<int> edge_map,
|
||||
ArrayRef<int> masked_poly_indices,
|
||||
ArrayRef<int> new_loop_starts)
|
||||
Span<int> vertex_map,
|
||||
Span<int> edge_map,
|
||||
Span<int> masked_poly_indices,
|
||||
Span<int> new_loop_starts)
|
||||
{
|
||||
for (const int i_dst : masked_poly_indices.index_range()) {
|
||||
const int i_src = masked_poly_indices[i_dst];
|
||||
|
|
|
@ -1,288 +0,0 @@
|
|||
#include "BLI_array_ref.hh"
|
||||
#include "BLI_strict_flags.h"
|
||||
#include "BLI_vector.hh"
|
||||
#include "testing/testing.h"
|
||||
|
||||
using namespace blender;
|
||||
|
||||
using IntVector = blender::Vector<int>;
|
||||
using IntArrayRef = blender::ArrayRef<int>;
|
||||
using MutableIntArrayRef = blender::MutableArrayRef<int>;
|
||||
|
||||
TEST(array_ref, FromSmallVector)
|
||||
{
|
||||
IntVector a = {1, 2, 3};
|
||||
IntArrayRef a_ref = a;
|
||||
EXPECT_EQ(a_ref.size(), 3);
|
||||
EXPECT_EQ(a_ref[0], 1);
|
||||
EXPECT_EQ(a_ref[1], 2);
|
||||
EXPECT_EQ(a_ref[2], 3);
|
||||
}
|
||||
|
||||
TEST(array_ref, AddConstToPointer)
|
||||
{
|
||||
int a = 0;
|
||||
std::vector<int *> vec = {&a};
|
||||
ArrayRef<int *> ref = vec;
|
||||
ArrayRef<const int *> const_ref = ref;
|
||||
EXPECT_EQ(const_ref.size(), 1);
|
||||
}
|
||||
|
||||
TEST(array_ref, IsReferencing)
|
||||
{
|
||||
int array[] = {3, 5, 8};
|
||||
MutableIntArrayRef ref(array, ARRAY_SIZE(array));
|
||||
EXPECT_EQ(ref.size(), 3);
|
||||
EXPECT_EQ(ref[1], 5);
|
||||
array[1] = 10;
|
||||
EXPECT_EQ(ref[1], 10);
|
||||
}
|
||||
|
||||
TEST(array_ref, DropBack)
|
||||
{
|
||||
IntVector a = {4, 5, 6, 7};
|
||||
auto slice = IntArrayRef(a).drop_back(2);
|
||||
EXPECT_EQ(slice.size(), 2);
|
||||
EXPECT_EQ(slice[0], 4);
|
||||
EXPECT_EQ(slice[1], 5);
|
||||
}
|
||||
|
||||
TEST(array_ref, DropBackAll)
|
||||
{
|
||||
IntVector a = {4, 5, 6, 7};
|
||||
auto slice = IntArrayRef(a).drop_back(a.size());
|
||||
EXPECT_EQ(slice.size(), 0);
|
||||
}
|
||||
|
||||
TEST(array_ref, DropFront)
|
||||
{
|
||||
IntVector a = {4, 5, 6, 7};
|
||||
auto slice = IntArrayRef(a).drop_front(1);
|
||||
EXPECT_EQ(slice.size(), 3);
|
||||
EXPECT_EQ(slice[0], 5);
|
||||
EXPECT_EQ(slice[1], 6);
|
||||
EXPECT_EQ(slice[2], 7);
|
||||
}
|
||||
|
||||
TEST(array_ref, DropFrontAll)
|
||||
{
|
||||
IntVector a = {4, 5, 6, 7};
|
||||
auto slice = IntArrayRef(a).drop_front(a.size());
|
||||
EXPECT_EQ(slice.size(), 0);
|
||||
}
|
||||
|
||||
TEST(array_ref, TakeFront)
|
||||
{
|
||||
IntVector a = {4, 5, 6, 7};
|
||||
auto slice = IntArrayRef(a).take_front(2);
|
||||
EXPECT_EQ(slice.size(), 2);
|
||||
EXPECT_EQ(slice[0], 4);
|
||||
EXPECT_EQ(slice[1], 5);
|
||||
}
|
||||
|
||||
TEST(array_ref, TakeBack)
|
||||
{
|
||||
IntVector a = {5, 6, 7, 8};
|
||||
auto slice = IntArrayRef(a).take_back(2);
|
||||
EXPECT_EQ(slice.size(), 2);
|
||||
EXPECT_EQ(slice[0], 7);
|
||||
EXPECT_EQ(slice[1], 8);
|
||||
}
|
||||
|
||||
TEST(array_ref, Slice)
|
||||
{
|
||||
IntVector a = {4, 5, 6, 7};
|
||||
auto slice = IntArrayRef(a).slice(1, 2);
|
||||
EXPECT_EQ(slice.size(), 2);
|
||||
EXPECT_EQ(slice[0], 5);
|
||||
EXPECT_EQ(slice[1], 6);
|
||||
}
|
||||
|
||||
TEST(array_ref, SliceEmpty)
|
||||
{
|
||||
IntVector a = {4, 5, 6, 7};
|
||||
auto slice = IntArrayRef(a).slice(2, 0);
|
||||
EXPECT_EQ(slice.size(), 0);
|
||||
}
|
||||
|
||||
TEST(array_ref, SliceRange)
|
||||
{
|
||||
IntVector a = {1, 2, 3, 4, 5};
|
||||
auto slice = IntArrayRef(a).slice(IndexRange(2, 2));
|
||||
EXPECT_EQ(slice.size(), 2);
|
||||
EXPECT_EQ(slice[0], 3);
|
||||
EXPECT_EQ(slice[1], 4);
|
||||
}
|
||||
|
||||
TEST(array_ref, Contains)
|
||||
{
|
||||
IntVector a = {4, 5, 6, 7};
|
||||
IntArrayRef a_ref = a;
|
||||
EXPECT_TRUE(a_ref.contains(4));
|
||||
EXPECT_TRUE(a_ref.contains(5));
|
||||
EXPECT_TRUE(a_ref.contains(6));
|
||||
EXPECT_TRUE(a_ref.contains(7));
|
||||
EXPECT_FALSE(a_ref.contains(3));
|
||||
EXPECT_FALSE(a_ref.contains(8));
|
||||
}
|
||||
|
||||
TEST(array_ref, Count)
|
||||
{
|
||||
IntVector a = {2, 3, 4, 3, 3, 2, 2, 2, 2};
|
||||
IntArrayRef a_ref = a;
|
||||
EXPECT_EQ(a_ref.count(1), 0);
|
||||
EXPECT_EQ(a_ref.count(2), 5);
|
||||
EXPECT_EQ(a_ref.count(3), 3);
|
||||
EXPECT_EQ(a_ref.count(4), 1);
|
||||
EXPECT_EQ(a_ref.count(5), 0);
|
||||
}
|
||||
|
||||
static void test_ref_from_initializer_list(IntArrayRef ref)
|
||||
{
|
||||
EXPECT_EQ(ref.size(), 4);
|
||||
EXPECT_EQ(ref[0], 3);
|
||||
EXPECT_EQ(ref[1], 6);
|
||||
EXPECT_EQ(ref[2], 8);
|
||||
EXPECT_EQ(ref[3], 9);
|
||||
}
|
||||
|
||||
TEST(array_ref, FromInitializerList)
|
||||
{
|
||||
test_ref_from_initializer_list({3, 6, 8, 9});
|
||||
}
|
||||
|
||||
TEST(array_ref, FromVector)
|
||||
{
|
||||
std::vector<int> a = {1, 2, 3, 4};
|
||||
IntArrayRef a_ref(a);
|
||||
EXPECT_EQ(a_ref.size(), 4);
|
||||
EXPECT_EQ(a_ref[0], 1);
|
||||
EXPECT_EQ(a_ref[1], 2);
|
||||
EXPECT_EQ(a_ref[2], 3);
|
||||
EXPECT_EQ(a_ref[3], 4);
|
||||
}
|
||||
|
||||
TEST(array_ref, FromArray)
|
||||
{
|
||||
std::array<int, 2> a = {5, 6};
|
||||
IntArrayRef a_ref(a);
|
||||
EXPECT_EQ(a_ref.size(), 2);
|
||||
EXPECT_EQ(a_ref[0], 5);
|
||||
EXPECT_EQ(a_ref[1], 6);
|
||||
}
|
||||
|
||||
TEST(array_ref, Fill)
|
||||
{
|
||||
std::array<int, 5> a = {4, 5, 6, 7, 8};
|
||||
MutableIntArrayRef a_ref(a);
|
||||
a_ref.fill(1);
|
||||
EXPECT_EQ(a[0], 1);
|
||||
EXPECT_EQ(a[1], 1);
|
||||
EXPECT_EQ(a[2], 1);
|
||||
EXPECT_EQ(a[3], 1);
|
||||
EXPECT_EQ(a[4], 1);
|
||||
}
|
||||
|
||||
TEST(array_ref, FillIndices)
|
||||
{
|
||||
std::array<int, 5> a = {0, 0, 0, 0, 0};
|
||||
MutableIntArrayRef a_ref(a);
|
||||
a_ref.fill_indices({0, 2, 3}, 1);
|
||||
EXPECT_EQ(a[0], 1);
|
||||
EXPECT_EQ(a[1], 0);
|
||||
EXPECT_EQ(a[2], 1);
|
||||
EXPECT_EQ(a[3], 1);
|
||||
EXPECT_EQ(a[4], 0);
|
||||
}
|
||||
|
||||
TEST(array_ref, SizeInBytes)
|
||||
{
|
||||
std::array<int, 10> a;
|
||||
IntArrayRef a_ref(a);
|
||||
EXPECT_EQ(a_ref.size_in_bytes(), sizeof(a));
|
||||
EXPECT_EQ(a_ref.size_in_bytes(), 40);
|
||||
}
|
||||
|
||||
TEST(array_ref, FirstLast)
|
||||
{
|
||||
std::array<int, 4> a = {6, 7, 8, 9};
|
||||
IntArrayRef a_ref(a);
|
||||
EXPECT_EQ(a_ref.first(), 6);
|
||||
EXPECT_EQ(a_ref.last(), 9);
|
||||
}
|
||||
|
||||
TEST(array_ref, FirstLast_OneElement)
|
||||
{
|
||||
int a = 3;
|
||||
IntArrayRef a_ref(&a, 1);
|
||||
EXPECT_EQ(a_ref.first(), 3);
|
||||
EXPECT_EQ(a_ref.last(), 3);
|
||||
}
|
||||
|
||||
TEST(array_ref, Get)
|
||||
{
|
||||
std::array<int, 3> a = {5, 6, 7};
|
||||
IntArrayRef a_ref(a);
|
||||
EXPECT_EQ(a_ref.get(0, 42), 5);
|
||||
EXPECT_EQ(a_ref.get(1, 42), 6);
|
||||
EXPECT_EQ(a_ref.get(2, 42), 7);
|
||||
EXPECT_EQ(a_ref.get(3, 42), 42);
|
||||
EXPECT_EQ(a_ref.get(4, 42), 42);
|
||||
}
|
||||
|
||||
TEST(array_ref, ContainsPtr)
|
||||
{
|
||||
std::array<int, 3> a = {5, 6, 7};
|
||||
int other = 10;
|
||||
IntArrayRef a_ref(a);
|
||||
EXPECT_TRUE(a_ref.contains_ptr(&a[0] + 0));
|
||||
EXPECT_TRUE(a_ref.contains_ptr(&a[0] + 1));
|
||||
EXPECT_TRUE(a_ref.contains_ptr(&a[0] + 2));
|
||||
EXPECT_FALSE(a_ref.contains_ptr(&a[0] + 3));
|
||||
EXPECT_FALSE(a_ref.contains_ptr(&a[0] - 1));
|
||||
EXPECT_FALSE(a_ref.contains_ptr(&other));
|
||||
}
|
||||
|
||||
TEST(array_ref, FirstIndex)
|
||||
{
|
||||
std::array<int, 5> a = {4, 5, 4, 2, 5};
|
||||
IntArrayRef a_ref(a);
|
||||
|
||||
EXPECT_EQ(a_ref.first_index(4), 0);
|
||||
EXPECT_EQ(a_ref.first_index(5), 1);
|
||||
EXPECT_EQ(a_ref.first_index(2), 3);
|
||||
}
|
||||
|
||||
TEST(array_ref, CastSameSize)
|
||||
{
|
||||
int value = 0;
|
||||
std::array<int *, 4> a = {&value, nullptr, nullptr, nullptr};
|
||||
ArrayRef<int *> a_ref = a;
|
||||
ArrayRef<float *> new_a_ref = a_ref.cast<float *>();
|
||||
|
||||
EXPECT_EQ(a_ref.size(), 4);
|
||||
EXPECT_EQ(new_a_ref.size(), 4);
|
||||
|
||||
EXPECT_EQ(a_ref[0], &value);
|
||||
EXPECT_EQ(new_a_ref[0], (float *)&value);
|
||||
}
|
||||
|
||||
TEST(array_ref, CastSmallerSize)
|
||||
{
|
||||
std::array<uint32_t, 4> a = {3, 4, 5, 6};
|
||||
ArrayRef<uint32_t> a_ref = a;
|
||||
ArrayRef<uint16_t> new_a_ref = a_ref.cast<uint16_t>();
|
||||
|
||||
EXPECT_EQ(a_ref.size(), 4);
|
||||
EXPECT_EQ(new_a_ref.size(), 8);
|
||||
}
|
||||
|
||||
TEST(array_ref, CastLargerSize)
|
||||
{
|
||||
std::array<uint16_t, 4> a = {4, 5, 6, 7};
|
||||
ArrayRef<uint16_t> a_ref = a;
|
||||
ArrayRef<uint32_t> new_a_ref = a_ref.cast<uint32_t>();
|
||||
|
||||
EXPECT_EQ(a_ref.size(), 4);
|
||||
EXPECT_EQ(new_a_ref.size(), 2);
|
||||
}
|
|
@ -39,11 +39,11 @@ TEST(array, InitializerListConstructor)
|
|||
EXPECT_EQ(array[3], 7);
|
||||
}
|
||||
|
||||
TEST(array, ArrayRefConstructor)
|
||||
TEST(array, SpanConstructor)
|
||||
{
|
||||
int stackarray[4] = {6, 7, 8, 9};
|
||||
ArrayRef<int> array_ref(stackarray, ARRAY_SIZE(stackarray));
|
||||
Array<int> array(array_ref);
|
||||
Span<int> span(stackarray, ARRAY_SIZE(stackarray));
|
||||
Array<int> array(span);
|
||||
EXPECT_EQ(array.size(), 4);
|
||||
EXPECT_EQ(array[0], 6);
|
||||
EXPECT_EQ(array[1], 7);
|
||||
|
|
|
@ -32,7 +32,7 @@ TEST(index_mask, RangeConstructor)
|
|||
EXPECT_TRUE(mask.is_range());
|
||||
EXPECT_EQ(mask.as_range().first(), 3);
|
||||
EXPECT_EQ(mask.as_range().last(), 7);
|
||||
ArrayRef<uint> indices = mask.indices();
|
||||
Span<uint> indices = mask.indices();
|
||||
EXPECT_EQ(indices[0], 3);
|
||||
EXPECT_EQ(indices[1], 4);
|
||||
EXPECT_EQ(indices[2], 5);
|
||||
|
|
|
@ -127,13 +127,13 @@ TEST(index_range, SliceRange)
|
|||
EXPECT_EQ(slice.last(), 12);
|
||||
}
|
||||
|
||||
TEST(index_range, AsArrayRef)
|
||||
TEST(index_range, AsSpan)
|
||||
{
|
||||
IndexRange range = IndexRange(4, 6);
|
||||
ArrayRef<uint> ref = range.as_array_ref();
|
||||
EXPECT_EQ(ref.size(), 6);
|
||||
EXPECT_EQ(ref[0], 4);
|
||||
EXPECT_EQ(ref[1], 5);
|
||||
EXPECT_EQ(ref[2], 6);
|
||||
EXPECT_EQ(ref[3], 7);
|
||||
Span<uint> span = range.as_span();
|
||||
EXPECT_EQ(span.size(), 6);
|
||||
EXPECT_EQ(span[0], 4);
|
||||
EXPECT_EQ(span[1], 5);
|
||||
EXPECT_EQ(span[2], 6);
|
||||
EXPECT_EQ(span[3], 7);
|
||||
}
|
||||
|
|
|
@ -67,8 +67,8 @@ TEST(linear_allocator, AllocateArray)
|
|||
{
|
||||
LinearAllocator<> allocator;
|
||||
|
||||
MutableArrayRef<int> array = allocator.allocate_array<int>(5);
|
||||
EXPECT_EQ(array.size(), 5);
|
||||
MutableSpan<int> span = allocator.allocate_array<int>(5);
|
||||
EXPECT_EQ(span.size(), 5);
|
||||
}
|
||||
|
||||
TEST(linear_allocator, Construct)
|
||||
|
@ -87,7 +87,7 @@ TEST(linear_allocator, ConstructElementsAndPointerArray)
|
|||
LinearAllocator<> allocator;
|
||||
|
||||
std::array<int, 7> values = {1, 2, 3, 4, 5, 6, 7};
|
||||
ArrayRef<Vector<int> *> vectors = allocator.construct_elements_and_pointer_array<Vector<int>>(
|
||||
Span<Vector<int> *> vectors = allocator.construct_elements_and_pointer_array<Vector<int>>(
|
||||
5, values);
|
||||
|
||||
EXPECT_EQ(vectors.size(), 5);
|
||||
|
@ -104,11 +104,11 @@ TEST(linear_allocator, ConstructArrayCopy)
|
|||
LinearAllocator<> allocator;
|
||||
|
||||
Vector<int> values = {1, 2, 3};
|
||||
MutableArrayRef<int> array1 = allocator.construct_array_copy(values.as_ref());
|
||||
MutableArrayRef<int> array2 = allocator.construct_array_copy(values.as_ref());
|
||||
EXPECT_NE(array1.data(), array2.data());
|
||||
EXPECT_EQ(array1.size(), 3);
|
||||
EXPECT_EQ(array2.size(), 3);
|
||||
EXPECT_EQ(array1[1], 2);
|
||||
EXPECT_EQ(array2[2], 3);
|
||||
MutableSpan<int> span1 = allocator.construct_array_copy(values.as_span());
|
||||
MutableSpan<int> span2 = allocator.construct_array_copy(values.as_span());
|
||||
EXPECT_NE(span1.data(), span2.data());
|
||||
EXPECT_EQ(span1.size(), 3);
|
||||
EXPECT_EQ(span2.size(), 3);
|
||||
EXPECT_EQ(span1[1], 2);
|
||||
EXPECT_EQ(span2[2], 3);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,284 @@
|
|||
#include "BLI_span.hh"
|
||||
#include "BLI_strict_flags.h"
|
||||
#include "BLI_vector.hh"
|
||||
#include "testing/testing.h"
|
||||
|
||||
using namespace blender;
|
||||
|
||||
TEST(array_ref, FromSmallVector)
|
||||
{
|
||||
Vector<int> a = {1, 2, 3};
|
||||
Span<int> a_span = a;
|
||||
EXPECT_EQ(a_span.size(), 3);
|
||||
EXPECT_EQ(a_span[0], 1);
|
||||
EXPECT_EQ(a_span[1], 2);
|
||||
EXPECT_EQ(a_span[2], 3);
|
||||
}
|
||||
|
||||
TEST(array_ref, AddConstToPointer)
|
||||
{
|
||||
int a = 0;
|
||||
std::vector<int *> vec = {&a};
|
||||
Span<int *> span = vec;
|
||||
Span<const int *> const_span = span;
|
||||
EXPECT_EQ(const_span.size(), 1);
|
||||
}
|
||||
|
||||
TEST(array_ref, IsReferencing)
|
||||
{
|
||||
int array[] = {3, 5, 8};
|
||||
MutableSpan<int> span(array, ARRAY_SIZE(array));
|
||||
EXPECT_EQ(span.size(), 3);
|
||||
EXPECT_EQ(span[1], 5);
|
||||
array[1] = 10;
|
||||
EXPECT_EQ(span[1], 10);
|
||||
}
|
||||
|
||||
TEST(array_ref, DropBack)
|
||||
{
|
||||
Vector<int> a = {4, 5, 6, 7};
|
||||
auto slice = Span<int>(a).drop_back(2);
|
||||
EXPECT_EQ(slice.size(), 2);
|
||||
EXPECT_EQ(slice[0], 4);
|
||||
EXPECT_EQ(slice[1], 5);
|
||||
}
|
||||
|
||||
TEST(array_ref, DropBackAll)
|
||||
{
|
||||
Vector<int> a = {4, 5, 6, 7};
|
||||
auto slice = Span<int>(a).drop_back(a.size());
|
||||
EXPECT_EQ(slice.size(), 0);
|
||||
}
|
||||
|
||||
TEST(array_ref, DropFront)
|
||||
{
|
||||
Vector<int> a = {4, 5, 6, 7};
|
||||
auto slice = Span<int>(a).drop_front(1);
|
||||
EXPECT_EQ(slice.size(), 3);
|
||||
EXPECT_EQ(slice[0], 5);
|
||||
EXPECT_EQ(slice[1], 6);
|
||||
EXPECT_EQ(slice[2], 7);
|
||||
}
|
||||
|
||||
TEST(array_ref, DropFrontAll)
|
||||
{
|
||||
Vector<int> a = {4, 5, 6, 7};
|
||||
auto slice = Span<int>(a).drop_front(a.size());
|
||||
EXPECT_EQ(slice.size(), 0);
|
||||
}
|
||||
|
||||
TEST(array_ref, TakeFront)
|
||||
{
|
||||
Vector<int> a = {4, 5, 6, 7};
|
||||
auto slice = Span<int>(a).take_front(2);
|
||||
EXPECT_EQ(slice.size(), 2);
|
||||
EXPECT_EQ(slice[0], 4);
|
||||
EXPECT_EQ(slice[1], 5);
|
||||
}
|
||||
|
||||
TEST(array_ref, TakeBack)
|
||||
{
|
||||
Vector<int> a = {5, 6, 7, 8};
|
||||
auto slice = Span<int>(a).take_back(2);
|
||||
EXPECT_EQ(slice.size(), 2);
|
||||
EXPECT_EQ(slice[0], 7);
|
||||
EXPECT_EQ(slice[1], 8);
|
||||
}
|
||||
|
||||
TEST(array_ref, Slice)
|
||||
{
|
||||
Vector<int> a = {4, 5, 6, 7};
|
||||
auto slice = Span<int>(a).slice(1, 2);
|
||||
EXPECT_EQ(slice.size(), 2);
|
||||
EXPECT_EQ(slice[0], 5);
|
||||
EXPECT_EQ(slice[1], 6);
|
||||
}
|
||||
|
||||
TEST(array_ref, SliceEmpty)
|
||||
{
|
||||
Vector<int> a = {4, 5, 6, 7};
|
||||
auto slice = Span<int>(a).slice(2, 0);
|
||||
EXPECT_EQ(slice.size(), 0);
|
||||
}
|
||||
|
||||
TEST(array_ref, SliceRange)
|
||||
{
|
||||
Vector<int> a = {1, 2, 3, 4, 5};
|
||||
auto slice = Span<int>(a).slice(IndexRange(2, 2));
|
||||
EXPECT_EQ(slice.size(), 2);
|
||||
EXPECT_EQ(slice[0], 3);
|
||||
EXPECT_EQ(slice[1], 4);
|
||||
}
|
||||
|
||||
TEST(array_ref, Contains)
|
||||
{
|
||||
Vector<int> a = {4, 5, 6, 7};
|
||||
Span<int> a_span = a;
|
||||
EXPECT_TRUE(a_span.contains(4));
|
||||
EXPECT_TRUE(a_span.contains(5));
|
||||
EXPECT_TRUE(a_span.contains(6));
|
||||
EXPECT_TRUE(a_span.contains(7));
|
||||
EXPECT_FALSE(a_span.contains(3));
|
||||
EXPECT_FALSE(a_span.contains(8));
|
||||
}
|
||||
|
||||
TEST(array_ref, Count)
|
||||
{
|
||||
Vector<int> a = {2, 3, 4, 3, 3, 2, 2, 2, 2};
|
||||
Span<int> a_span = a;
|
||||
EXPECT_EQ(a_span.count(1), 0);
|
||||
EXPECT_EQ(a_span.count(2), 5);
|
||||
EXPECT_EQ(a_span.count(3), 3);
|
||||
EXPECT_EQ(a_span.count(4), 1);
|
||||
EXPECT_EQ(a_span.count(5), 0);
|
||||
}
|
||||
|
||||
static void test_ref_from_initializer_list(Span<int> span)
|
||||
{
|
||||
EXPECT_EQ(span.size(), 4);
|
||||
EXPECT_EQ(span[0], 3);
|
||||
EXPECT_EQ(span[1], 6);
|
||||
EXPECT_EQ(span[2], 8);
|
||||
EXPECT_EQ(span[3], 9);
|
||||
}
|
||||
|
||||
TEST(array_ref, FromInitializerList)
|
||||
{
|
||||
test_ref_from_initializer_list({3, 6, 8, 9});
|
||||
}
|
||||
|
||||
TEST(array_ref, FromVector)
|
||||
{
|
||||
std::vector<int> a = {1, 2, 3, 4};
|
||||
Span<int> a_span(a);
|
||||
EXPECT_EQ(a_span.size(), 4);
|
||||
EXPECT_EQ(a_span[0], 1);
|
||||
EXPECT_EQ(a_span[1], 2);
|
||||
EXPECT_EQ(a_span[2], 3);
|
||||
EXPECT_EQ(a_span[3], 4);
|
||||
}
|
||||
|
||||
TEST(array_ref, FromArray)
|
||||
{
|
||||
std::array<int, 2> a = {5, 6};
|
||||
Span<int> a_span(a);
|
||||
EXPECT_EQ(a_span.size(), 2);
|
||||
EXPECT_EQ(a_span[0], 5);
|
||||
EXPECT_EQ(a_span[1], 6);
|
||||
}
|
||||
|
||||
TEST(array_ref, Fill)
|
||||
{
|
||||
std::array<int, 5> a = {4, 5, 6, 7, 8};
|
||||
MutableSpan<int> a_span(a);
|
||||
a_span.fill(1);
|
||||
EXPECT_EQ(a[0], 1);
|
||||
EXPECT_EQ(a[1], 1);
|
||||
EXPECT_EQ(a[2], 1);
|
||||
EXPECT_EQ(a[3], 1);
|
||||
EXPECT_EQ(a[4], 1);
|
||||
}
|
||||
|
||||
TEST(array_ref, FillIndices)
|
||||
{
|
||||
std::array<int, 5> a = {0, 0, 0, 0, 0};
|
||||
MutableSpan<int> a_span(a);
|
||||
a_span.fill_indices({0, 2, 3}, 1);
|
||||
EXPECT_EQ(a[0], 1);
|
||||
EXPECT_EQ(a[1], 0);
|
||||
EXPECT_EQ(a[2], 1);
|
||||
EXPECT_EQ(a[3], 1);
|
||||
EXPECT_EQ(a[4], 0);
|
||||
}
|
||||
|
||||
TEST(array_ref, SizeInBytes)
|
||||
{
|
||||
std::array<int, 10> a;
|
||||
Span<int> a_span(a);
|
||||
EXPECT_EQ(a_span.size_in_bytes(), sizeof(a));
|
||||
EXPECT_EQ(a_span.size_in_bytes(), 40);
|
||||
}
|
||||
|
||||
TEST(array_ref, FirstLast)
|
||||
{
|
||||
std::array<int, 4> a = {6, 7, 8, 9};
|
||||
Span<int> a_span(a);
|
||||
EXPECT_EQ(a_span.first(), 6);
|
||||
EXPECT_EQ(a_span.last(), 9);
|
||||
}
|
||||
|
||||
TEST(array_ref, FirstLast_OneElement)
|
||||
{
|
||||
int a = 3;
|
||||
Span<int> a_span(&a, 1);
|
||||
EXPECT_EQ(a_span.first(), 3);
|
||||
EXPECT_EQ(a_span.last(), 3);
|
||||
}
|
||||
|
||||
TEST(array_ref, Get)
|
||||
{
|
||||
std::array<int, 3> a = {5, 6, 7};
|
||||
Span<int> a_span(a);
|
||||
EXPECT_EQ(a_span.get(0, 42), 5);
|
||||
EXPECT_EQ(a_span.get(1, 42), 6);
|
||||
EXPECT_EQ(a_span.get(2, 42), 7);
|
||||
EXPECT_EQ(a_span.get(3, 42), 42);
|
||||
EXPECT_EQ(a_span.get(4, 42), 42);
|
||||
}
|
||||
|
||||
TEST(array_ref, ContainsPtr)
|
||||
{
|
||||
std::array<int, 3> a = {5, 6, 7};
|
||||
int other = 10;
|
||||
Span<int> a_span(a);
|
||||
EXPECT_TRUE(a_span.contains_ptr(&a[0] + 0));
|
||||
EXPECT_TRUE(a_span.contains_ptr(&a[0] + 1));
|
||||
EXPECT_TRUE(a_span.contains_ptr(&a[0] + 2));
|
||||
EXPECT_FALSE(a_span.contains_ptr(&a[0] + 3));
|
||||
EXPECT_FALSE(a_span.contains_ptr(&a[0] - 1));
|
||||
EXPECT_FALSE(a_span.contains_ptr(&other));
|
||||
}
|
||||
|
||||
TEST(array_ref, FirstIndex)
|
||||
{
|
||||
std::array<int, 5> a = {4, 5, 4, 2, 5};
|
||||
Span<int> a_span(a);
|
||||
|
||||
EXPECT_EQ(a_span.first_index(4), 0);
|
||||
EXPECT_EQ(a_span.first_index(5), 1);
|
||||
EXPECT_EQ(a_span.first_index(2), 3);
|
||||
}
|
||||
|
||||
TEST(array_ref, CastSameSize)
|
||||
{
|
||||
int value = 0;
|
||||
std::array<int *, 4> a = {&value, nullptr, nullptr, nullptr};
|
||||
Span<int *> a_span = a;
|
||||
Span<float *> new_a_span = a_span.cast<float *>();
|
||||
|
||||
EXPECT_EQ(a_span.size(), 4);
|
||||
EXPECT_EQ(new_a_span.size(), 4);
|
||||
|
||||
EXPECT_EQ(a_span[0], &value);
|
||||
EXPECT_EQ(new_a_span[0], (float *)&value);
|
||||
}
|
||||
|
||||
TEST(array_ref, CastSmallerSize)
|
||||
{
|
||||
std::array<uint32_t, 4> a = {3, 4, 5, 6};
|
||||
Span<uint32_t> a_span = a;
|
||||
Span<uint16_t> new_a_span = a_span.cast<uint16_t>();
|
||||
|
||||
EXPECT_EQ(a_span.size(), 4);
|
||||
EXPECT_EQ(new_a_span.size(), 8);
|
||||
}
|
||||
|
||||
TEST(array_ref, CastLargerSize)
|
||||
{
|
||||
std::array<uint16_t, 4> a = {4, 5, 6, 7};
|
||||
Span<uint16_t> a_span = a;
|
||||
Span<uint32_t> new_a_span = a_span.cast<uint32_t>();
|
||||
|
||||
EXPECT_EQ(a_span.size(), 4);
|
||||
EXPECT_EQ(new_a_span.size(), 2);
|
||||
}
|
|
@ -12,7 +12,7 @@ TEST(stack, DefaultConstructor)
|
|||
EXPECT_TRUE(stack.is_empty());
|
||||
}
|
||||
|
||||
TEST(stack, ArrayRefConstructor)
|
||||
TEST(stack, SpanConstructor)
|
||||
{
|
||||
std::array<int, 3> array = {4, 7, 2};
|
||||
Stack<int> stack(array);
|
||||
|
|
|
@ -408,17 +408,17 @@ TEST(vector, Remove)
|
|||
{
|
||||
Vector<int> vec = {1, 2, 3, 4, 5, 6};
|
||||
vec.remove(3);
|
||||
EXPECT_TRUE(std::equal(vec.begin(), vec.end(), ArrayRef<int>({1, 2, 3, 5, 6}).begin()));
|
||||
EXPECT_TRUE(std::equal(vec.begin(), vec.end(), Span<int>({1, 2, 3, 5, 6}).begin()));
|
||||
vec.remove(0);
|
||||
EXPECT_TRUE(std::equal(vec.begin(), vec.end(), ArrayRef<int>({2, 3, 5, 6}).begin()));
|
||||
EXPECT_TRUE(std::equal(vec.begin(), vec.end(), Span<int>({2, 3, 5, 6}).begin()));
|
||||
vec.remove(3);
|
||||
EXPECT_TRUE(std::equal(vec.begin(), vec.end(), ArrayRef<int>({2, 3, 5}).begin()));
|
||||
EXPECT_TRUE(std::equal(vec.begin(), vec.end(), Span<int>({2, 3, 5}).begin()));
|
||||
vec.remove(1);
|
||||
EXPECT_TRUE(std::equal(vec.begin(), vec.end(), ArrayRef<int>({2, 5}).begin()));
|
||||
EXPECT_TRUE(std::equal(vec.begin(), vec.end(), Span<int>({2, 5}).begin()));
|
||||
vec.remove(1);
|
||||
EXPECT_TRUE(std::equal(vec.begin(), vec.end(), ArrayRef<int>({2}).begin()));
|
||||
EXPECT_TRUE(std::equal(vec.begin(), vec.end(), Span<int>({2}).begin()));
|
||||
vec.remove(0);
|
||||
EXPECT_TRUE(std::equal(vec.begin(), vec.end(), ArrayRef<int>({}).begin()));
|
||||
EXPECT_TRUE(std::equal(vec.begin(), vec.end(), Span<int>({}).begin()));
|
||||
}
|
||||
|
||||
TEST(vector, ExtendSmallVector)
|
||||
|
|
|
@ -40,7 +40,6 @@ else()
|
|||
endif()
|
||||
|
||||
BLENDER_TEST(BLI_array "bf_blenlib")
|
||||
BLENDER_TEST(BLI_array_ref "bf_blenlib")
|
||||
BLENDER_TEST(BLI_array_store "bf_blenlib")
|
||||
BLENDER_TEST(BLI_array_utils "bf_blenlib")
|
||||
BLENDER_TEST(BLI_delaunay_2d "bf_blenlib")
|
||||
|
@ -67,6 +66,7 @@ BLENDER_TEST(BLI_optional "bf_blenlib")
|
|||
BLENDER_TEST(BLI_path_util "${BLI_path_util_extra_libs}")
|
||||
BLENDER_TEST(BLI_polyfill_2d "bf_blenlib")
|
||||
BLENDER_TEST(BLI_set "bf_blenlib")
|
||||
BLENDER_TEST(BLI_span "bf_blenlib")
|
||||
BLENDER_TEST(BLI_stack "bf_blenlib")
|
||||
BLENDER_TEST(BLI_stack_cxx "bf_blenlib")
|
||||
BLENDER_TEST(BLI_string "bf_blenlib")
|
||||
|
|
Loading…
Reference in New Issue