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
parent9052c6fafa87654c9a45ce0d5b9ecee073ec1a5b (diff)
parent3657bb514130ce2d28c407432d6f10202a68c92a (diff)
Merge branch 'master' into draw-colormanagementdraw-colormanagement
Diffstat (limited to 'source/blender/blenlib')
-rw-r--r--source/blender/blenlib/BLI_allocator.h26
-rw-r--r--source/blender/blenlib/BLI_array_cxx.h73
-rw-r--r--source/blender/blenlib/BLI_array_ref.h129
-rw-r--r--source/blender/blenlib/BLI_hash_cxx.h1
-rw-r--r--source/blender/blenlib/BLI_index_range.h15
-rw-r--r--source/blender/blenlib/BLI_kdtree.h8
-rw-r--r--source/blender/blenlib/BLI_listbase_wrapper.h13
-rw-r--r--source/blender/blenlib/BLI_map.h13
-rw-r--r--source/blender/blenlib/BLI_math_color_blend.h64
-rw-r--r--source/blender/blenlib/BLI_memory_utils_cxx.h37
-rw-r--r--source/blender/blenlib/BLI_open_addressing.h4
-rw-r--r--source/blender/blenlib/BLI_optional.h199
-rw-r--r--source/blender/blenlib/BLI_rand.h2
-rw-r--r--source/blender/blenlib/BLI_stack_cxx.h9
-rw-r--r--source/blender/blenlib/BLI_string_map.h46
-rw-r--r--source/blender/blenlib/BLI_string_ref.h8
-rw-r--r--source/blender/blenlib/BLI_string_utils.h8
-rw-r--r--source/blender/blenlib/BLI_temporary_allocator.h64
-rw-r--r--source/blender/blenlib/BLI_temporary_allocator_cxx.h38
-rw-r--r--source/blender/blenlib/BLI_utility_mixins.h52
-rw-r--r--source/blender/blenlib/BLI_vector.h73
-rw-r--r--source/blender/blenlib/BLI_vector_set.h6
-rw-r--r--source/blender/blenlib/CMakeLists.txt5
-rw-r--r--source/blender/blenlib/intern/BLI_ghash.c10
-rw-r--r--source/blender/blenlib/intern/BLI_index_range.cc4
-rw-r--r--source/blender/blenlib/intern/BLI_temporary_allocator.cc115
-rw-r--r--source/blender/blenlib/intern/delaunay_2d.c3
-rw-r--r--source/blender/blenlib/intern/math_base_inline.c2
-rw-r--r--source/blender/blenlib/intern/math_color_blend_inline.c200
-rw-r--r--source/blender/blenlib/intern/math_geom.c31
-rw-r--r--source/blender/blenlib/intern/math_vector.c34
-rw-r--r--source/blender/blenlib/intern/string_utf8.c2
-rw-r--r--source/blender/blenlib/intern/string_utils.c18
33 files changed, 826 insertions, 486 deletions
diff --git a/source/blender/blenlib/BLI_allocator.h b/source/blender/blenlib/BLI_allocator.h
index 52fa8d2b705..075c181833c 100644
--- a/source/blender/blenlib/BLI_allocator.h
+++ b/source/blender/blenlib/BLI_allocator.h
@@ -30,12 +30,12 @@
*/
#include <stdlib.h>
+#include <algorithm>
#include "MEM_guardedalloc.h"
#include "BLI_utildefines.h"
#include "BLI_math_base.h"
-#include "BLI_temporary_allocator.h"
namespace BLI {
@@ -52,7 +52,6 @@ class GuardedAllocator {
void *allocate_aligned(uint size, uint alignment, const char *name)
{
- alignment = std::max<uint>(alignment, 8);
return MEM_mallocN_aligned(size, alignment, name);
}
@@ -101,29 +100,6 @@ class RawAllocator {
}
};
-/**
- * Use this only under specific circumstances as described in BLI_temporary_allocator.h.
- */
-class TemporaryAllocator {
- public:
- void *allocate(uint size, const char *UNUSED(name))
- {
- return BLI_temporary_allocate(size);
- }
-
- void *allocate_aligned(uint size, uint alignment, const char *UNUSED(name))
- {
- BLI_assert(alignment <= 64);
- UNUSED_VARS_NDEBUG(alignment);
- return BLI_temporary_allocate(size);
- }
-
- void deallocate(void *ptr)
- {
- BLI_temporary_deallocate(ptr);
- }
-};
-
} // namespace BLI
#endif /* __BLI_ALLOCATOR_H__ */
diff --git a/source/blender/blenlib/BLI_array_cxx.h b/source/blender/blenlib/BLI_array_cxx.h
index c7704e20fb1..adb00c95f28 100644
--- a/source/blender/blenlib/BLI_array_cxx.h
+++ b/source/blender/blenlib/BLI_array_cxx.h
@@ -27,26 +27,28 @@
#include "BLI_allocator.h"
#include "BLI_array_ref.h"
#include "BLI_memory_utils_cxx.h"
+#include "BLI_index_range.h"
namespace BLI {
-template<typename T, typename Allocator = GuardedAllocator> class Array {
+template<typename T, uint N = 4, typename Allocator = GuardedAllocator> class Array {
private:
T *m_data;
uint m_size;
Allocator m_allocator;
+ AlignedBuffer<sizeof(T) * N, alignof(T)> m_inline_storage;
public:
Array()
{
- m_data = nullptr;
+ m_data = this->inline_storage();
m_size = 0;
}
Array(ArrayRef<T> values)
{
m_size = values.size();
- m_data = this->allocate(m_size);
+ m_data = this->get_buffer_for_size(values.size());
uninitialized_copy_n(values.begin(), m_size, m_data);
}
@@ -56,8 +58,8 @@ template<typename T, typename Allocator = GuardedAllocator> class Array {
explicit Array(uint size)
{
- m_data = this->allocate(size);
m_size = size;
+ m_data = this->get_buffer_for_size(size);
for (uint i = 0; i < m_size; i++) {
new (m_data + i) T();
@@ -66,8 +68,8 @@ template<typename T, typename Allocator = GuardedAllocator> class Array {
Array(uint size, const T &value)
{
- m_data = this->allocate(size);
m_size = size;
+ m_data = this->get_buffer_for_size(size);
uninitialized_fill_n(m_data, m_size, value);
}
@@ -76,30 +78,31 @@ template<typename T, typename Allocator = GuardedAllocator> class Array {
m_size = other.size();
m_allocator = other.m_allocator;
- if (m_size == 0) {
- m_data = nullptr;
- return;
- }
- else {
- m_data = this->allocate(m_size);
- copy_n(other.begin(), m_size, m_data);
- }
+ m_data = this->get_buffer_for_size(other.size());
+ copy_n(other.begin(), m_size, m_data);
}
Array(Array &&other) noexcept
{
- m_data = other.m_data;
m_size = other.m_size;
m_allocator = other.m_allocator;
- other.m_data = nullptr;
+ if (!other.uses_inline_storage()) {
+ m_data = other.m_data;
+ }
+ else {
+ m_data = this->get_buffer_for_size(m_size);
+ uninitialized_relocate_n(other.m_data, m_size, m_data);
+ }
+
+ other.m_data = other.inline_storage();
other.m_size = 0;
}
~Array()
{
destruct_n(m_data, m_size);
- if (m_data != nullptr) {
+ if (!this->uses_inline_storage()) {
m_allocator.deallocate((void *)m_data);
}
}
@@ -141,12 +144,23 @@ template<typename T, typename Allocator = GuardedAllocator> class Array {
return *this;
}
+ MutableArrayRef<T> as_mutable_ref()
+ {
+ return *this;
+ }
+
T &operator[](uint index)
{
BLI_assert(index < m_size);
return m_data[index];
}
+ const T &operator[](uint index) const
+ {
+ BLI_assert(index < m_size);
+ return m_data[index];
+ }
+
uint size() const
{
return m_size;
@@ -182,15 +196,38 @@ template<typename T, typename Allocator = GuardedAllocator> class Array {
return m_data + m_size;
}
+ IndexRange index_range() const
+ {
+ return IndexRange(m_size);
+ }
+
private:
+ T *get_buffer_for_size(uint size)
+ {
+ if (size <= N) {
+ return this->inline_storage();
+ }
+ else {
+ return this->allocate(size);
+ }
+ }
+
+ T *inline_storage() const
+ {
+ return (T *)m_inline_storage.ptr();
+ }
+
T *allocate(uint size)
{
return (T *)m_allocator.allocate_aligned(
size * sizeof(T), std::alignment_of<T>::value, __func__);
}
-};
-template<typename T> using TemporaryArray = Array<T, TemporaryAllocator>;
+ bool uses_inline_storage() const
+ {
+ return m_data == this->inline_storage();
+ }
+};
} // namespace BLI
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__ */
diff --git a/source/blender/blenlib/BLI_hash_cxx.h b/source/blender/blenlib/BLI_hash_cxx.h
index e899f27c9ee..a369774a471 100644
--- a/source/blender/blenlib/BLI_hash_cxx.h
+++ b/source/blender/blenlib/BLI_hash_cxx.h
@@ -58,6 +58,7 @@ TRIVIAL_DEFAULT_INT_HASH(uint16_t);
TRIVIAL_DEFAULT_INT_HASH(int32_t);
TRIVIAL_DEFAULT_INT_HASH(uint32_t);
TRIVIAL_DEFAULT_INT_HASH(int64_t);
+TRIVIAL_DEFAULT_INT_HASH(uint64_t);
template<> struct DefaultHash<float> {
uint32_t operator()(float value) const
diff --git a/source/blender/blenlib/BLI_index_range.h b/source/blender/blenlib/BLI_index_range.h
index a1fed5bd97c..f67cc259227 100644
--- a/source/blender/blenlib/BLI_index_range.h
+++ b/source/blender/blenlib/BLI_index_range.h
@@ -31,6 +31,11 @@
#include "BLI_utildefines.h"
+/* Forward declare tbb::blocked_range for conversion operations. */
+namespace tbb {
+template<typename Value> class blocked_range;
+}
+
namespace BLI {
template<typename T> class ArrayRef;
@@ -51,6 +56,11 @@ class IndexRange {
{
}
+ template<typename T>
+ IndexRange(const tbb::blocked_range<T> &range) : m_start(range.begin()), m_size(range.size())
+ {
+ }
+
class Iterator {
private:
uint m_current;
@@ -179,6 +189,11 @@ class IndexRange {
return IndexRange(new_start, size);
}
+ IndexRange slice(IndexRange range) const
+ {
+ return this->slice(range.start(), range.size());
+ }
+
/**
* Get read-only access to a memory buffer that contains the range as actual numbers.
*/
diff --git a/source/blender/blenlib/BLI_kdtree.h b/source/blender/blenlib/BLI_kdtree.h
index 9e966ffb798..9ba045fdbf8 100644
--- a/source/blender/blenlib/BLI_kdtree.h
+++ b/source/blender/blenlib/BLI_kdtree.h
@@ -17,6 +17,10 @@
#ifndef __BLI_KDTREE_H__
#define __BLI_KDTREE_H__
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/** \file
* \ingroup bli
* \brief A kd-tree for nearest neighbor search.
@@ -66,4 +70,8 @@
#undef KDTreeNearest
#undef KDTREE_PREFIX_ID
+#ifdef __cplusplus
+}
+#endif
+
#endif /* __BLI_KDTREE_H__ */
diff --git a/source/blender/blenlib/BLI_listbase_wrapper.h b/source/blender/blenlib/BLI_listbase_wrapper.h
index 34197fe9c45..d6832166e35 100644
--- a/source/blender/blenlib/BLI_listbase_wrapper.h
+++ b/source/blender/blenlib/BLI_listbase_wrapper.h
@@ -93,6 +93,19 @@ template<typename T> class IntrusiveListBaseWrapper {
BLI_assert(ptr);
return (T *)ptr;
}
+
+ uint index_of(const T *value) const
+ {
+ uint index = 0;
+ for (T *ptr : *this) {
+ if (ptr == value) {
+ return index;
+ }
+ index++;
+ }
+ BLI_assert(false);
+ return 0;
+ }
};
} /* namespace BLI */
diff --git a/source/blender/blenlib/BLI_map.h b/source/blender/blenlib/BLI_map.h
index 1edf7653c71..73b731252b6 100644
--- a/source/blender/blenlib/BLI_map.h
+++ b/source/blender/blenlib/BLI_map.h
@@ -413,6 +413,19 @@ template<typename KeyT, typename ValueT, typename Allocator = GuardedAllocator>
return m_array.slots_set();
}
+ template<typename FuncT> void foreach_item(const FuncT &func) const
+ {
+ for (const Item &item : m_array) {
+ for (uint offset = 0; offset < 4; offset++) {
+ if (item.is_set(offset)) {
+ const KeyT &key = *item.key(offset);
+ const ValueT &value = *item.value(offset);
+ func(key, value);
+ }
+ }
+ }
+ }
+
void print_table() const
{
std::cout << "Hash Table:\n";
diff --git a/source/blender/blenlib/BLI_math_color_blend.h b/source/blender/blenlib/BLI_math_color_blend.h
index 2e756b14424..47bafff3a49 100644
--- a/source/blender/blenlib/BLI_math_color_blend.h
+++ b/source/blender/blenlib/BLI_math_color_blend.h
@@ -64,53 +64,49 @@ MINLINE void blend_color_add_alpha_byte(unsigned char dst[4],
const unsigned char src2[4]);
MINLINE void blend_color_overlay_byte(unsigned char dst[4],
- unsigned const char src1[4],
- unsigned const char src2[4]);
+ const uchar src1[4],
+ const uchar src2[4]);
MINLINE void blend_color_hardlight_byte(unsigned char dst[4],
- unsigned const char src1[4],
- unsigned const char src2[4]);
-MINLINE void blend_color_burn_byte(unsigned char dst[4],
- unsigned const char src1[4],
- unsigned const char src2[4]);
+ const uchar src1[4],
+ const uchar src2[4]);
+MINLINE void blend_color_burn_byte(unsigned char dst[4], const uchar src1[4], const uchar src2[4]);
MINLINE void blend_color_linearburn_byte(unsigned char dst[4],
- unsigned const char src1[4],
- unsigned const char src2[4]);
+ const uchar src1[4],
+ const uchar src2[4]);
MINLINE void blend_color_dodge_byte(unsigned char dst[4],
- unsigned const char src1[4],
- unsigned const char src2[4]);
+ const uchar src1[4],
+ const uchar src2[4]);
MINLINE void blend_color_screen_byte(unsigned char dst[4],
- unsigned const char src1[4],
- unsigned const char src2[4]);
+ const uchar src1[4],
+ const uchar src2[4]);
MINLINE void blend_color_softlight_byte(unsigned char dst[4],
- unsigned const char src1[4],
- unsigned const char src2[4]);
+ const uchar src1[4],
+ const uchar src2[4]);
MINLINE void blend_color_pinlight_byte(unsigned char dst[4],
- unsigned const char src1[4],
- unsigned const char src2[4]);
+ const uchar src1[4],
+ const uchar src2[4]);
MINLINE void blend_color_linearlight_byte(unsigned char dst[4],
- unsigned const char src1[4],
- unsigned const char src2[4]);
+ const uchar src1[4],
+ const uchar src2[4]);
MINLINE void blend_color_vividlight_byte(unsigned char dst[4],
- unsigned const char src1[4],
- unsigned const char src2[4]);
+ const uchar src1[4],
+ const uchar src2[4]);
MINLINE void blend_color_difference_byte(unsigned char dst[4],
- unsigned const char src1[4],
- unsigned const char src2[4]);
+ const uchar src1[4],
+ const uchar src2[4]);
MINLINE void blend_color_exclusion_byte(unsigned char dst[4],
- unsigned const char src1[4],
- unsigned const char src2[4]);
+ const uchar src1[4],
+ const uchar src2[4]);
MINLINE void blend_color_color_byte(unsigned char dst[4],
- unsigned const char src1[4],
- unsigned const char src2[4]);
-MINLINE void blend_color_hue_byte(unsigned char dst[4],
- unsigned const char src1[4],
- unsigned const char src2[4]);
+ const uchar src1[4],
+ const uchar src2[4]);
+MINLINE void blend_color_hue_byte(unsigned char dst[4], const uchar src1[4], const uchar src2[4]);
MINLINE void blend_color_saturation_byte(unsigned char dst[4],
- unsigned const char src1[4],
- unsigned const char src2[4]);
+ const uchar src1[4],
+ const uchar src2[4]);
MINLINE void blend_color_luminosity_byte(unsigned char dst[4],
- unsigned const char src1[4],
- unsigned const char src2[4]);
+ const uchar src1[4],
+ const uchar src2[4]);
MINLINE void blend_color_interpolate_byte(unsigned char dst[4],
const unsigned char src1[4],
diff --git a/source/blender/blenlib/BLI_memory_utils_cxx.h b/source/blender/blenlib/BLI_memory_utils_cxx.h
index 22f333c6303..f15621b4e41 100644
--- a/source/blender/blenlib/BLI_memory_utils_cxx.h
+++ b/source/blender/blenlib/BLI_memory_utils_cxx.h
@@ -33,6 +33,11 @@ using std::uninitialized_copy_n;
using std::uninitialized_fill;
using std::uninitialized_fill_n;
+template<typename T> void construct_default(T *ptr)
+{
+ new (ptr) T();
+}
+
template<typename T> void destruct(T *ptr)
{
ptr->~T();
@@ -79,6 +84,38 @@ template<typename T> void relocate_n(T *src, uint n, T *dst)
destruct_n(src, n);
}
+template<typename T, typename... Args> std::unique_ptr<T> make_unique(Args &&... args)
+{
+ return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
+}
+
+template<typename T> struct DestructValueAtAddress {
+ void operator()(T *ptr)
+ {
+ ptr->~T();
+ }
+};
+
+template<typename T> using destruct_ptr = std::unique_ptr<T, DestructValueAtAddress<T>>;
+
+template<uint Size, uint Alignment> class alignas(Alignment) AlignedBuffer {
+ private:
+ /* Don't create an empty array. This causes problems with some compilers. */
+ static constexpr uint ActualSize = (Size > 0) ? Size : 1;
+ char m_buffer[ActualSize];
+
+ public:
+ void *ptr()
+ {
+ return (void *)m_buffer;
+ }
+
+ const void *ptr() const
+ {
+ return (const void *)m_buffer;
+ }
+};
+
} // namespace BLI
#endif /* __BLI_MEMORY_UTILS_CXX_H__ */
diff --git a/source/blender/blenlib/BLI_open_addressing.h b/source/blender/blenlib/BLI_open_addressing.h
index 8ca5156a952..a238902c631 100644
--- a/source/blender/blenlib/BLI_open_addressing.h
+++ b/source/blender/blenlib/BLI_open_addressing.h
@@ -70,7 +70,7 @@ class OpenAddressingArray {
/* Can be used to map a hash value into the range of valid slot indices. */
uint32_t m_slot_mask;
Allocator m_allocator;
- char m_local_storage[sizeof(Item) * ItemsInSmallStorage];
+ AlignedBuffer<sizeof(Item) * ItemsInSmallStorage, alignof(Item)> m_local_storage;
public:
explicit OpenAddressingArray(uint8_t item_exponent = 0)
@@ -291,7 +291,7 @@ class OpenAddressingArray {
private:
Item *small_storage() const
{
- return reinterpret_cast<Item *>((char *)m_local_storage);
+ return reinterpret_cast<Item *>((char *)m_local_storage.ptr());
}
bool is_in_small_storage() const
diff --git a/source/blender/blenlib/BLI_optional.h b/source/blender/blenlib/BLI_optional.h
new file mode 100644
index 00000000000..90bded604ea
--- /dev/null
+++ b/source/blender/blenlib/BLI_optional.h
@@ -0,0 +1,199 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/** \file
+ * \ingroup bli
+ *
+ * Simple version of std::optional, which is only available since C++17.
+ */
+
+#ifndef __BLI_OPTIONAL_H__
+#define __BLI_OPTIONAL_H__
+
+#include "BLI_utildefines.h"
+#include "BLI_memory_utils_cxx.h"
+
+#include <algorithm>
+#include <memory>
+
+namespace BLI {
+
+template<typename T> class Optional {
+ private:
+ AlignedBuffer<sizeof(T), alignof(T)> m_storage;
+ bool m_set;
+
+ public:
+ static Optional FromPointer(const T *ptr)
+ {
+ if (ptr == nullptr) {
+ return Optional();
+ }
+ else {
+ return Optional(*ptr);
+ }
+ }
+
+ Optional() : m_set(false)
+ {
+ }
+
+ ~Optional()
+ {
+ this->reset();
+ }
+
+ Optional(const T &value) : Optional()
+ {
+ this->set(value);
+ }
+
+ Optional(T &&value) : Optional()
+ {
+ this->set(std::forward<T>(value));
+ }
+
+ Optional(const Optional &other) : Optional()
+ {
+ if (other.has_value()) {
+ this->set(other.value());
+ }
+ }
+
+ Optional(Optional &&other) : Optional()
+ {
+ if (other.has_value()) {
+ this->set(std::move(other.value()));
+ }
+ }
+
+ Optional &operator=(const Optional &other)
+ {
+ if (this == &other) {
+ return *this;
+ }
+ if (other.has_value()) {
+ this->set(other.value());
+ }
+ else {
+ this->reset();
+ }
+ return *this;
+ }
+
+ Optional &operator=(Optional &&other)
+ {
+ if (this == &other) {
+ return *this;
+ }
+ if (other.has_value()) {
+ this->set(std::move(other.value()));
+ }
+ else {
+ this->reset();
+ }
+ return *this;
+ }
+
+ bool has_value() const
+ {
+ return m_set;
+ }
+
+ const T &value() const
+ {
+ BLI_assert(m_set);
+ return *this->value_ptr();
+ }
+
+ T &value()
+ {
+ BLI_assert(m_set);
+ return *this->value_ptr();
+ }
+
+ void set(const T &value)
+ {
+ if (m_set) {
+ this->value() = value;
+ }
+ else {
+ new (this->value_ptr()) T(value);
+ m_set = true;
+ }
+ }
+
+ void set(T &&value)
+ {
+ if (m_set) {
+ this->value() = std::move(value);
+ }
+ else {
+ new (this->value_ptr()) T(std::move(value));
+ m_set = true;
+ }
+ }
+
+ void set_new(const T &value)
+ {
+ BLI_assert(!m_set);
+ new (this->value_ptr()) T(value);
+ m_set = true;
+ }
+
+ void set_new(T &&value)
+ {
+ BLI_assert(!m_set);
+ new (this->value_ptr()) T(std::move(value));
+ m_set = true;
+ }
+
+ void reset()
+ {
+ if (m_set) {
+ this->value_ptr()->~T();
+ m_set = false;
+ }
+ }
+
+ T extract()
+ {
+ BLI_assert(m_set);
+ T value = std::move(this->value());
+ this->reset();
+ return value;
+ }
+
+ T *operator->()
+ {
+ return this->value_ptr();
+ }
+
+ T &operator*()
+ {
+ return *this->value_ptr();
+ }
+
+ private:
+ T *value_ptr() const
+ {
+ return (T *)m_storage.ptr();
+ }
+};
+
+} /* namespace BLI */
+
+#endif /* __BLI_OPTIONAL_H__ */
diff --git a/source/blender/blenlib/BLI_rand.h b/source/blender/blenlib/BLI_rand.h
index be2b18b05fd..ad8a90b3977 100644
--- a/source/blender/blenlib/BLI_rand.h
+++ b/source/blender/blenlib/BLI_rand.h
@@ -20,6 +20,8 @@
#ifndef __BLI_RAND_H__
#define __BLI_RAND_H__
+#include "BLI_compiler_attrs.h"
+
/** \file
* \ingroup bli
* \brief Random number functions.
diff --git a/source/blender/blenlib/BLI_stack_cxx.h b/source/blender/blenlib/BLI_stack_cxx.h
index 7915acadfac..a26318a3dcb 100644
--- a/source/blender/blenlib/BLI_stack_cxx.h
+++ b/source/blender/blenlib/BLI_stack_cxx.h
@@ -58,7 +58,7 @@ template<typename T, uint N = 4, typename Allocator = GuardedAllocator> class St
/**
* Return true when the stack is empty, otherwise false.
*/
- bool empty() const
+ bool is_empty() const
{
return this->size() == 0;
}
@@ -76,6 +76,11 @@ template<typename T, uint N = 4, typename Allocator = GuardedAllocator> class St
m_elements.append(std::move(value));
}
+ void push_multiple(ArrayRef<T> values)
+ {
+ m_elements.extend(values);
+ }
+
/**
* Remove the element from the top of the stack and return it.
* This will assert when the stack is empty.
@@ -91,7 +96,7 @@ template<typename T, uint N = 4, typename Allocator = GuardedAllocator> class St
*/
T &peek()
{
- BLI_assert(!this->empty());
+ BLI_assert(!this->is_empty());
return m_elements[this->size() - 1];
}
diff --git a/source/blender/blenlib/BLI_string_map.h b/source/blender/blenlib/BLI_string_map.h
index ba870eb878a..2f09e489a7a 100644
--- a/source/blender/blenlib/BLI_string_map.h
+++ b/source/blender/blenlib/BLI_string_map.h
@@ -30,6 +30,7 @@
#include "BLI_map.h"
#include "BLI_string_ref.h"
#include "BLI_vector.h"
+#include "BLI_optional.h"
namespace BLI {
@@ -190,6 +191,22 @@ template<typename T, typename Allocator = GuardedAllocator> class StringMap {
}
/**
+ * Add a new element to the map if the key does not exist yet.
+ */
+ void add(StringRef key, const T &value)
+ {
+ if (!this->contains(key)) {
+ this->add_new(key, value);
+ }
+ }
+ void add(StringRef key, T &&value)
+ {
+ if (!this->contains(key)) {
+ this->add_new(key, std::move(value));
+ }
+ }
+
+ /**
* Return true when the key exists in the map, otherwise false.
*/
bool contains(StringRef key) const
@@ -263,6 +280,11 @@ template<typename T, typename Allocator = GuardedAllocator> class StringMap {
return const_cast<T *>(const_cast<const StringMap *>(this)->lookup_ptr(key));
}
+ Optional<T> try_lookup(StringRef key) const
+ {
+ return Optional<T>::FromPointer(this->lookup_ptr(key));
+ }
+
/**
* Get a copy of the value corresponding to the key. If the key does not exist, return the
* default value.
@@ -326,7 +348,7 @@ template<typename T, typename Allocator = GuardedAllocator> class StringMap {
/**
* Run a function for every key-value-pair in the map.
*/
- template<typename FuncT> void foreach_key_value_pair(const FuncT &func)
+ template<typename FuncT> void foreach_item(const FuncT &func)
{
for (Item &item : m_array) {
for (uint offset = 0; offset < 4; offset++) {
@@ -339,6 +361,19 @@ template<typename T, typename Allocator = GuardedAllocator> class StringMap {
}
}
+ template<typename FuncT> void foreach_item(const FuncT &func) const
+ {
+ for (const Item &item : m_array) {
+ for (uint offset = 0; offset < 4; offset++) {
+ if (item.is_set(offset)) {
+ StringRefNull key = item.get_key(offset, m_chars);
+ const T &value = *item.value(offset);
+ func(key, value);
+ }
+ }
+ }
+ }
+
private:
uint32_t compute_string_hash(StringRef key) const
{
@@ -415,6 +450,15 @@ template<typename T, typename Allocator = GuardedAllocator> class StringMap {
}
ITER_SLOTS_END(offset);
}
+
+ template<typename ForwardT> void add__impl(StringRef key, ForwardT &&value)
+ {
+ this->ensure_can_add();
+ uint32_t hash = this->compute_string_hash(key);
+ ITER_SLOTS_BEGIN (hash, m_array, , item, offset) {
+ }
+ ITER_SLOTS_END(offset);
+ }
};
#undef ITER_SLOTS_BEGIN
diff --git a/source/blender/blenlib/BLI_string_ref.h b/source/blender/blenlib/BLI_string_ref.h
index 76163a2754c..54c2f0e7209 100644
--- a/source/blender/blenlib/BLI_string_ref.h
+++ b/source/blender/blenlib/BLI_string_ref.h
@@ -109,6 +109,8 @@ class StringRefBase {
* Returns true when the string ends with the given suffix. Otherwise false.
*/
bool endswith(StringRef suffix) const;
+
+ StringRef substr(uint start, uint size) const;
};
/**
@@ -242,6 +244,12 @@ inline bool StringRefBase::endswith(StringRef suffix) const
return true;
}
+inline StringRef StringRefBase::substr(uint start, uint size) const
+{
+ BLI_assert(start + size <= m_size);
+ return StringRef(m_data + start, size);
+}
+
} // namespace BLI
#endif /* __BLI_STRING_REF_H__ */
diff --git a/source/blender/blenlib/BLI_string_utils.h b/source/blender/blenlib/BLI_string_utils.h
index 13dbb2de659..b3aed438641 100644
--- a/source/blender/blenlib/BLI_string_utils.h
+++ b/source/blender/blenlib/BLI_string_utils.h
@@ -44,6 +44,11 @@ void BLI_string_split_suffix(const char *string, char *r_body, char *r_suf, cons
void BLI_string_split_prefix(const char *string, char *r_pre, char *r_body, const size_t str_len);
/* Join strings, return newly allocated string. */
+char *BLI_string_join_array(char *result,
+ size_t result_len,
+ const char *strings[],
+ uint strings_len) ATTR_NONNULL();
+
char *BLI_string_join_arrayN(const char *strings[], uint strings_len) ATTR_WARN_UNUSED_RESULT
ATTR_NONNULL();
char *BLI_string_join_array_by_sep_charN(char sep,
@@ -54,6 +59,9 @@ char *BLI_string_join_array_by_sep_char_with_tableN(char sep,
const char *strings[],
uint strings_len) ATTR_NONNULL();
/* Take multiple arguments, pass as (array, length). */
+#define BLI_string_join(result, result_len, ...) \
+ BLI_string_join_array( \
+ result, result_len, ((const char *[]){__VA_ARGS__}), VA_NARGS_COUNT(__VA_ARGS__))
#define BLI_string_joinN(...) \
BLI_string_join_arrayN(((const char *[]){__VA_ARGS__}), VA_NARGS_COUNT(__VA_ARGS__))
#define BLI_string_join_by_sep_charN(sep, ...) \
diff --git a/source/blender/blenlib/BLI_temporary_allocator.h b/source/blender/blenlib/BLI_temporary_allocator.h
deleted file mode 100644
index b378e5869c0..00000000000
--- a/source/blender/blenlib/BLI_temporary_allocator.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-/** \file
- * \ingroup bli
- *
- * This allocation method assumes
- * 1. The allocations are short-lived.
- * 2. The total number of allocations is bound by a constant per thread.
- *
- * These two assumptions make it possible to cache and reuse relatively large buffers. They allow
- * to hand out buffers that are much larger than the requested size, without the fear of running
- * out of memory.
- *
- * The assumptions might feel a bit limiting at first, but hold true in many cases. For example,
- * many algorithms need to store temporary data. With this allocator, the allocation can become
- * very cheap for common cases.
- *
- * Many cpu-bound algorithms can benefit from being split up into several stages, whereby the
- * output of one stage is written into an array that is read by the next stage. This makes them
- * easier to debug, profile and optimize. Often a reason this is not done is that the memory
- * allocation might be expensive. The goal of this allocator is to make this a non-issue, by
- * reusing the same long buffers over and over again.
- *
- * All allocated buffers are 64 byte aligned, to make them as reusable as possible.
- * If the requested size is too large, there is a fallback to normal allocation. The allocation
- * overhead is probably very small in these cases anyway.
- *
- * The best way to use this allocator is to use one of the prepared containers like TemporaryVector
- * and TemporaryArray.
- */
-
-#ifndef __BLI_TEMPORARY_ALLOCATOR_H__
-#define __BLI_TEMPORARY_ALLOCATOR_H__
-
-#include "BLI_utildefines.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define BLI_TEMPORARY_BUFFER_ALIGNMENT 64
-
-void *BLI_temporary_allocate(uint size);
-void BLI_temporary_deallocate(void *buffer);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __BLI_TEMPORARY_ALLOCATOR_H__ */
diff --git a/source/blender/blenlib/BLI_temporary_allocator_cxx.h b/source/blender/blenlib/BLI_temporary_allocator_cxx.h
deleted file mode 100644
index 06159f68059..00000000000
--- a/source/blender/blenlib/BLI_temporary_allocator_cxx.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#ifndef __BLI_TEMPORARY_ALLOCATOR_CXX_H__
-#define __BLI_TEMPORARY_ALLOCATOR_CXX_H__
-
-/** \file
- * \ingroup bli
- */
-
-#include "BLI_temporary_allocator.h"
-
-namespace BLI {
-
-template<typename T> class MutableArrayRef;
-
-template<typename T> MutableArrayRef<T> temporary_allocate_array(uint size)
-{
- void *ptr = BLI_temporary_allocate(sizeof(T) * size);
- return MutableArrayRef<T>((T *)ptr, size);
-}
-
-}; // namespace BLI
-
-#endif /* __BLI_TEMPORARY_ALLOCATOR_CXX_H__ */
diff --git a/source/blender/blenlib/BLI_utility_mixins.h b/source/blender/blenlib/BLI_utility_mixins.h
new file mode 100644
index 00000000000..ce7a4ce094a
--- /dev/null
+++ b/source/blender/blenlib/BLI_utility_mixins.h
@@ -0,0 +1,52 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/** \file
+ * \ingroup bli
+ */
+
+#ifndef __BLI_UTILITY_MIXINS_H__
+#define __BLI_UTILITY_MIXINS_H__
+
+namespace BLI {
+
+class NonCopyable {
+ public:
+ /* Disable copy construction and assignment. */
+ NonCopyable(const NonCopyable &other) = delete;
+ NonCopyable &operator=(const NonCopyable &other) = delete;
+
+ /* Explicitly enable default construction, move construction and move assignment. */
+ NonCopyable() = default;
+ NonCopyable(NonCopyable &&other) = default;
+ NonCopyable &operator=(NonCopyable &&other) = default;
+};
+
+class NonMovable {
+ public:
+ /* Disable move construction and assignment. */
+ NonMovable(NonMovable &&other) = delete;
+ NonMovable &operator=(NonMovable &&other) = delete;
+
+ /* Explicitly enable default construction, copy construction and copy assignment. */
+ NonMovable() = default;
+ NonMovable(const NonMovable &other) = default;
+ NonMovable &operator=(const NonMovable &other) = default;
+};
+
+} // namespace BLI
+
+#endif /* __BLI_UTILITY_MIXINS_H__ */
diff --git a/source/blender/blenlib/BLI_vector.h b/source/blender/blenlib/BLI_vector.h
index 46c46a1440f..60251347795 100644
--- a/source/blender/blenlib/BLI_vector.h
+++ b/source/blender/blenlib/BLI_vector.h
@@ -37,6 +37,7 @@
#include "BLI_listbase_wrapper.h"
#include "BLI_math_base.h"
#include "BLI_allocator.h"
+#include "BLI_index_range.h"
#include "MEM_guardedalloc.h"
@@ -48,7 +49,7 @@ template<typename T, uint N = 4, typename Allocator = GuardedAllocator> class Ve
T *m_end;
T *m_capacity_end;
Allocator m_allocator;
- char m_small_buffer[sizeof(T) * N];
+ AlignedBuffer<sizeof(T) * N, alignof(T)> m_small_buffer;
#ifndef NDEBUG
/* Storing size in debug builds, because it makes debugging much easier sometimes. */
@@ -215,6 +216,16 @@ template<typename T, uint N = 4, typename Allocator = GuardedAllocator> class Ve
return MutableArrayRef<T>(m_begin, this->size());
}
+ ArrayRef<T> as_ref() const
+ {
+ return *this;
+ }
+
+ MutableArrayRef<T> as_mutable_ref()
+ {
+ return *this;
+ }
+
Vector &operator=(const Vector &other)
{
if (this == &other) {
@@ -233,6 +244,8 @@ template<typename T, uint N = 4, typename Allocator = GuardedAllocator> class Ve
return *this;
}
+ /* This can fail, when the vector is used to build a recursive data structure.
+ See https://youtu.be/7Qgd9B1KuMQ?t=840. */
this->~Vector();
new (this) Vector(std::move(other));
@@ -293,6 +306,20 @@ template<typename T, uint N = 4, typename Allocator = GuardedAllocator> class Ve
this->append_unchecked(std::move(value));
}
+ uint append_and_get_index(const T &value)
+ {
+ uint index = this->size();
+ this->append(value);
+ return index;
+ }
+
+ void append_non_duplicates(const T &value)
+ {
+ if (!this->contains(value)) {
+ this->append(value);
+ }
+ }
+
void append_unchecked(const T &value)
{
BLI_assert(m_end < m_capacity_end);
@@ -341,6 +368,13 @@ template<typename T, uint N = 4, typename Allocator = GuardedAllocator> class Ve
this->extend_unchecked(start, amount);
}
+ void extend_non_duplicates(ArrayRef<T> array)
+ {
+ for (const T &value : array) {
+ this->append_non_duplicates(value);
+ }
+ }
+
void extend_unchecked(ArrayRef<T> array)
{
this->extend_unchecked(array.begin(), array.size());
@@ -441,11 +475,17 @@ template<typename T, uint N = 4, typename Allocator = GuardedAllocator> class Ve
UPDATE_VECTOR_SIZE(this);
}
+ void remove_first_occurrence_and_reorder(const T &value)
+ {
+ uint index = this->index(value);
+ this->remove_and_reorder((uint)index);
+ }
+
/**
* Do a linear search to find the value in the vector.
* When found, return the first index, otherwise return -1.
*/
- int index(const T &value) const
+ int index_try(const T &value) const
{
for (T *current = m_begin; current != m_end; current++) {
if (*current == value) {
@@ -456,12 +496,23 @@ template<typename T, uint N = 4, typename Allocator = GuardedAllocator> class Ve
}
/**
+ * Do a linear search to find the value in the vector.
+ * When found, return the first index, otherwise fail.
+ */
+ uint index(const T &value) const
+ {
+ int index = this->index_try(value);
+ BLI_assert(index >= 0);
+ return (uint)index;
+ }
+
+ /**
* Do a linear search to see of the value is in the vector.
* Return true when it exists, otherwise false.
*/
bool contains(const T &value) const
{
- return this->index(value) != -1;
+ return this->index_try(value) != -1;
}
/**
@@ -520,6 +571,11 @@ template<typename T, uint N = 4, typename Allocator = GuardedAllocator> class Ve
return (uint)(m_capacity_end - m_begin);
}
+ IndexRange index_range() const
+ {
+ return IndexRange(this->size());
+ }
+
void print_stats() const
{
std::cout << "Small Vector at " << (void *)this << ":" << std::endl;
@@ -531,7 +587,7 @@ template<typename T, uint N = 4, typename Allocator = GuardedAllocator> class Ve
private:
T *small_buffer() const
{
- return (T *)m_small_buffer;
+ return (T *)m_small_buffer.ptr();
}
bool is_small() const
@@ -555,10 +611,11 @@ template<typename T, uint N = 4, typename Allocator = GuardedAllocator> class Ve
/* Round up to the next power of two. Otherwise consecutive calls to grow can cause a
* reallocation every time even though the min_capacity only increments. */
min_capacity = power_of_2_max_u(min_capacity);
+
uint size = this->size();
T *new_array = (T *)m_allocator.allocate_aligned(
- min_capacity * (uint)sizeof(T), std::alignment_of<T>::value, __func__);
+ min_capacity * (uint)sizeof(T), std::alignment_of<T>::value, "grow BLI::Vector");
uninitialized_relocate_n(m_begin, size, new_array);
if (!this->is_small()) {
@@ -600,7 +657,11 @@ template<typename T, uint N = 4, typename Allocator = GuardedAllocator> class Ve
#undef UPDATE_VECTOR_SIZE
-template<typename T, uint N = 4> using TemporaryVector = Vector<T, N, TemporaryAllocator>;
+/**
+ * Use when the vector is used in the local scope of a function. It has a larger inline storage by
+ * default to make allocations less likely.
+ */
+template<typename T, uint N = 20> using ScopedVector = Vector<T, N, GuardedAllocator>;
} /* namespace BLI */
diff --git a/source/blender/blenlib/BLI_vector_set.h b/source/blender/blenlib/BLI_vector_set.h
index fb21f7ed987..99d955c60d8 100644
--- a/source/blender/blenlib/BLI_vector_set.h
+++ b/source/blender/blenlib/BLI_vector_set.h
@@ -292,12 +292,12 @@ template<typename T, typename Allocator = GuardedAllocator> class VectorSet {
return m_elements[index];
}
- operator ArrayRef<T>() const
+ ArrayRef<T> as_ref() const
{
- return m_elements;
+ return *this;
}
- operator MutableArrayRef<T>()
+ operator ArrayRef<T>() const
{
return m_elements;
}
diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt
index d22b1cd0ddb..1e4e07d63b3 100644
--- a/source/blender/blenlib/CMakeLists.txt
+++ b/source/blender/blenlib/CMakeLists.txt
@@ -52,7 +52,6 @@ set(SRC
intern/BLI_memblock.c
intern/BLI_memiter.c
intern/BLI_mempool.c
- intern/BLI_temporary_allocator.cc
intern/BLI_timer.c
intern/DLRB_tree.c
intern/array_store.c
@@ -213,6 +212,7 @@ set(SRC
BLI_mempool.h
BLI_noise.h
BLI_open_addressing.h
+ BLI_optional.h
BLI_path_util.h
BLI_polyfill_2d.h
BLI_polyfill_2d_beautify.h
@@ -236,8 +236,6 @@ set(SRC
BLI_sys_types.h
BLI_system.h
BLI_task.h
- BLI_temporary_allocator.h
- BLI_temporary_allocator_cxx.h
BLI_threads.h
BLI_timecode.h
BLI_timer.h
@@ -245,6 +243,7 @@ set(SRC
BLI_utildefines_iter.h
BLI_utildefines_stack.h
BLI_utildefines_variadic.h
+ BLI_utility_mixins.h
BLI_uvproject.h
BLI_vector.h
BLI_vector_set.h
diff --git a/source/blender/blenlib/intern/BLI_ghash.c b/source/blender/blenlib/intern/BLI_ghash.c
index 05ffb02597d..1c518cf1487 100644
--- a/source/blender/blenlib/intern/BLI_ghash.c
+++ b/source/blender/blenlib/intern/BLI_ghash.c
@@ -220,8 +220,8 @@ static void ghash_buckets_resize(GHash *gh, const uint nbuckets)
if (nbuckets > nbuckets_old) {
for (i = 0; i < nbuckets_old; i++) {
for (Entry *e = buckets_old[i], *e_next; e; e = e_next) {
- const unsigned hash = ghash_entryhash(gh, e);
- const unsigned bucket_index = ghash_bucket_index(gh, hash);
+ const uint hash = ghash_entryhash(gh, e);
+ const uint bucket_index = ghash_bucket_index(gh, hash);
e_next = e->next;
e->next = buckets_new[bucket_index];
buckets_new[bucket_index] = e;
@@ -232,8 +232,8 @@ static void ghash_buckets_resize(GHash *gh, const uint nbuckets)
for (i = 0; i < nbuckets_old; i++) {
#ifdef GHASH_USE_MODULO_BUCKETS
for (Entry *e = buckets_old[i], *e_next; e; e = e_next) {
- const unsigned hash = ghash_entryhash(gh, e);
- const unsigned bucket_index = ghash_bucket_index(gh, hash);
+ const uint hash = ghash_entryhash(gh, e);
+ const uint bucket_index = ghash_bucket_index(gh, hash);
e_next = e->next;
e->next = buckets_new[bucket_index];
buckets_new[bucket_index] = e;
@@ -241,7 +241,7 @@ static void ghash_buckets_resize(GHash *gh, const uint nbuckets)
#else
/* No need to recompute hashes in this case, since our mask is just smaller,
* all items in old bucket 'i' will go in same new bucket (i & new_mask)! */
- const unsigned bucket_index = ghash_bucket_index(gh, i);
+ const uint bucket_index = ghash_bucket_index(gh, i);
BLI_assert(!buckets_old[i] ||
(bucket_index == ghash_bucket_index(gh, ghash_entryhash(gh, buckets_old[i]))));
Entry *e;
diff --git a/source/blender/blenlib/intern/BLI_index_range.cc b/source/blender/blenlib/intern/BLI_index_range.cc
index fde4dcf6d41..6421eb0794b 100644
--- a/source/blender/blenlib/intern/BLI_index_range.cc
+++ b/source/blender/blenlib/intern/BLI_index_range.cc
@@ -24,7 +24,7 @@
namespace BLI {
-static Vector<Array<uint, RawAllocator>, 1, RawAllocator> arrays;
+static Vector<Array<uint, 0, RawAllocator>, 1, RawAllocator> arrays;
static uint current_array_size = 0;
static uint *current_array = nullptr;
static std::mutex current_array_mutex;
@@ -44,7 +44,7 @@ ArrayRef<uint> IndexRange::as_array_ref() const
}
uint new_size = std::max<uint>(1000, power_of_2_max_u(min_required_size));
- Array<uint, RawAllocator> new_array(new_size);
+ Array<uint, 0, RawAllocator> new_array(new_size);
for (uint i = 0; i < new_size; i++) {
new_array[i] = i;
}
diff --git a/source/blender/blenlib/intern/BLI_temporary_allocator.cc b/source/blender/blenlib/intern/BLI_temporary_allocator.cc
deleted file mode 100644
index b145e65530d..00000000000
--- a/source/blender/blenlib/intern/BLI_temporary_allocator.cc
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#include <mutex>
-#include <stack>
-
-#include "BLI_temporary_allocator.h"
-#include "BLI_stack_cxx.h"
-
-using namespace BLI;
-
-constexpr uint ALIGNMENT = BLI_TEMPORARY_BUFFER_ALIGNMENT;
-constexpr uint SMALL_BUFFER_SIZE = 64 * 1024;
-constexpr uintptr_t ALIGNMENT_MASK = ~(uintptr_t)(ALIGNMENT - 1);
-
-enum TemporaryBufferType {
- Small,
- Large,
-};
-
-struct MemHead {
- void *raw_ptr;
- TemporaryBufferType type;
-};
-
-static MemHead &get_memhead(void *aligned_ptr)
-{
- return *((MemHead *)aligned_ptr - 1);
-}
-
-static void *raw_allocate(uint size)
-{
- uint total_allocation_size = size + ALIGNMENT + sizeof(MemHead);
-
- uintptr_t raw_ptr = (uintptr_t)malloc(total_allocation_size);
- uintptr_t aligned_ptr = (raw_ptr + ALIGNMENT + sizeof(MemHead)) & ALIGNMENT_MASK;
-
- MemHead &memhead = get_memhead((void *)aligned_ptr);
- memhead.raw_ptr = (void *)raw_ptr;
- return (void *)aligned_ptr;
-}
-
-static void raw_deallocate(void *ptr)
-{
- BLI_assert(((uintptr_t)ptr & ~ALIGNMENT_MASK) == 0);
- MemHead &memhead = get_memhead(ptr);
- void *raw_ptr = memhead.raw_ptr;
- free(raw_ptr);
-}
-
-struct ThreadLocalBuffers {
- uint allocated_amount = 0;
- Stack<void *, 32, RawAllocator> buffers;
-
- ~ThreadLocalBuffers()
- {
- for (void *ptr : buffers) {
- raw_deallocate(ptr);
- }
- }
-};
-
-static thread_local ThreadLocalBuffers local_storage;
-
-void *BLI_temporary_allocate(uint size)
-{
- /* The total amount of allocated buffers using this allocator should be limited by a constant. If
- * it grows unbounded, there is likely a memory leak somewhere. */
- BLI_assert(local_storage.allocated_amount < 100);
-
- if (size <= SMALL_BUFFER_SIZE) {
- auto &buffers = local_storage.buffers;
- if (buffers.empty()) {
- void *ptr = raw_allocate(SMALL_BUFFER_SIZE);
- MemHead &memhead = get_memhead(ptr);
- memhead.type = TemporaryBufferType::Small;
- local_storage.allocated_amount++;
- return ptr;
- }
- else {
- return buffers.pop();
- }
- }
- else {
- void *ptr = raw_allocate(size);
- MemHead &memhead = get_memhead(ptr);
- memhead.type = TemporaryBufferType::Large;
- return ptr;
- }
-}
-
-void BLI_temporary_deallocate(void *buffer)
-{
- MemHead &memhead = get_memhead(buffer);
- if (memhead.type == TemporaryBufferType::Small) {
- auto &buffers = local_storage.buffers;
- buffers.push(buffer);
- }
- else {
- raw_deallocate(buffer);
- }
-}
diff --git a/source/blender/blenlib/intern/delaunay_2d.c b/source/blender/blenlib/intern/delaunay_2d.c
index 118949d1c46..7287bec0849 100644
--- a/source/blender/blenlib/intern/delaunay_2d.c
+++ b/source/blender/blenlib/intern/delaunay_2d.c
@@ -389,7 +389,6 @@ static CDTEdge *connect_separate_parts(CDT_state *cdt, SymEdge *se1, SymEdge *se
{
CDTEdge *e;
SymEdge *se1_rot, *se1_rotsym, *se2_rot, *se2_rotsym, *new_se, *new_se_sym;
- ;
BLI_assert(se1->face == cdt->outer_face && se2->face == cdt->outer_face);
se1_rot = se1->rot;
@@ -1735,7 +1734,7 @@ static bool can_collapse(const SymEdge *se)
* edges may end up with zero or negative area (see can_collapse, above).
* So don't choose a collapse direction that is not allowed or one that has an original vertex
* as origin and a non-original vertex as destination.
- * If both collapse directions are allowed by that rule, picke the one with the lower original
+ * If both collapse directions are allowed by that rule, pick the one with the lower original
* index.
*
* After merging, the faces abc and adb disappear (if they are not the outer face).
diff --git a/source/blender/blenlib/intern/math_base_inline.c b/source/blender/blenlib/intern/math_base_inline.c
index a1c88edca6f..0a496d2bd68 100644
--- a/source/blender/blenlib/intern/math_base_inline.c
+++ b/source/blender/blenlib/intern/math_base_inline.c
@@ -224,7 +224,7 @@ MINLINE unsigned int power_of_2_max_u(unsigned int x)
return x + 1;
}
-MINLINE unsigned power_of_2_min_u(unsigned x)
+MINLINE unsigned int power_of_2_min_u(unsigned int x)
{
x |= (x >> 1);
x |= (x >> 2);
diff --git a/source/blender/blenlib/intern/math_color_blend_inline.c b/source/blender/blenlib/intern/math_color_blend_inline.c
index 7241779b32a..eb82bb81a89 100644
--- a/source/blender/blenlib/intern/math_color_blend_inline.c
+++ b/source/blender/blenlib/intern/math_color_blend_inline.c
@@ -49,9 +49,7 @@
/* straight alpha byte blending modes */
-MINLINE void blend_color_mix_byte(unsigned char dst[4],
- const unsigned char src1[4],
- const unsigned char src2[4])
+MINLINE void blend_color_mix_byte(uchar dst[4], const uchar src1[4], const uchar src2[4])
{
if (src2[3] != 0) {
/* straight over operation */
@@ -64,10 +62,10 @@ MINLINE void blend_color_mix_byte(unsigned char dst[4],
tmp[2] = (mt * src1[3] * src1[2]) + (t * 255 * src2[2]);
tmp[3] = (mt * src1[3]) + (t * 255);
- dst[0] = (unsigned char)divide_round_i(tmp[0], tmp[3]);
- dst[1] = (unsigned char)divide_round_i(tmp[1], tmp[3]);
- dst[2] = (unsigned char)divide_round_i(tmp[2], tmp[3]);
- dst[3] = (unsigned char)divide_round_i(tmp[3], 255);
+ dst[0] = (uchar)divide_round_i(tmp[0], tmp[3]);
+ dst[1] = (uchar)divide_round_i(tmp[1], tmp[3]);
+ dst[2] = (uchar)divide_round_i(tmp[2], tmp[3]);
+ dst[3] = (uchar)divide_round_i(tmp[3], 255);
}
else {
/* no op */
@@ -75,9 +73,7 @@ MINLINE void blend_color_mix_byte(unsigned char dst[4],
}
}
-MINLINE void blend_color_add_byte(unsigned char dst[4],
- const unsigned char src1[4],
- const unsigned char src2[4])
+MINLINE void blend_color_add_byte(uchar dst[4], const uchar src1[4], const uchar src2[4])
{
if (src2[3] != 0) {
/* straight add operation */
@@ -88,9 +84,9 @@ MINLINE void blend_color_add_byte(unsigned char dst[4],
tmp[1] = (src1[1] * 255) + (src2[1] * t);
tmp[2] = (src1[2] * 255) + (src2[2] * t);
- dst[0] = (unsigned char)min_ii(divide_round_i(tmp[0], 255), 255);
- dst[1] = (unsigned char)min_ii(divide_round_i(tmp[1], 255), 255);
- dst[2] = (unsigned char)min_ii(divide_round_i(tmp[2], 255), 255);
+ dst[0] = (uchar)min_ii(divide_round_i(tmp[0], 255), 255);
+ dst[1] = (uchar)min_ii(divide_round_i(tmp[1], 255), 255);
+ dst[2] = (uchar)min_ii(divide_round_i(tmp[2], 255), 255);
dst[3] = src1[3];
}
else {
@@ -99,9 +95,7 @@ MINLINE void blend_color_add_byte(unsigned char dst[4],
}
}
-MINLINE void blend_color_sub_byte(unsigned char dst[4],
- const unsigned char src1[4],
- const unsigned char src2[4])
+MINLINE void blend_color_sub_byte(uchar dst[4], const uchar src1[4], const uchar src2[4])
{
if (src2[3] != 0) {
/* straight sub operation */
@@ -112,9 +106,9 @@ MINLINE void blend_color_sub_byte(unsigned char dst[4],
tmp[1] = (src1[1] * 255) - (src2[1] * t);
tmp[2] = (src1[2] * 255) - (src2[2] * t);
- dst[0] = (unsigned char)max_ii(divide_round_i(tmp[0], 255), 0);
- dst[1] = (unsigned char)max_ii(divide_round_i(tmp[1], 255), 0);
- dst[2] = (unsigned char)max_ii(divide_round_i(tmp[2], 255), 0);
+ dst[0] = (uchar)max_ii(divide_round_i(tmp[0], 255), 0);
+ dst[1] = (uchar)max_ii(divide_round_i(tmp[1], 255), 0);
+ dst[2] = (uchar)max_ii(divide_round_i(tmp[2], 255), 0);
dst[3] = src1[3];
}
else {
@@ -123,9 +117,7 @@ MINLINE void blend_color_sub_byte(unsigned char dst[4],
}
}
-MINLINE void blend_color_mul_byte(unsigned char dst[4],
- const unsigned char src1[4],
- const unsigned char src2[4])
+MINLINE void blend_color_mul_byte(uchar dst[4], const uchar src1[4], const uchar src2[4])
{
if (src2[3] != 0) {
/* straight multiply operation */
@@ -137,9 +129,9 @@ MINLINE void blend_color_mul_byte(unsigned char dst[4],
tmp[1] = (mt * src1[1] * 255) + (t * src1[1] * src2[1]);
tmp[2] = (mt * src1[2] * 255) + (t * src1[2] * src2[2]);
- dst[0] = (unsigned char)divide_round_i(tmp[0], 255 * 255);
- dst[1] = (unsigned char)divide_round_i(tmp[1], 255 * 255);
- dst[2] = (unsigned char)divide_round_i(tmp[2], 255 * 255);
+ dst[0] = (uchar)divide_round_i(tmp[0], 255 * 255);
+ dst[1] = (uchar)divide_round_i(tmp[1], 255 * 255);
+ dst[2] = (uchar)divide_round_i(tmp[2], 255 * 255);
dst[3] = src1[3];
}
else {
@@ -148,9 +140,7 @@ MINLINE void blend_color_mul_byte(unsigned char dst[4],
}
}
-MINLINE void blend_color_lighten_byte(unsigned char dst[4],
- const unsigned char src1[4],
- const unsigned char src2[4])
+MINLINE void blend_color_lighten_byte(uchar dst[4], const uchar src1[4], const uchar src2[4])
{
if (src2[3] != 0) {
/* straight lighten operation */
@@ -162,9 +152,9 @@ MINLINE void blend_color_lighten_byte(unsigned char dst[4],
tmp[1] = (mt * src1[1]) + (t * max_ii(src1[1], src2[1]));
tmp[2] = (mt * src1[2]) + (t * max_ii(src1[2], src2[2]));
- dst[0] = (unsigned char)divide_round_i(tmp[0], 255);
- dst[1] = (unsigned char)divide_round_i(tmp[1], 255);
- dst[2] = (unsigned char)divide_round_i(tmp[2], 255);
+ dst[0] = (uchar)divide_round_i(tmp[0], 255);
+ dst[1] = (uchar)divide_round_i(tmp[1], 255);
+ dst[2] = (uchar)divide_round_i(tmp[2], 255);
dst[3] = src1[3];
}
else {
@@ -173,9 +163,7 @@ MINLINE void blend_color_lighten_byte(unsigned char dst[4],
}
}
-MINLINE void blend_color_darken_byte(unsigned char dst[4],
- const unsigned char src1[4],
- const unsigned char src2[4])
+MINLINE void blend_color_darken_byte(uchar dst[4], const uchar src1[4], const uchar src2[4])
{
if (src2[3] != 0) {
/* straight darken operation */
@@ -187,9 +175,9 @@ MINLINE void blend_color_darken_byte(unsigned char dst[4],
tmp[1] = (mt * src1[1]) + (t * min_ii(src1[1], src2[1]));
tmp[2] = (mt * src1[2]) + (t * min_ii(src1[2], src2[2]));
- dst[0] = (unsigned char)divide_round_i(tmp[0], 255);
- dst[1] = (unsigned char)divide_round_i(tmp[1], 255);
- dst[2] = (unsigned char)divide_round_i(tmp[2], 255);
+ dst[0] = (uchar)divide_round_i(tmp[0], 255);
+ dst[1] = (uchar)divide_round_i(tmp[1], 255);
+ dst[2] = (uchar)divide_round_i(tmp[2], 255);
dst[3] = src1[3];
}
else {
@@ -198,9 +186,7 @@ MINLINE void blend_color_darken_byte(unsigned char dst[4],
}
}
-MINLINE void blend_color_erase_alpha_byte(unsigned char dst[4],
- const unsigned char src1[4],
- const unsigned char src2[4])
+MINLINE void blend_color_erase_alpha_byte(uchar dst[4], const uchar src1[4], const uchar src2[4])
{
if (src2[3] != 0) {
/* straight so just modify alpha channel */
@@ -209,7 +195,7 @@ MINLINE void blend_color_erase_alpha_byte(unsigned char dst[4],
dst[0] = src1[0];
dst[1] = src1[1];
dst[2] = src1[2];
- dst[3] = (unsigned char)max_ii(src1[3] - divide_round_i(t * src2[3], 255), 0);
+ dst[3] = (uchar)max_ii(src1[3] - divide_round_i(t * src2[3], 255), 0);
}
else {
/* no op */
@@ -217,9 +203,7 @@ MINLINE void blend_color_erase_alpha_byte(unsigned char dst[4],
}
}
-MINLINE void blend_color_add_alpha_byte(unsigned char dst[4],
- const unsigned char src1[4],
- const unsigned char src2[4])
+MINLINE void blend_color_add_alpha_byte(uchar dst[4], const uchar src1[4], const uchar src2[4])
{
if (src2[3] != 0) {
/* straight so just modify alpha channel */
@@ -228,7 +212,7 @@ MINLINE void blend_color_add_alpha_byte(unsigned char dst[4],
dst[0] = src1[0];
dst[1] = src1[1];
dst[2] = src1[2];
- dst[3] = (unsigned char)min_ii(src1[3] + divide_round_i(t * src2[3], 255), 255);
+ dst[3] = (uchar)min_ii(src1[3] + divide_round_i(t * src2[3], 255), 255);
}
else {
/* no op */
@@ -236,9 +220,7 @@ MINLINE void blend_color_add_alpha_byte(unsigned char dst[4],
}
}
-MINLINE void blend_color_overlay_byte(unsigned char dst[4],
- unsigned const char src1[4],
- unsigned const char src2[4])
+MINLINE void blend_color_overlay_byte(uchar dst[4], const uchar src1[4], const uchar src2[4])
{
const int fac = (int)src2[3];
if (fac != 0) {
@@ -254,7 +236,7 @@ MINLINE void blend_color_overlay_byte(unsigned char dst[4],
else {
temp = (2 * src1[i] * src2[i]) >> 8;
}
- dst[i] = (unsigned char)min_ii((temp * fac + src1[i] * mfac) / 255, 255);
+ dst[i] = (uchar)min_ii((temp * fac + src1[i] * mfac) / 255, 255);
}
}
else {
@@ -263,9 +245,7 @@ MINLINE void blend_color_overlay_byte(unsigned char dst[4],
}
}
-MINLINE void blend_color_hardlight_byte(unsigned char dst[4],
- unsigned const char src1[4],
- unsigned const char src2[4])
+MINLINE void blend_color_hardlight_byte(uchar dst[4], const uchar src1[4], const uchar src2[4])
{
const int fac = (int)src2[3];
if (fac != 0) {
@@ -281,7 +261,7 @@ MINLINE void blend_color_hardlight_byte(unsigned char dst[4],
else {
temp = (2 * src2[i] * src1[i]) >> 8;
}
- dst[i] = (unsigned char)min_ii((temp * fac + src1[i] * mfac) / 255, 255);
+ dst[i] = (uchar)min_ii((temp * fac + src1[i] * mfac) / 255, 255);
}
}
else {
@@ -290,9 +270,7 @@ MINLINE void blend_color_hardlight_byte(unsigned char dst[4],
}
}
-MINLINE void blend_color_burn_byte(unsigned char dst[4],
- unsigned const char src1[4],
- unsigned const char src2[4])
+MINLINE void blend_color_burn_byte(uchar dst[4], const uchar src1[4], const uchar src2[4])
{
const int fac = src2[3];
if (fac != 0) {
@@ -301,7 +279,7 @@ MINLINE void blend_color_burn_byte(unsigned char dst[4],
while (i--) {
const int temp = (src2[i] == 0) ? 0 : max_ii(255 - ((255 - src1[i]) * 255) / src2[i], 0);
- dst[i] = (unsigned char)((temp * fac + src1[i] * mfac) / 255);
+ dst[i] = (uchar)((temp * fac + src1[i] * mfac) / 255);
}
}
else {
@@ -310,9 +288,7 @@ MINLINE void blend_color_burn_byte(unsigned char dst[4],
}
}
-MINLINE void blend_color_linearburn_byte(unsigned char dst[4],
- unsigned const char src1[4],
- unsigned const char src2[4])
+MINLINE void blend_color_linearburn_byte(uchar dst[4], const uchar src1[4], const uchar src2[4])
{
const int fac = src2[3];
if (fac != 0) {
@@ -321,7 +297,7 @@ MINLINE void blend_color_linearburn_byte(unsigned char dst[4],
while (i--) {
const int temp = max_ii(src1[i] + src2[i] - 255, 0);
- dst[i] = (unsigned char)((temp * fac + src1[i] * mfac) / 255);
+ dst[i] = (uchar)((temp * fac + src1[i] * mfac) / 255);
}
}
else {
@@ -330,9 +306,7 @@ MINLINE void blend_color_linearburn_byte(unsigned char dst[4],
}
}
-MINLINE void blend_color_dodge_byte(unsigned char dst[4],
- unsigned const char src1[4],
- unsigned const char src2[4])
+MINLINE void blend_color_dodge_byte(uchar dst[4], const uchar src1[4], const uchar src2[4])
{
const int fac = src2[3];
if (fac != 0) {
@@ -341,7 +315,7 @@ MINLINE void blend_color_dodge_byte(unsigned char dst[4],
while (i--) {
const int temp = (src2[i] == 255) ? 255 : min_ii((src1[i] * 255) / (255 - src2[i]), 255);
- dst[i] = (unsigned char)((temp * fac + src1[i] * mfac) / 255);
+ dst[i] = (uchar)((temp * fac + src1[i] * mfac) / 255);
}
}
else {
@@ -350,9 +324,7 @@ MINLINE void blend_color_dodge_byte(unsigned char dst[4],
}
}
-MINLINE void blend_color_screen_byte(unsigned char dst[4],
- unsigned const char src1[4],
- unsigned const char src2[4])
+MINLINE void blend_color_screen_byte(uchar dst[4], const uchar src1[4], const uchar src2[4])
{
const int fac = src2[3];
if (fac != 0) {
@@ -361,7 +333,7 @@ MINLINE void blend_color_screen_byte(unsigned char dst[4],
while (i--) {
const int temp = max_ii(255 - (((255 - src1[i]) * (255 - src2[i])) / 255), 0);
- dst[i] = (unsigned char)((temp * fac + src1[i] * mfac) / 255);
+ dst[i] = (uchar)((temp * fac + src1[i] * mfac) / 255);
}
}
else {
@@ -370,9 +342,7 @@ MINLINE void blend_color_screen_byte(unsigned char dst[4],
}
}
-MINLINE void blend_color_softlight_byte(unsigned char dst[4],
- unsigned const char src1[4],
- unsigned const char src2[4])
+MINLINE void blend_color_softlight_byte(uchar dst[4], const uchar src1[4], const uchar src2[4])
{
const int fac = src2[3];
if (fac != 0) {
@@ -388,7 +358,7 @@ MINLINE void blend_color_softlight_byte(unsigned char dst[4],
else {
temp = 255 - (2 * (255 - ((src2[i] / 2) + 64)) * (255 - src1[i]) / 255);
}
- dst[i] = (unsigned char)((temp * fac + src1[i] * mfac) / 255);
+ dst[i] = (uchar)((temp * fac + src1[i] * mfac) / 255);
}
}
else {
@@ -397,9 +367,7 @@ MINLINE void blend_color_softlight_byte(unsigned char dst[4],
}
}
-MINLINE void blend_color_pinlight_byte(unsigned char dst[4],
- unsigned const char src1[4],
- unsigned const char src2[4])
+MINLINE void blend_color_pinlight_byte(uchar dst[4], const uchar src1[4], const uchar src2[4])
{
const int fac = src2[3];
if (fac != 0) {
@@ -415,7 +383,7 @@ MINLINE void blend_color_pinlight_byte(unsigned char dst[4],
else {
temp = min_ii(2 * src2[i], src1[i]);
}
- dst[i] = (unsigned char)((temp * fac + src1[i] * mfac) / 255);
+ dst[i] = (uchar)((temp * fac + src1[i] * mfac) / 255);
}
}
else {
@@ -424,9 +392,7 @@ MINLINE void blend_color_pinlight_byte(unsigned char dst[4],
}
}
-MINLINE void blend_color_linearlight_byte(unsigned char dst[4],
- unsigned const char src1[4],
- unsigned const char src2[4])
+MINLINE void blend_color_linearlight_byte(uchar dst[4], const uchar src1[4], const uchar src2[4])
{
const int fac = src2[3];
if (fac != 0) {
@@ -442,7 +408,7 @@ MINLINE void blend_color_linearlight_byte(unsigned char dst[4],
else {
temp = max_ii(src1[i] + 2 * src2[i] - 255, 0);
}
- dst[i] = (unsigned char)((temp * fac + src1[i] * mfac) / 255);
+ dst[i] = (uchar)((temp * fac + src1[i] * mfac) / 255);
}
}
else {
@@ -451,9 +417,7 @@ MINLINE void blend_color_linearlight_byte(unsigned char dst[4],
}
}
-MINLINE void blend_color_vividlight_byte(unsigned char dst[4],
- unsigned const char src1[4],
- unsigned const char src2[4])
+MINLINE void blend_color_vividlight_byte(uchar dst[4], const uchar src1[4], const uchar src2[4])
{
const int fac = src2[3];
if (fac != 0) {
@@ -475,7 +439,7 @@ MINLINE void blend_color_vividlight_byte(unsigned char dst[4],
else {
temp = max_ii(255 - ((255 - src1[i]) * 255 / (2 * src2[i])), 0);
}
- dst[i] = (unsigned char)((temp * fac + src1[i] * mfac) / 255);
+ dst[i] = (uchar)((temp * fac + src1[i] * mfac) / 255);
}
}
else {
@@ -484,9 +448,7 @@ MINLINE void blend_color_vividlight_byte(unsigned char dst[4],
}
}
-MINLINE void blend_color_difference_byte(unsigned char dst[4],
- unsigned const char src1[4],
- unsigned const char src2[4])
+MINLINE void blend_color_difference_byte(uchar dst[4], const uchar src1[4], const uchar src2[4])
{
const int fac = src2[3];
if (fac != 0) {
@@ -495,7 +457,7 @@ MINLINE void blend_color_difference_byte(unsigned char dst[4],
while (i--) {
const int temp = abs(src1[i] - src2[i]);
- dst[i] = (unsigned char)((temp * fac + src1[i] * mfac) / 255);
+ dst[i] = (uchar)((temp * fac + src1[i] * mfac) / 255);
}
}
else {
@@ -504,9 +466,7 @@ MINLINE void blend_color_difference_byte(unsigned char dst[4],
}
}
-MINLINE void blend_color_exclusion_byte(unsigned char dst[4],
- unsigned const char src1[4],
- unsigned const char src2[4])
+MINLINE void blend_color_exclusion_byte(uchar dst[4], const uchar src1[4], const uchar src2[4])
{
const int fac = src2[3];
if (fac != 0) {
@@ -515,7 +475,7 @@ MINLINE void blend_color_exclusion_byte(unsigned char dst[4],
while (i--) {
const int temp = 127 - ((2 * (src1[i] - 127) * (src2[i] - 127)) / 255);
- dst[i] = (unsigned char)((temp * fac + src1[i] * mfac) / 255);
+ dst[i] = (uchar)((temp * fac + src1[i] * mfac) / 255);
}
}
else {
@@ -524,9 +484,7 @@ MINLINE void blend_color_exclusion_byte(unsigned char dst[4],
}
}
-MINLINE void blend_color_color_byte(unsigned char dst[4],
- unsigned const char src1[4],
- unsigned const char src2[4])
+MINLINE void blend_color_color_byte(uchar dst[4], const uchar src1[4], const uchar src2[4])
{
const int fac = src2[3];
if (fac != 0) {
@@ -542,9 +500,9 @@ MINLINE void blend_color_color_byte(unsigned char dst[4],
hsv_to_rgb(h1, s1, v1, &r, &g, &b);
- dst[0] = (unsigned char)(((int)(r * 255.0f) * fac + src1[0] * mfac) / 255);
- dst[1] = (unsigned char)(((int)(g * 255.0f) * fac + src1[1] * mfac) / 255);
- dst[2] = (unsigned char)(((int)(b * 255.0f) * fac + src1[2] * mfac) / 255);
+ dst[0] = (uchar)(((int)(r * 255.0f) * fac + src1[0] * mfac) / 255);
+ dst[1] = (uchar)(((int)(g * 255.0f) * fac + src1[1] * mfac) / 255);
+ dst[2] = (uchar)(((int)(b * 255.0f) * fac + src1[2] * mfac) / 255);
}
else {
/* no op */
@@ -552,9 +510,7 @@ MINLINE void blend_color_color_byte(unsigned char dst[4],
}
}
-MINLINE void blend_color_hue_byte(unsigned char dst[4],
- unsigned const char src1[4],
- unsigned const char src2[4])
+MINLINE void blend_color_hue_byte(uchar dst[4], const uchar src1[4], const uchar src2[4])
{
const int fac = src2[3];
if (fac != 0) {
@@ -569,9 +525,9 @@ MINLINE void blend_color_hue_byte(unsigned char dst[4],
hsv_to_rgb(h1, s1, v1, &r, &g, &b);
- dst[0] = (unsigned char)(((int)(r * 255.0f) * fac + src1[0] * mfac) / 255);
- dst[1] = (unsigned char)(((int)(g * 255.0f) * fac + src1[1] * mfac) / 255);
- dst[2] = (unsigned char)(((int)(b * 255.0f) * fac + src1[2] * mfac) / 255);
+ dst[0] = (uchar)(((int)(r * 255.0f) * fac + src1[0] * mfac) / 255);
+ dst[1] = (uchar)(((int)(g * 255.0f) * fac + src1[1] * mfac) / 255);
+ dst[2] = (uchar)(((int)(b * 255.0f) * fac + src1[2] * mfac) / 255);
}
else {
/* no op */
@@ -579,9 +535,7 @@ MINLINE void blend_color_hue_byte(unsigned char dst[4],
}
}
-MINLINE void blend_color_saturation_byte(unsigned char dst[4],
- unsigned const char src1[4],
- unsigned const char src2[4])
+MINLINE void blend_color_saturation_byte(uchar dst[4], const uchar src1[4], const uchar src2[4])
{
const int fac = src2[3];
if (fac != 0) {
@@ -598,9 +552,9 @@ MINLINE void blend_color_saturation_byte(unsigned char dst[4],
hsv_to_rgb(h1, s1, v1, &r, &g, &b);
- dst[0] = (unsigned char)(((int)(r * 255.0f) * fac + src1[0] * mfac) / 255);
- dst[1] = (unsigned char)(((int)(g * 255.0f) * fac + src1[1] * mfac) / 255);
- dst[2] = (unsigned char)(((int)(b * 255.0f) * fac + src1[2] * mfac) / 255);
+ dst[0] = (uchar)(((int)(r * 255.0f) * fac + src1[0] * mfac) / 255);
+ dst[1] = (uchar)(((int)(g * 255.0f) * fac + src1[1] * mfac) / 255);
+ dst[2] = (uchar)(((int)(b * 255.0f) * fac + src1[2] * mfac) / 255);
}
else {
/* no op */
@@ -608,9 +562,7 @@ MINLINE void blend_color_saturation_byte(unsigned char dst[4],
}
}
-MINLINE void blend_color_luminosity_byte(unsigned char dst[4],
- unsigned const char src1[4],
- unsigned const char src2[4])
+MINLINE void blend_color_luminosity_byte(uchar dst[4], const uchar src1[4], const uchar src2[4])
{
const int fac = src2[3];
if (fac != 0) {
@@ -625,9 +577,9 @@ MINLINE void blend_color_luminosity_byte(unsigned char dst[4],
hsv_to_rgb(h1, s1, v1, &r, &g, &b);
- dst[0] = (unsigned char)(((int)(r * 255.0f) * fac + src1[0] * mfac) / 255);
- dst[1] = (unsigned char)(((int)(g * 255.0f) * fac + src1[1] * mfac) / 255);
- dst[2] = (unsigned char)(((int)(b * 255.0f) * fac + src1[2] * mfac) / 255);
+ dst[0] = (uchar)(((int)(r * 255.0f) * fac + src1[0] * mfac) / 255);
+ dst[1] = (uchar)(((int)(g * 255.0f) * fac + src1[1] * mfac) / 255);
+ dst[2] = (uchar)(((int)(b * 255.0f) * fac + src1[2] * mfac) / 255);
}
else {
/* no op */
@@ -635,9 +587,9 @@ MINLINE void blend_color_luminosity_byte(unsigned char dst[4],
}
}
-MINLINE void blend_color_interpolate_byte(unsigned char dst[4],
- const unsigned char src1[4],
- const unsigned char src2[4],
+MINLINE void blend_color_interpolate_byte(uchar dst[4],
+ const uchar src1[4],
+ const uchar src2[4],
float ft)
{
/* do color interpolation, but in premultiplied space so that RGB colors
@@ -647,10 +599,10 @@ MINLINE void blend_color_interpolate_byte(unsigned char dst[4],
int tmp = (mt * src1[3] + t * src2[3]);
if (tmp > 0) {
- dst[0] = (unsigned char)divide_round_i(mt * src1[0] * src1[3] + t * src2[0] * src2[3], tmp);
- dst[1] = (unsigned char)divide_round_i(mt * src1[1] * src1[3] + t * src2[1] * src2[3], tmp);
- dst[2] = (unsigned char)divide_round_i(mt * src1[2] * src1[3] + t * src2[2] * src2[3], tmp);
- dst[3] = (unsigned char)divide_round_i(tmp, 255);
+ dst[0] = (uchar)divide_round_i(mt * src1[0] * src1[3] + t * src2[0] * src2[3], tmp);
+ dst[1] = (uchar)divide_round_i(mt * src1[1] * src1[3] + t * src2[1] * src2[3], tmp);
+ dst[2] = (uchar)divide_round_i(mt * src1[2] * src1[3] + t * src2[2] * src2[3], tmp);
+ dst[3] = (uchar)divide_round_i(tmp, 255);
}
else {
copy_v4_v4_uchar(dst, src1);
diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c
index a17fecca303..e0e463615e5 100644
--- a/source/blender/blenlib/intern/math_geom.c
+++ b/source/blender/blenlib/intern/math_geom.c
@@ -4152,33 +4152,36 @@ struct Float2_Len {
static float mean_value_half_tan_v3(const struct Float3_Len *d_curr,
const struct Float3_Len *d_next)
{
- float cross[3], area;
+ float cross[3];
cross_v3_v3v3(cross, d_curr->dir, d_next->dir);
- area = len_v3(cross);
- if (LIKELY(fabsf(area) > FLT_EPSILON)) {
+ const float area = len_v3(cross);
+ /* Compare against zero since 'FLT_EPSILON' can be too large, see: T73348. */
+ if (LIKELY(area != 0.0f)) {
const float dot = dot_v3v3(d_curr->dir, d_next->dir);
const float len = d_curr->len * d_next->len;
- return (len - dot) / area;
- }
- else {
- return 0.0f;
+ const float result = (len - dot) / area;
+ if (isfinite(result)) {
+ return result;
+ }
}
+ return 0.0f;
}
static float mean_value_half_tan_v2(const struct Float2_Len *d_curr,
const struct Float2_Len *d_next)
{
- float area;
/* different from the 3d version but still correct */
- area = cross_v2v2(d_curr->dir, d_next->dir);
- if (LIKELY(fabsf(area) > FLT_EPSILON)) {
+ const float area = cross_v2v2(d_curr->dir, d_next->dir);
+ /* Compare against zero since 'FLT_EPSILON' can be too large, see: T73348. */
+ if (LIKELY(area != 0.0f)) {
const float dot = dot_v2v2(d_curr->dir, d_next->dir);
const float len = d_curr->len * d_next->len;
- return (len - dot) / area;
- }
- else {
- return 0.0f;
+ const float result = (len - dot) / area;
+ if (isfinite(result)) {
+ return result;
+ }
}
+ return 0.0f;
}
void interp_weights_poly_v3(float *w, float v[][3], const int n, const float co[3])
diff --git a/source/blender/blenlib/intern/math_vector.c b/source/blender/blenlib/intern/math_vector.c
index 55f21250659..5919b7e1dd6 100644
--- a/source/blender/blenlib/intern/math_vector.c
+++ b/source/blender/blenlib/intern/math_vector.c
@@ -240,10 +240,7 @@ void interp_v3_v3v3v3_uv(
p[2] = v1[2] + ((v2[2] - v1[2]) * uv[0]) + ((v3[2] - v1[2]) * uv[1]);
}
-void interp_v3_v3v3_uchar(char unsigned target[3],
- const unsigned char a[3],
- const unsigned char b[3],
- const float t)
+void interp_v3_v3v3_uchar(uchar target[3], const uchar a[3], const uchar b[3], const float t)
{
const float s = 1.0f - t;
@@ -253,14 +250,10 @@ void interp_v3_v3v3_uchar(char unsigned target[3],
}
void interp_v3_v3v3_char(char target[3], const char a[3], const char b[3], const float t)
{
- interp_v3_v3v3_uchar(
- (unsigned char *)target, (const unsigned char *)a, (const unsigned char *)b, t);
+ interp_v3_v3v3_uchar((uchar *)target, (const uchar *)a, (const uchar *)b, t);
}
-void interp_v4_v4v4_uchar(char unsigned target[4],
- const unsigned char a[4],
- const unsigned char b[4],
- const float t)
+void interp_v4_v4v4_uchar(uchar target[4], const uchar a[4], const uchar b[4], const float t)
{
const float s = 1.0f - t;
@@ -271,8 +264,7 @@ void interp_v4_v4v4_uchar(char unsigned target[4],
}
void interp_v4_v4v4_char(char target[4], const char a[4], const char b[4], const float t)
{
- interp_v4_v4v4_uchar(
- (unsigned char *)target, (const unsigned char *)a, (const unsigned char *)b, t);
+ interp_v4_v4v4_uchar((uchar *)target, (const uchar *)a, (const uchar *)b, t);
}
void mid_v3_v3v3(float v[3], const float v1[3], const float v2[3])
@@ -303,12 +295,12 @@ void mid_v3_v3v3v3v3(
v[2] = (v1[2] + v2[2] + v3[2] + v4[2]) / 4.0f;
}
-void mid_v3_v3_array(float r[3], const float (*vec_arr)[3], const unsigned int nbr)
+void mid_v3_v3_array(float r[3], const float (*vec_arr)[3], const uint nbr)
{
const float factor = 1.0f / (float)nbr;
zero_v3(r);
- for (unsigned int i = 0; i < nbr; i++) {
+ for (uint i = 0; i < nbr; i++) {
madd_v3_v3fl(r, vec_arr[i], factor);
}
}
@@ -1119,10 +1111,10 @@ void range_vn_i(int *array_tar, const int size, const int start)
}
}
-void range_vn_u(unsigned int *array_tar, const int size, const unsigned int start)
+void range_vn_u(uint *array_tar, const int size, const uint start)
{
- unsigned int *array_pt = array_tar + (size - 1);
- unsigned int j = start + (unsigned int)(size - 1);
+ uint *array_pt = array_tar + (size - 1);
+ uint j = start + (uint)(size - 1);
int i = size;
while (i--) {
*(array_pt--) = j--;
@@ -1329,18 +1321,18 @@ void copy_vn_short(short *array_tar, const int size, const short val)
}
}
-void copy_vn_ushort(unsigned short *array_tar, const int size, const unsigned short val)
+void copy_vn_ushort(ushort *array_tar, const int size, const ushort val)
{
- unsigned short *tar = array_tar + (size - 1);
+ ushort *tar = array_tar + (size - 1);
int i = size;
while (i--) {
*(tar--) = val;
}
}
-void copy_vn_uchar(unsigned char *array_tar, const int size, const unsigned char val)
+void copy_vn_uchar(uchar *array_tar, const int size, const uchar val)
{
- unsigned char *tar = array_tar + (size - 1);
+ uchar *tar = array_tar + (size - 1);
int i = size;
while (i--) {
*(tar--) = val;
diff --git a/source/blender/blenlib/intern/string_utf8.c b/source/blender/blenlib/intern/string_utf8.c
index 63657f33bba..7fc95a33092 100644
--- a/source/blender/blenlib/intern/string_utf8.c
+++ b/source/blender/blenlib/intern/string_utf8.c
@@ -600,7 +600,7 @@ uint BLI_str_utf8_as_unicode(const char *p)
uint BLI_str_utf8_as_unicode_and_size(const char *__restrict p, size_t *__restrict index)
{
int i, len;
- unsigned mask = 0;
+ uint mask = 0;
uint result;
const unsigned char c = (unsigned char)*p;
diff --git a/source/blender/blenlib/intern/string_utils.c b/source/blender/blenlib/intern/string_utils.c
index b956e1c0a7e..85cb32b6457 100644
--- a/source/blender/blenlib/intern/string_utils.c
+++ b/source/blender/blenlib/intern/string_utils.c
@@ -410,12 +410,30 @@ bool BLI_uniquename(
/** \name Join Strings
*
* For non array versions of these functions, use the macros:
+ * - #BLI_string_join
* - #BLI_string_joinN
* - #BLI_string_join_by_sep_charN
* - #BLI_string_join_by_sep_char_with_tableN
*
* \{ */
+char *BLI_string_join_array(char *result,
+ size_t result_len,
+ const char *strings[],
+ uint strings_len)
+{
+ char *c = result;
+ char *c_end = &result[result_len - 1];
+ for (uint i = 0; i < strings_len; i++) {
+ const char *p = strings[i];
+ while (*p && (c < c_end)) {
+ *c++ = *p++;
+ }
+ }
+ *c = '\0';
+ return c;
+}
+
/**
* Join an array of strings into a newly allocated, null terminated string.
*/