Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClément Foucault <foucault.clem@gmail.com>2020-02-11 16:57:41 +0300
committerClément Foucault <foucault.clem@gmail.com>2020-02-11 16:57:41 +0300
commit30f65b54a78edc2a974ba93fefa86534fe2b7ff4 (patch)
tree030cf43b7c2cbd649a2e8758bf319a5b76a29aef /source/blender/blenlib/BLI_array_ref.h
parent9052c6fafa87654c9a45ce0d5b9ecee073ec1a5b (diff)
parent3657bb514130ce2d28c407432d6f10202a68c92a (diff)
Merge branch 'master' into draw-colormanagementdraw-colormanagement
Diffstat (limited to 'source/blender/blenlib/BLI_array_ref.h')
-rw-r--r--source/blender/blenlib/BLI_array_ref.h129
1 files changed, 124 insertions, 5 deletions
diff --git a/source/blender/blenlib/BLI_array_ref.h b/source/blender/blenlib/BLI_array_ref.h
index e34647676d8..6cc96cedc83 100644
--- a/source/blender/blenlib/BLI_array_ref.h
+++ b/source/blender/blenlib/BLI_array_ref.h
@@ -79,6 +79,16 @@ template<typename T> class ArrayRef {
}
/**
+ * ArrayRef<T *> -> ArrayRef<const T *>
+ * ArrayRef<Derived *> -> ArrayRef<Base *>
+ */
+ template<typename U,
+ typename std::enable_if<std::is_convertible<U *, T>::value>::type * = nullptr>
+ ArrayRef(ArrayRef<U *> array) : ArrayRef((T *)array.begin(), array.size())
+ {
+ }
+
+ /**
* Return a continuous part of the array.
* Asserts that the slice stays within the array.
*/
@@ -247,14 +257,85 @@ template<typename T> class ArrayRef {
}
/**
+ * Check if the array contains duplicates. Does a linear search for every element. So the total
+ * running time is O(n^2). Only use this for small arrays.
+ */
+ bool has_duplicates__linear_search() const
+ {
+ /* The size should really be smaller than that. If it is not, the calling code should be
+ * changed. */
+ BLI_assert(m_size < 1000);
+
+ for (uint i = 0; i < m_size; i++) {
+ const T &value = m_start[i];
+ for (uint j = i + 1; j < m_size; j++) {
+ if (value == m_start[j]) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ bool intersects__linear_search(ArrayRef other) const
+ {
+ /* The size should really be smaller than that. If it is not, the calling code should be
+ * changed. */
+ BLI_assert(m_size < 1000);
+
+ for (uint i = 0; i < m_size; i++) {
+ const T &value = m_start[i];
+ if (other.contains(value)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ uint first_index(const T &search_value) const
+ {
+ int index = this->first_index_try(search_value);
+ BLI_assert(index >= 0);
+ return (uint)index;
+ }
+
+ int first_index_try(const T &search_value) const
+ {
+ for (uint i = 0; i < m_size; i++) {
+ if (m_start[i] == search_value) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ template<typename PredicateT> bool any(const PredicateT predicate)
+ {
+ for (uint i = 0; i < m_size; i++) {
+ if (predicate(m_start[i])) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Utility to make it more convenient to iterate over all indices that can be used with this
+ * array.
+ */
+ IndexRange index_range() const
+ {
+ return IndexRange(m_size);
+ }
+
+ /**
* Get a new array ref to the same underlying memory buffer. No conversions are done.
- * Asserts when the sizes of the types don't match.
*/
template<typename NewT> ArrayRef<NewT> cast() const
{
- /* Can be adjusted to allow different type sizes when necessary. */
- BLI_STATIC_ASSERT(sizeof(T) == sizeof(NewT), "");
- return ArrayRef<NewT>((NewT *)m_start, m_size);
+ 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);
}
/**
@@ -270,6 +351,11 @@ template<typename T> class ArrayRef {
std::cout << '\n';
}
}
+
+ void print_as_lines(std::string name) const
+ {
+ this->print_as_lines(name, [](const T &value) { std::cout << value; });
+ }
};
/**
@@ -300,7 +386,7 @@ template<typename T> class MutableArrayRef {
{
}
- operator ArrayRef<T>()
+ operator ArrayRef<T>() const
{
return ArrayRef<T>(m_start, m_size);
}
@@ -411,6 +497,17 @@ template<typename T> class MutableArrayRef {
{
return ArrayRef<T>(m_start, m_size);
}
+
+ IndexRange index_range() const
+ {
+ return IndexRange(m_size);
+ }
+
+ const T &last() const
+ {
+ BLI_assert(m_size > 0);
+ return m_start[m_size - 1];
+ }
};
/**
@@ -421,6 +518,28 @@ template<typename T> ArrayRef<T> ref_c_array(const T *array, uint size)
return ArrayRef<T>(array, size);
}
+template<typename T1, typename T2> void assert_same_size(const T1 &v1, const T2 &v2)
+{
+ UNUSED_VARS_NDEBUG(v1, v2);
+#ifdef DEBUG
+ uint size = v1.size();
+ BLI_assert(size == v1.size());
+ BLI_assert(size == v2.size());
+#endif
+}
+
+template<typename T1, typename T2, typename T3>
+void assert_same_size(const T1 &v1, const T2 &v2, const T3 &v3)
+{
+ UNUSED_VARS_NDEBUG(v1, v2, v3);
+#ifdef DEBUG
+ uint size = v1.size();
+ BLI_assert(size == v1.size());
+ BLI_assert(size == v2.size());
+ BLI_assert(size == v3.size());
+#endif
+}
+
} /* namespace BLI */
#endif /* __BLI_ARRAY_REF_H__ */