diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2020-02-11 16:57:41 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2020-02-11 16:57:41 +0300 |
commit | 30f65b54a78edc2a974ba93fefa86534fe2b7ff4 (patch) | |
tree | 030cf43b7c2cbd649a2e8758bf319a5b76a29aef /source/blender/blenlib/BLI_array_ref.h | |
parent | 9052c6fafa87654c9a45ce0d5b9ecee073ec1a5b (diff) | |
parent | 3657bb514130ce2d28c407432d6f10202a68c92a (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.h | 129 |
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__ */ |