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:
Diffstat (limited to 'tests/gtests')
-rw-r--r--tests/gtests/alembic/CMakeLists.txt2
-rw-r--r--tests/gtests/alembic/abc_export_test.cc213
-rw-r--r--tests/gtests/alembic/abc_matrix_test.cc8
-rw-r--r--tests/gtests/blenlib/BLI_array_test.cc69
-rw-r--r--tests/gtests/blenlib/BLI_edgehash_test.cc3
-rw-r--r--tests/gtests/blenlib/BLI_index_mask_test.cc4
-rw-r--r--tests/gtests/blenlib/BLI_index_range_test.cc74
-rw-r--r--tests/gtests/blenlib/BLI_linear_allocator_test.cc16
-rw-r--r--tests/gtests/blenlib/BLI_map_test.cc93
-rw-r--r--tests/gtests/blenlib/BLI_math_matrix_test.cc99
-rw-r--r--tests/gtests/blenlib/BLI_optional_test.cc61
-rw-r--r--tests/gtests/blenlib/BLI_set_test.cc42
-rw-r--r--tests/gtests/blenlib/BLI_span_test.cc64
-rw-r--r--tests/gtests/blenlib/BLI_stack_cxx_test.cc44
-rw-r--r--tests/gtests/blenlib/BLI_string_ref_test.cc38
-rw-r--r--tests/gtests/blenlib/BLI_vector_set_test.cc60
-rw-r--r--tests/gtests/blenlib/BLI_vector_test.cc122
-rw-r--r--tests/gtests/blenlib/CMakeLists.txt2
-rw-r--r--tests/gtests/functions/CMakeLists.txt6
-rw-r--r--tests/gtests/functions/FN_array_spans_test.cc149
-rw-r--r--tests/gtests/functions/FN_attributes_ref_test.cc114
-rw-r--r--tests/gtests/functions/FN_cpp_type_test.cc11
-rw-r--r--tests/gtests/functions/FN_generic_vector_array_test.cc118
-rw-r--r--tests/gtests/functions/FN_multi_function_network_test.cc270
-rw-r--r--tests/gtests/functions/FN_multi_function_test.cc334
-rw-r--r--tests/gtests/functions/FN_spans_test.cc231
-rw-r--r--tests/gtests/usd/CMakeLists.txt2
-rw-r--r--tests/gtests/usd/abstract_hierarchy_iterator_test.cc146
-rw-r--r--tests/gtests/usd/hierarchy_context_order_test.cc4
29 files changed, 1941 insertions, 458 deletions
diff --git a/tests/gtests/alembic/CMakeLists.txt b/tests/gtests/alembic/CMakeLists.txt
index 6ba1c4465d9..90f1829fc77 100644
--- a/tests/gtests/alembic/CMakeLists.txt
+++ b/tests/gtests/alembic/CMakeLists.txt
@@ -24,6 +24,8 @@ set(INC
../../../source/blender/blenlib
../../../source/blender/blenkernel
../../../source/blender/io/alembic
+ ../../../source/blender/io/common
+ ../../../source/blender/io/usd/intern
../../../source/blender/makesdna
../../../source/blender/depsgraph
${ALEMBIC_INCLUDE_DIRS}
diff --git a/tests/gtests/alembic/abc_export_test.cc b/tests/gtests/alembic/abc_export_test.cc
index 238fab2f872..cdc98178550 100644
--- a/tests/gtests/alembic/abc_export_test.cc
+++ b/tests/gtests/alembic/abc_export_test.cc
@@ -1,11 +1,12 @@
#include "testing/testing.h"
// Keep first since utildefines defines AT which conflicts with STL
-#include "intern/abc_exporter.h"
+#include "exporter/abc_archive.h"
#include "intern/abc_util.h"
extern "C" {
#include "BKE_main.h"
+#include "BLI_fileops.h"
#include "BLI_math.h"
#include "BLI_utildefines.h"
#include "DNA_scene_types.h"
@@ -13,138 +14,150 @@ extern "C" {
#include "DEG_depsgraph.h"
-class TestableAbcExporter : public AbcExporter {
- public:
- TestableAbcExporter(Main *bmain, const char *filename, ExportSettings &settings)
- : AbcExporter(bmain, filename, settings)
- {
- }
-
- void getShutterSamples(unsigned int nr_of_samples,
- bool time_relative,
- std::vector<double> &samples)
- {
- AbcExporter::getShutterSamples(nr_of_samples, time_relative, samples);
- }
-
- void getFrameSet(unsigned int nr_of_samples, std::set<double> &frames)
- {
- AbcExporter::getFrameSet(nr_of_samples, frames);
- }
-};
+namespace blender {
+namespace io {
+namespace alembic {
class AlembicExportTest : public testing::Test {
protected:
- ExportSettings settings;
+ ABCArchive *abc_archive;
+
+ AlembicExportParams params;
Scene scene;
Depsgraph *depsgraph;
- TestableAbcExporter *exporter;
Main *bmain;
virtual void SetUp()
{
- settings.frame_start = 31.0;
- settings.frame_end = 223.0;
+ abc_archive = nullptr;
/* Fake a 25 FPS scene with a nonzero base (because that's sometimes forgotten) */
scene.r.frs_sec = 50;
scene.r.frs_sec_base = 2;
+ strcpy(scene.id.name, "SCTestScene");
bmain = BKE_main_new();
/* TODO(sergey): Pass scene layer somehow? */
ViewLayer *view_layer = (ViewLayer *)scene.view_layers.first;
- settings.depsgraph = depsgraph = DEG_graph_new(bmain, &scene, view_layer, DAG_EVAL_VIEWPORT);
-
- settings.scene = &scene;
- settings.view_layer = view_layer;
-
- exporter = NULL;
+ depsgraph = DEG_graph_new(bmain, &scene, view_layer, DAG_EVAL_RENDER);
}
virtual void TearDown()
{
BKE_main_free(bmain);
DEG_graph_free(depsgraph);
- delete exporter;
+ deleteArchive();
+ }
+
+ // Call after setting up the parameters.
+ void createArchive()
+ {
+ if (abc_archive != nullptr) {
+ deleteArchive();
+ }
+ abc_archive = new ABCArchive(bmain, &scene, params, "somefile.abc");
}
- // Call after setting up the settings.
- void createExporter()
+ void deleteArchive()
{
- exporter = new TestableAbcExporter(bmain, "somefile.abc", settings);
+ delete abc_archive;
+ if (BLI_exists("somefile.abc")) {
+ BLI_delete("somefile.abc", false, false);
+ }
+ abc_archive = nullptr;
}
};
-TEST_F(AlembicExportTest, TimeSamplesFullShutter)
+TEST_F(AlembicExportTest, TimeSamplesFullShutterUniform)
{
- settings.shutter_open = 0.0;
- settings.shutter_close = 1.0;
-
- createExporter();
- std::vector<double> samples;
-
- /* test 5 samples per frame */
- exporter->getShutterSamples(5, true, samples);
- EXPECT_EQ(5, samples.size());
- EXPECT_NEAR(1.240, samples[0], 1e-5f);
- EXPECT_NEAR(1.248, samples[1], 1e-5f);
- EXPECT_NEAR(1.256, samples[2], 1e-5f);
- EXPECT_NEAR(1.264, samples[3], 1e-5f);
- EXPECT_NEAR(1.272, samples[4], 1e-5f);
-
- /* test same, but using frame number offset instead of time */
- exporter->getShutterSamples(5, false, samples);
- EXPECT_EQ(5, samples.size());
- EXPECT_NEAR(0.0, samples[0], 1e-5f);
- EXPECT_NEAR(0.2, samples[1], 1e-5f);
- EXPECT_NEAR(0.4, samples[2], 1e-5f);
- EXPECT_NEAR(0.6, samples[3], 1e-5f);
- EXPECT_NEAR(0.8, samples[4], 1e-5f);
-
- /* use the same setup to test getFrameSet() */
- std::set<double> frames;
- exporter->getFrameSet(5, frames);
- EXPECT_EQ(965, frames.size());
- EXPECT_EQ(1, frames.count(31.0));
- EXPECT_EQ(1, frames.count(31.2));
- EXPECT_EQ(1, frames.count(31.4));
- EXPECT_EQ(1, frames.count(31.6));
- EXPECT_EQ(1, frames.count(31.8));
+ /* Test 5 samples per frame, for 2 frames. */
+ params.shutter_open = 0.0;
+ params.shutter_close = 1.0;
+ params.frame_start = 31.0;
+ params.frame_end = 32.0;
+ params.frame_samples_xform = params.frame_samples_shape = 5;
+ createArchive();
+ std::vector<double> frames(abc_archive->frames_begin(), abc_archive->frames_end());
+ EXPECT_EQ(10, frames.size());
+ EXPECT_NEAR(31.0, frames[0], 1e-5);
+ EXPECT_NEAR(31.2, frames[1], 1e-5);
+ EXPECT_NEAR(31.4, frames[2], 1e-5);
+ EXPECT_NEAR(31.6, frames[3], 1e-5);
+ EXPECT_NEAR(31.8, frames[4], 1e-5);
+ EXPECT_NEAR(32.0, frames[5], 1e-5);
+ EXPECT_NEAR(32.2, frames[6], 1e-5);
+ EXPECT_NEAR(32.4, frames[7], 1e-5);
+ EXPECT_NEAR(32.6, frames[8], 1e-5);
+ EXPECT_NEAR(32.8, frames[9], 1e-5);
+
+ for (double frame : frames) {
+ EXPECT_TRUE(abc_archive->is_xform_frame(frame));
+ EXPECT_TRUE(abc_archive->is_shape_frame(frame));
+ }
+}
+
+TEST_F(AlembicExportTest, TimeSamplesFullShutterDifferent)
+{
+ /* Test 3 samples per frame for transforms, and 2 per frame for shapes, for 2 frames. */
+ params.shutter_open = 0.0;
+ params.shutter_close = 1.0;
+ params.frame_start = 31.0;
+ params.frame_end = 32.0;
+ params.frame_samples_xform = 3;
+ params.frame_samples_shape = 2;
+ createArchive();
+ std::vector<double> frames(abc_archive->frames_begin(), abc_archive->frames_end());
+ EXPECT_EQ(8, frames.size());
+ EXPECT_NEAR(31.0, frames[0], 1e-5); // transform + shape
+ EXPECT_TRUE(abc_archive->is_xform_frame(frames[0]));
+ EXPECT_TRUE(abc_archive->is_shape_frame(frames[0]));
+ EXPECT_NEAR(31.33333, frames[1], 1e-5); // transform
+ EXPECT_TRUE(abc_archive->is_xform_frame(frames[1]));
+ EXPECT_FALSE(abc_archive->is_shape_frame(frames[1]));
+ EXPECT_NEAR(31.5, frames[2], 1e-5); // shape
+ EXPECT_FALSE(abc_archive->is_xform_frame(frames[2]));
+ EXPECT_TRUE(abc_archive->is_shape_frame(frames[2]));
+ EXPECT_NEAR(31.66666, frames[3], 1e-5); // transform
+ EXPECT_TRUE(abc_archive->is_xform_frame(frames[3]));
+ EXPECT_FALSE(abc_archive->is_shape_frame(frames[3]));
+ EXPECT_NEAR(32.0, frames[4], 1e-5); // transform + shape
+ EXPECT_TRUE(abc_archive->is_xform_frame(frames[4]));
+ EXPECT_TRUE(abc_archive->is_shape_frame(frames[4]));
+ EXPECT_NEAR(32.33333, frames[5], 1e-5); // transform
+ EXPECT_TRUE(abc_archive->is_xform_frame(frames[5]));
+ EXPECT_FALSE(abc_archive->is_shape_frame(frames[5]));
+ EXPECT_NEAR(32.5, frames[6], 1e-5); // shape
+ EXPECT_FALSE(abc_archive->is_xform_frame(frames[6]));
+ EXPECT_TRUE(abc_archive->is_shape_frame(frames[6]));
+ EXPECT_NEAR(32.66666, frames[7], 1e-5); // transform
+ EXPECT_TRUE(abc_archive->is_xform_frame(frames[7]));
+ EXPECT_FALSE(abc_archive->is_shape_frame(frames[7]));
}
TEST_F(AlembicExportTest, TimeSamples180degShutter)
{
- settings.shutter_open = -0.25;
- settings.shutter_close = 0.25;
-
- createExporter();
- std::vector<double> samples;
-
- /* test 5 samples per frame */
- exporter->getShutterSamples(5, true, samples);
- EXPECT_EQ(5, samples.size());
- EXPECT_NEAR(1.230, samples[0], 1e-5f);
- EXPECT_NEAR(1.234, samples[1], 1e-5f);
- EXPECT_NEAR(1.238, samples[2], 1e-5f);
- EXPECT_NEAR(1.242, samples[3], 1e-5f);
- EXPECT_NEAR(1.246, samples[4], 1e-5f);
-
- /* test same, but using frame number offset instead of time */
- exporter->getShutterSamples(5, false, samples);
- EXPECT_EQ(5, samples.size());
- EXPECT_NEAR(-0.25, samples[0], 1e-5f);
- EXPECT_NEAR(-0.15, samples[1], 1e-5f);
- EXPECT_NEAR(-0.05, samples[2], 1e-5f);
- EXPECT_NEAR(0.05, samples[3], 1e-5f);
- EXPECT_NEAR(0.15, samples[4], 1e-5f);
-
- /* Use the same setup to test getFrameSet().
- * Here only a few numbers are tested, due to rounding issues. */
- std::set<double> frames;
- exporter->getFrameSet(5, frames);
- EXPECT_EQ(965, frames.size());
- EXPECT_EQ(1, frames.count(30.75));
- EXPECT_EQ(1, frames.count(30.95));
- EXPECT_EQ(1, frames.count(31.15));
+ /* Test 5 samples per frame, for 2 frames. */
+ params.shutter_open = -0.25;
+ params.shutter_close = 0.25;
+ params.frame_start = 31.0;
+ params.frame_end = 32.0;
+ params.frame_samples_xform = params.frame_samples_shape = 5;
+ createArchive();
+ std::vector<double> frames(abc_archive->frames_begin(), abc_archive->frames_end());
+ EXPECT_EQ(10, frames.size());
+ EXPECT_NEAR(31 - 0.25, frames[0], 1e-5);
+ EXPECT_NEAR(31 - 0.15, frames[1], 1e-5);
+ EXPECT_NEAR(31 - 0.05, frames[2], 1e-5);
+ EXPECT_NEAR(31 + 0.05, frames[3], 1e-5);
+ EXPECT_NEAR(31 + 0.15, frames[4], 1e-5);
+ EXPECT_NEAR(32 - 0.25, frames[5], 1e-5);
+ EXPECT_NEAR(32 - 0.15, frames[6], 1e-5);
+ EXPECT_NEAR(32 - 0.05, frames[7], 1e-5);
+ EXPECT_NEAR(32 + 0.05, frames[8], 1e-5);
+ EXPECT_NEAR(32 + 0.15, frames[9], 1e-5);
}
+
+} // namespace alembic
+} // namespace io
+} // namespace blender
diff --git a/tests/gtests/alembic/abc_matrix_test.cc b/tests/gtests/alembic/abc_matrix_test.cc
index 9b16eb108be..fe0635ea7ab 100644
--- a/tests/gtests/alembic/abc_matrix_test.cc
+++ b/tests/gtests/alembic/abc_matrix_test.cc
@@ -8,6 +8,10 @@ extern "C" {
#include "BLI_utildefines.h"
}
+namespace blender {
+namespace io {
+namespace alembic {
+
TEST(abc_matrix, CreateRotationMatrixY_YfromZ)
{
// Input variables
@@ -284,3 +288,7 @@ TEST(abc_matrix, CopyM44AxisSwapWithScale_gimbal_ZfromY)
EXPECT_M4_NEAR(expect, result, 1e-5f);
}
+
+} // namespace alembic
+} // namespace io
+} // namespace blender
diff --git a/tests/gtests/blenlib/BLI_array_test.cc b/tests/gtests/blenlib/BLI_array_test.cc
index fc3c15fe813..9c77c69e296 100644
--- a/tests/gtests/blenlib/BLI_array_test.cc
+++ b/tests/gtests/blenlib/BLI_array_test.cc
@@ -2,26 +2,26 @@
#include "BLI_strict_flags.h"
#include "testing/testing.h"
-using namespace blender;
+namespace blender {
TEST(array, DefaultConstructor)
{
Array<int> array;
- EXPECT_EQ(array.size(), 0);
+ EXPECT_EQ(array.size(), 0u);
EXPECT_TRUE(array.is_empty());
}
TEST(array, SizeConstructor)
{
Array<int> array(5);
- EXPECT_EQ(array.size(), 5);
+ EXPECT_EQ(array.size(), 5u);
EXPECT_FALSE(array.is_empty());
}
TEST(array, FillConstructor)
{
Array<int> array(5, 8);
- EXPECT_EQ(array.size(), 5);
+ EXPECT_EQ(array.size(), 5u);
EXPECT_EQ(array[0], 8);
EXPECT_EQ(array[1], 8);
EXPECT_EQ(array[2], 8);
@@ -32,7 +32,7 @@ TEST(array, FillConstructor)
TEST(array, InitializerListConstructor)
{
Array<int> array = {4, 5, 6, 7};
- EXPECT_EQ(array.size(), 4);
+ EXPECT_EQ(array.size(), 4u);
EXPECT_EQ(array[0], 4);
EXPECT_EQ(array[1], 5);
EXPECT_EQ(array[2], 6);
@@ -44,7 +44,7 @@ TEST(array, SpanConstructor)
int stackarray[4] = {6, 7, 8, 9};
Span<int> span(stackarray, ARRAY_SIZE(stackarray));
Array<int> array(span);
- EXPECT_EQ(array.size(), 4);
+ EXPECT_EQ(array.size(), 4u);
EXPECT_EQ(array[0], 6);
EXPECT_EQ(array[1], 7);
EXPECT_EQ(array[2], 8);
@@ -56,8 +56,8 @@ TEST(array, CopyConstructor)
Array<int> array = {5, 6, 7, 8};
Array<int> new_array(array);
- EXPECT_EQ(array.size(), 4);
- EXPECT_EQ(new_array.size(), 4);
+ EXPECT_EQ(array.size(), 4u);
+ EXPECT_EQ(new_array.size(), 4u);
EXPECT_NE(array.data(), new_array.data());
EXPECT_EQ(new_array[0], 5);
EXPECT_EQ(new_array[1], 6);
@@ -70,8 +70,8 @@ TEST(array, MoveConstructor)
Array<int> array = {5, 6, 7, 8};
Array<int> new_array(std::move(array));
- EXPECT_EQ(array.size(), 0);
- EXPECT_EQ(new_array.size(), 4);
+ EXPECT_EQ(array.size(), 0u);
+ EXPECT_EQ(new_array.size(), 4u);
EXPECT_EQ(new_array[0], 5);
EXPECT_EQ(new_array[1], 6);
EXPECT_EQ(new_array[2], 7);
@@ -82,10 +82,10 @@ TEST(array, CopyAssignment)
{
Array<int> array = {1, 2, 3};
Array<int> new_array = {4};
- EXPECT_EQ(new_array.size(), 1);
+ EXPECT_EQ(new_array.size(), 1u);
new_array = array;
- EXPECT_EQ(new_array.size(), 3);
- EXPECT_EQ(array.size(), 3);
+ EXPECT_EQ(new_array.size(), 3u);
+ EXPECT_EQ(array.size(), 3u);
EXPECT_NE(array.data(), new_array.data());
EXPECT_EQ(new_array[0], 1);
EXPECT_EQ(new_array[1], 2);
@@ -96,10 +96,10 @@ TEST(array, MoveAssignment)
{
Array<int> array = {1, 2, 3};
Array<int> new_array = {4};
- EXPECT_EQ(new_array.size(), 1);
+ EXPECT_EQ(new_array.size(), 1u);
new_array = std::move(array);
- EXPECT_EQ(new_array.size(), 3);
- EXPECT_EQ(array.size(), 0);
+ EXPECT_EQ(new_array.size(), 3u);
+ EXPECT_EQ(array.size(), 0u);
EXPECT_EQ(new_array[0], 1);
EXPECT_EQ(new_array[1], 2);
EXPECT_EQ(new_array[2], 3);
@@ -124,3 +124,40 @@ TEST(array, TrivialTypeSizeConstructor)
EXPECT_EQ(*ptr, magic);
delete array;
}
+
+struct ConstructibleType {
+ char value;
+
+ ConstructibleType()
+ {
+ value = 42;
+ }
+};
+
+TEST(array, NoInitializationSizeConstructor)
+{
+ using MyArray = Array<ConstructibleType>;
+
+ AlignedBuffer<sizeof(MyArray), alignof(MyArray)> buffer;
+ char *buffer_ptr = (char *)buffer.ptr();
+ memset(buffer_ptr, 100, sizeof(MyArray));
+
+ /* Doing this to avoid some compiler optimization. */
+ for (uint i : IndexRange(sizeof(MyArray))) {
+ EXPECT_EQ(buffer_ptr[i], 100);
+ }
+
+ {
+ MyArray &array = *new (buffer.ptr()) MyArray(1, NoInitialization());
+ EXPECT_EQ(array[0].value, 100);
+ array.clear_without_destruct();
+ array.~Array();
+ }
+ {
+ MyArray &array = *new (buffer.ptr()) MyArray(1);
+ EXPECT_EQ(array[0].value, 42);
+ array.~Array();
+ }
+}
+
+} // namespace blender
diff --git a/tests/gtests/blenlib/BLI_edgehash_test.cc b/tests/gtests/blenlib/BLI_edgehash_test.cc
index 982f5b35565..23ad618825b 100644
--- a/tests/gtests/blenlib/BLI_edgehash_test.cc
+++ b/tests/gtests/blenlib/BLI_edgehash_test.cc
@@ -2,6 +2,7 @@
#include "testing/testing.h"
#include <algorithm>
+#include <random>
#include <vector>
extern "C" {
@@ -320,7 +321,7 @@ TEST(edgehash, StressTest)
}
std::vector<Edge> shuffled = edges;
- std::random_shuffle(shuffled.begin(), shuffled.end());
+ std::shuffle(shuffled.begin(), shuffled.end(), std::default_random_engine());
/* then remove half of them */
int remove_until = shuffled.size() / 2;
diff --git a/tests/gtests/blenlib/BLI_index_mask_test.cc b/tests/gtests/blenlib/BLI_index_mask_test.cc
index 63b528c91b1..50b32be6364 100644
--- a/tests/gtests/blenlib/BLI_index_mask_test.cc
+++ b/tests/gtests/blenlib/BLI_index_mask_test.cc
@@ -1,7 +1,7 @@
#include "BLI_index_mask.hh"
#include "testing/testing.h"
-using namespace blender;
+namespace blender {
TEST(index_mask, DefaultConstructor)
{
@@ -37,3 +37,5 @@ TEST(index_mask, RangeConstructor)
EXPECT_EQ(indices[1], 4);
EXPECT_EQ(indices[2], 5);
}
+
+} // namespace blender
diff --git a/tests/gtests/blenlib/BLI_index_range_test.cc b/tests/gtests/blenlib/BLI_index_range_test.cc
index da51b7a66c0..e484da5ef42 100644
--- a/tests/gtests/blenlib/BLI_index_range_test.cc
+++ b/tests/gtests/blenlib/BLI_index_range_test.cc
@@ -3,46 +3,46 @@
#include "BLI_vector.hh"
#include "testing/testing.h"
-using namespace blender;
+namespace blender {
TEST(index_range, DefaultConstructor)
{
IndexRange range;
- EXPECT_EQ(range.size(), 0);
+ EXPECT_EQ(range.size(), 0u);
Vector<uint> vector;
for (uint value : range) {
vector.append(value);
}
- EXPECT_EQ(vector.size(), 0);
+ EXPECT_EQ(vector.size(), 0u);
}
TEST(index_range, SingleElementRange)
{
IndexRange range(4, 1);
- EXPECT_EQ(range.size(), 1);
- EXPECT_EQ(*range.begin(), 4);
+ EXPECT_EQ(range.size(), 1u);
+ EXPECT_EQ(*range.begin(), 4u);
Vector<uint> vector;
for (uint value : range) {
vector.append(value);
}
- EXPECT_EQ(vector.size(), 1);
- EXPECT_EQ(vector[0], 4);
+ EXPECT_EQ(vector.size(), 1u);
+ EXPECT_EQ(vector[0], 4u);
}
TEST(index_range, MultipleElementRange)
{
IndexRange range(6, 4);
- EXPECT_EQ(range.size(), 4);
+ EXPECT_EQ(range.size(), 4u);
Vector<uint> vector;
for (uint value : range) {
vector.append(value);
}
- EXPECT_EQ(vector.size(), 4);
+ EXPECT_EQ(vector.size(), 4u);
for (uint i = 0; i < 4; i++) {
EXPECT_EQ(vector[i], i + 6);
}
@@ -51,28 +51,28 @@ TEST(index_range, MultipleElementRange)
TEST(index_range, SubscriptOperator)
{
IndexRange range(5, 5);
- EXPECT_EQ(range[0], 5);
- EXPECT_EQ(range[1], 6);
- EXPECT_EQ(range[2], 7);
+ EXPECT_EQ(range[0], 5u);
+ EXPECT_EQ(range[1], 6u);
+ EXPECT_EQ(range[2], 7u);
}
TEST(index_range, Before)
{
IndexRange range = IndexRange(5, 5).before(3);
- EXPECT_EQ(range[0], 2);
- EXPECT_EQ(range[1], 3);
- EXPECT_EQ(range[2], 4);
- EXPECT_EQ(range.size(), 3);
+ EXPECT_EQ(range[0], 2u);
+ EXPECT_EQ(range[1], 3u);
+ EXPECT_EQ(range[2], 4u);
+ EXPECT_EQ(range.size(), 3u);
}
TEST(index_range, After)
{
IndexRange range = IndexRange(5, 5).after(4);
- EXPECT_EQ(range[0], 10);
- EXPECT_EQ(range[1], 11);
- EXPECT_EQ(range[2], 12);
- EXPECT_EQ(range[3], 13);
- EXPECT_EQ(range.size(), 4);
+ EXPECT_EQ(range[0], 10u);
+ EXPECT_EQ(range[1], 11u);
+ EXPECT_EQ(range[2], 12u);
+ EXPECT_EQ(range[3], 13u);
+ EXPECT_EQ(range.size(), 4u);
}
TEST(index_range, Contains)
@@ -88,52 +88,54 @@ TEST(index_range, Contains)
TEST(index_range, First)
{
IndexRange range = IndexRange(5, 3);
- EXPECT_EQ(range.first(), 5);
+ EXPECT_EQ(range.first(), 5u);
}
TEST(index_range, Last)
{
IndexRange range = IndexRange(5, 3);
- EXPECT_EQ(range.last(), 7);
+ EXPECT_EQ(range.last(), 7u);
}
TEST(index_range, OneAfterEnd)
{
IndexRange range = IndexRange(5, 3);
- EXPECT_EQ(range.one_after_last(), 8);
+ EXPECT_EQ(range.one_after_last(), 8u);
}
TEST(index_range, Start)
{
IndexRange range = IndexRange(6, 2);
- EXPECT_EQ(range.start(), 6);
+ EXPECT_EQ(range.start(), 6u);
}
TEST(index_range, Slice)
{
IndexRange range = IndexRange(5, 15);
IndexRange slice = range.slice(2, 6);
- EXPECT_EQ(slice.size(), 6);
- EXPECT_EQ(slice.first(), 7);
- EXPECT_EQ(slice.last(), 12);
+ EXPECT_EQ(slice.size(), 6u);
+ EXPECT_EQ(slice.first(), 7u);
+ EXPECT_EQ(slice.last(), 12u);
}
TEST(index_range, SliceRange)
{
IndexRange range = IndexRange(5, 15);
IndexRange slice = range.slice(IndexRange(3, 5));
- EXPECT_EQ(slice.size(), 5);
- EXPECT_EQ(slice.first(), 8);
- EXPECT_EQ(slice.last(), 12);
+ EXPECT_EQ(slice.size(), 5u);
+ EXPECT_EQ(slice.first(), 8u);
+ EXPECT_EQ(slice.last(), 12u);
}
TEST(index_range, AsSpan)
{
IndexRange range = IndexRange(4, 6);
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);
+ EXPECT_EQ(span.size(), 6u);
+ EXPECT_EQ(span[0], 4u);
+ EXPECT_EQ(span[1], 5u);
+ EXPECT_EQ(span[2], 6u);
+ EXPECT_EQ(span[3], 7u);
}
+
+} // namespace blender
diff --git a/tests/gtests/blenlib/BLI_linear_allocator_test.cc b/tests/gtests/blenlib/BLI_linear_allocator_test.cc
index 0d926ca7931..bbea4c1239f 100644
--- a/tests/gtests/blenlib/BLI_linear_allocator_test.cc
+++ b/tests/gtests/blenlib/BLI_linear_allocator_test.cc
@@ -2,7 +2,7 @@
#include "BLI_strict_flags.h"
#include "testing/testing.h"
-using namespace blender;
+namespace blender {
static bool is_aligned(void *ptr, uint alignment)
{
@@ -68,7 +68,7 @@ TEST(linear_allocator, AllocateArray)
LinearAllocator<> allocator;
MutableSpan<int> span = allocator.allocate_array<int>(5);
- EXPECT_EQ(span.size(), 5);
+ EXPECT_EQ(span.size(), 5u);
}
TEST(linear_allocator, Construct)
@@ -77,7 +77,7 @@ TEST(linear_allocator, Construct)
std::array<int, 5> values = {1, 2, 3, 4, 5};
Vector<int> *vector = allocator.construct<Vector<int>>(values);
- EXPECT_EQ(vector->size(), 5);
+ EXPECT_EQ(vector->size(), 5u);
EXPECT_EQ((*vector)[3], 4);
vector->~Vector();
}
@@ -90,8 +90,8 @@ TEST(linear_allocator, ConstructElementsAndPointerArray)
Span<Vector<int> *> vectors = allocator.construct_elements_and_pointer_array<Vector<int>>(
5, values);
- EXPECT_EQ(vectors.size(), 5);
- EXPECT_EQ(vectors[3]->size(), 7);
+ EXPECT_EQ(vectors.size(), 5u);
+ EXPECT_EQ(vectors[3]->size(), 7u);
EXPECT_EQ((*vectors[2])[5], 6);
for (Vector<int> *vector : vectors) {
@@ -107,8 +107,10 @@ TEST(linear_allocator, ConstructArrayCopy)
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.size(), 3u);
+ EXPECT_EQ(span2.size(), 3u);
EXPECT_EQ(span1[1], 2);
EXPECT_EQ(span2[2], 3);
}
+
+} // namespace blender
diff --git a/tests/gtests/blenlib/BLI_map_test.cc b/tests/gtests/blenlib/BLI_map_test.cc
index 96e9879abe7..3b72795d36f 100644
--- a/tests/gtests/blenlib/BLI_map_test.cc
+++ b/tests/gtests/blenlib/BLI_map_test.cc
@@ -6,25 +6,25 @@
#include "BLI_vector.hh"
#include "testing/testing.h"
-using namespace blender;
+namespace blender {
TEST(map, DefaultConstructor)
{
Map<int, float> map;
- EXPECT_EQ(map.size(), 0);
+ EXPECT_EQ(map.size(), 0u);
EXPECT_TRUE(map.is_empty());
}
TEST(map, AddIncreasesSize)
{
Map<int, float> map;
- EXPECT_EQ(map.size(), 0);
+ EXPECT_EQ(map.size(), 0u);
EXPECT_TRUE(map.is_empty());
map.add(2, 5.0f);
- EXPECT_EQ(map.size(), 1);
+ EXPECT_EQ(map.size(), 1u);
EXPECT_FALSE(map.is_empty());
map.add(6, 2.0f);
- EXPECT_EQ(map.size(), 2);
+ EXPECT_EQ(map.size(), 2u);
EXPECT_FALSE(map.is_empty());
}
@@ -87,16 +87,16 @@ TEST(map, PopTry)
Map<int, int> map;
map.add(1, 5);
map.add(2, 7);
- EXPECT_EQ(map.size(), 2);
- Optional<int> value = map.pop_try(4);
- EXPECT_EQ(map.size(), 2);
+ EXPECT_EQ(map.size(), 2u);
+ std::optional<int> value = map.pop_try(4);
+ EXPECT_EQ(map.size(), 2u);
EXPECT_FALSE(value.has_value());
value = map.pop_try(2);
- EXPECT_EQ(map.size(), 1);
+ EXPECT_EQ(map.size(), 1u);
EXPECT_TRUE(value.has_value());
- EXPECT_EQ(value.value(), 7);
+ EXPECT_EQ(*value, 7);
EXPECT_EQ(*map.pop_try(1), 5);
- EXPECT_EQ(map.size(), 0);
+ EXPECT_EQ(map.size(), 0u);
}
TEST(map, PopDefault)
@@ -105,17 +105,17 @@ TEST(map, PopDefault)
map.add(1, 4);
map.add(2, 7);
map.add(3, 8);
- EXPECT_EQ(map.size(), 3);
+ EXPECT_EQ(map.size(), 3u);
EXPECT_EQ(map.pop_default(4, 10), 10);
- EXPECT_EQ(map.size(), 3);
+ EXPECT_EQ(map.size(), 3u);
EXPECT_EQ(map.pop_default(1, 10), 4);
- EXPECT_EQ(map.size(), 2);
+ EXPECT_EQ(map.size(), 2u);
EXPECT_EQ(map.pop_default(2, 20), 7);
- EXPECT_EQ(map.size(), 1);
+ EXPECT_EQ(map.size(), 1u);
EXPECT_EQ(map.pop_default(2, 20), 20);
- EXPECT_EQ(map.size(), 1);
+ EXPECT_EQ(map.size(), 1u);
EXPECT_EQ(map.pop_default(3, 0), 8);
- EXPECT_EQ(map.size(), 0);
+ EXPECT_EQ(map.size(), 0u);
}
TEST(map, PopItemMany)
@@ -147,7 +147,7 @@ TEST(map, ValueIterator)
iterations++;
}
- EXPECT_EQ(iterations, 3);
+ EXPECT_EQ(iterations, 3u);
EXPECT_TRUE(values.contains(5.0f));
EXPECT_TRUE(values.contains(-2.0f));
EXPECT_TRUE(values.contains(2.0f));
@@ -168,7 +168,7 @@ TEST(map, KeyIterator)
iterations++;
}
- EXPECT_EQ(iterations, 3);
+ EXPECT_EQ(iterations, 3u);
EXPECT_TRUE(keys.contains(1));
EXPECT_TRUE(keys.contains(2));
EXPECT_TRUE(keys.contains(6));
@@ -192,7 +192,7 @@ TEST(map, ItemIterator)
iterations++;
}
- EXPECT_EQ(iterations, 3);
+ EXPECT_EQ(iterations, 3u);
EXPECT_TRUE(keys.contains(5));
EXPECT_TRUE(keys.contains(2));
EXPECT_TRUE(keys.contains(1));
@@ -241,8 +241,8 @@ TEST(map, MutableItemToItemConversion)
values.append(item.value);
}
- EXPECT_EQ(keys.size(), 2);
- EXPECT_EQ(values.size(), 2);
+ EXPECT_EQ(keys.size(), 2u);
+ EXPECT_EQ(values.size(), 2u);
EXPECT_TRUE(keys.contains(3));
EXPECT_TRUE(keys.contains(2));
EXPECT_TRUE(values.contains(6));
@@ -330,10 +330,10 @@ TEST(map, MoveConstructorSmall)
map1.add(1, 2.0f);
map1.add(4, 1.0f);
Map<int, float> map2(std::move(map1));
- EXPECT_EQ(map2.size(), 2);
+ EXPECT_EQ(map2.size(), 2u);
EXPECT_EQ(map2.lookup(1), 2.0f);
EXPECT_EQ(map2.lookup(4), 1.0f);
- EXPECT_EQ(map1.size(), 0);
+ EXPECT_EQ(map1.size(), 0u);
EXPECT_EQ(map1.lookup_ptr(4), nullptr);
}
@@ -344,10 +344,10 @@ TEST(map, MoveConstructorLarge)
map1.add_new(i, i);
}
Map<int, int> map2(std::move(map1));
- EXPECT_EQ(map2.size(), 100);
+ EXPECT_EQ(map2.size(), 100u);
EXPECT_EQ(map2.lookup(1), 1);
EXPECT_EQ(map2.lookup(4), 4);
- EXPECT_EQ(map1.size(), 0);
+ EXPECT_EQ(map1.size(), 0u);
EXPECT_EQ(map1.lookup_ptr(4), nullptr);
}
@@ -358,10 +358,10 @@ TEST(map, MoveAssignment)
map1.add(4, 1.0f);
Map<int, float> map2;
map2 = std::move(map1);
- EXPECT_EQ(map2.size(), 2);
+ EXPECT_EQ(map2.size(), 2u);
EXPECT_EQ(map2.lookup(1), 2.0f);
EXPECT_EQ(map2.lookup(4), 1.0f);
- EXPECT_EQ(map1.size(), 0);
+ EXPECT_EQ(map1.size(), 0u);
EXPECT_EQ(map1.lookup_ptr(4), nullptr);
}
@@ -372,10 +372,10 @@ TEST(map, CopyAssignment)
map1.add(4, 1.0f);
Map<int, float> map2;
map2 = map1;
- EXPECT_EQ(map2.size(), 2);
+ EXPECT_EQ(map2.size(), 2u);
EXPECT_EQ(map2.lookup(1), 2.0f);
EXPECT_EQ(map2.lookup(4), 1.0f);
- EXPECT_EQ(map1.size(), 2);
+ EXPECT_EQ(map1.size(), 2u);
EXPECT_EQ(*map1.lookup_ptr(4), 1.0f);
}
@@ -385,13 +385,13 @@ TEST(map, Clear)
map.add(1, 1.0f);
map.add(2, 5.0f);
- EXPECT_EQ(map.size(), 2);
+ EXPECT_EQ(map.size(), 2u);
EXPECT_TRUE(map.contains(1));
EXPECT_TRUE(map.contains(2));
map.clear();
- EXPECT_EQ(map.size(), 0);
+ EXPECT_EQ(map.size(), 0u);
EXPECT_FALSE(map.contains(1));
EXPECT_FALSE(map.contains(2));
}
@@ -423,11 +423,11 @@ TEST(map, Remove)
{
Map<int, int> map;
map.add(2, 4);
- EXPECT_EQ(map.size(), 1);
+ EXPECT_EQ(map.size(), 1u);
EXPECT_FALSE(map.remove(3));
- EXPECT_EQ(map.size(), 1);
+ EXPECT_EQ(map.size(), 1u);
EXPECT_TRUE(map.remove(2));
- EXPECT_EQ(map.size(), 0);
+ EXPECT_EQ(map.size(), 0u);
}
TEST(map, PointerKeys)
@@ -439,7 +439,7 @@ TEST(map, PointerKeys)
EXPECT_FALSE(map.add(&a, 4));
map.add_new(&b, 1);
map.add_new(&c, 1);
- EXPECT_EQ(map.size(), 3);
+ EXPECT_EQ(map.size(), 3u);
EXPECT_TRUE(map.remove(&b));
EXPECT_TRUE(map.add(&b, 8));
EXPECT_FALSE(map.remove(&d));
@@ -458,6 +458,25 @@ TEST(map, ConstKeysAndValues)
EXPECT_FALSE(map.contains("54"));
}
+TEST(map, ForeachItem)
+{
+ Map<int, int> map;
+ map.add(3, 4);
+ map.add(1, 8);
+
+ Vector<int> keys;
+ Vector<int> values;
+ map.foreach_item([&](int key, int value) {
+ keys.append(key);
+ values.append(value);
+ });
+
+ EXPECT_EQ(keys.size(), 2u);
+ EXPECT_EQ(values.size(), 2u);
+ EXPECT_EQ(keys.first_index_of(3), values.first_index_of(4));
+ EXPECT_EQ(keys.first_index_of(1), values.first_index_of(8));
+}
+
/**
* Set this to 1 to activate the benchmark. It is disabled by default, because it prints a lot.
*/
@@ -565,3 +584,5 @@ TEST(map, Benchmark)
*/
#endif /* Benchmark */
+
+} // namespace blender
diff --git a/tests/gtests/blenlib/BLI_math_matrix_test.cc b/tests/gtests/blenlib/BLI_math_matrix_test.cc
new file mode 100644
index 00000000000..9c47c02ceaf
--- /dev/null
+++ b/tests/gtests/blenlib/BLI_math_matrix_test.cc
@@ -0,0 +1,99 @@
+/* Apache License, Version 2.0 */
+
+#include "testing/testing.h"
+
+#include "BLI_math_matrix.h"
+
+TEST(math_matrix, interp_m4_m4m4_regular)
+{
+ /* Test 4x4 matrix interpolation without singularity, i.e. without axis flip. */
+
+ /* Transposed matrix, so that the code here is written in the same way as print_m4() outputs. */
+ /* This matrix represents T=(0.1, 0.2, 0.3), R=(40, 50, 60) degrees, S=(0.7, 0.8, 0.9) */
+ float matrix_a[4][4] = {
+ {0.224976f, -0.333770f, 0.765074f, 0.100000f},
+ {0.389669f, 0.647565f, 0.168130f, 0.200000f},
+ {-0.536231f, 0.330541f, 0.443163f, 0.300000f},
+ {0.000000f, 0.000000f, 0.000000f, 1.000000f},
+ };
+ transpose_m4(matrix_a);
+
+ float matrix_i[4][4];
+ unit_m4(matrix_i);
+
+ float result[4][4];
+ const float epsilon = 1e-6;
+ interp_m4_m4m4(result, matrix_i, matrix_a, 0.0f);
+ EXPECT_M4_NEAR(result, matrix_i, epsilon);
+
+ interp_m4_m4m4(result, matrix_i, matrix_a, 1.0f);
+ EXPECT_M4_NEAR(result, matrix_a, epsilon);
+
+ /* This matrix is based on the current implementation of the code, and isn't guaranteed to be
+ * correct. It's just consistent with the current implementation. */
+ float matrix_halfway[4][4] = {
+ {0.690643f, -0.253244f, 0.484996f, 0.050000f},
+ {0.271924f, 0.852623f, 0.012348f, 0.100000f},
+ {-0.414209f, 0.137484f, 0.816778f, 0.150000f},
+ {0.000000f, 0.000000f, 0.000000f, 1.000000f},
+ };
+
+ transpose_m4(matrix_halfway);
+ interp_m4_m4m4(result, matrix_i, matrix_a, 0.5f);
+ EXPECT_M4_NEAR(result, matrix_halfway, epsilon);
+}
+
+TEST(math_matrix, interp_m3_m3m3_singularity)
+{
+ /* A singluarity means that there is an axis mirror in the rotation component of the matrix. This
+ * is reflected in its negative determinant.
+ *
+ * The interpolation of 4x4 matrices performs linear interpolation on the translation component,
+ * and then uses the 3x3 interpolation function to handle rotation and scale. As a result, this
+ * test for a singularity in the rotation matrix only needs to test the 3x3 case. */
+
+ /* Transposed matrix, so that the code here is written in the same way as print_m4() outputs. */
+ /* This matrix represents R=(4, 5, 6) degrees, S=(-1, 1, 1) */
+ float matrix_a[3][3] = {
+ {-0.990737f, -0.098227f, 0.093759f},
+ {-0.104131f, 0.992735f, -0.060286f},
+ {0.087156f, 0.069491f, 0.993768f},
+ };
+ transpose_m3(matrix_a);
+ EXPECT_NEAR(-1.0f, determinant_m3_array(matrix_a), 1e-6);
+
+ /* This matrix represents R=(0, 0, 0), S=(-1, 0, 0) */
+ float matrix_b[3][3] = {
+ {-1.0f, 0.0f, 0.0f},
+ {0.0f, 1.0f, 0.0f},
+ {0.0f, 0.0f, 1.0f},
+ };
+ transpose_m3(matrix_b);
+
+ float result[3][3];
+ interp_m3_m3m3(result, matrix_a, matrix_b, 0.0f);
+ EXPECT_M3_NEAR(result, matrix_a, 1e-5);
+
+ interp_m3_m3m3(result, matrix_a, matrix_b, 1.0f);
+ EXPECT_M3_NEAR(result, matrix_b, 1e-5);
+
+ interp_m3_m3m3(result, matrix_a, matrix_b, 0.5f);
+ float expect[3][3] = {
+ {-0.997681f, -0.049995f, 0.046186f},
+ {-0.051473f, 0.998181f, -0.031385f},
+ {0.044533f, 0.033689f, 0.998440f},
+ };
+ transpose_m3(expect);
+ EXPECT_M3_NEAR(result, expect, 1e-5);
+
+ /* Interpolating between a matrix with and without axis flip can cause it to go through a zero
+ * point. The determinant det(A) of a matrix represents the change in volume; interpolating
+ * between matrices with det(A)=-1 and det(B)=1 will have to go through a point where
+ * det(result)=0, so where the volume becomes zero. */
+ float matrix_i[3][3];
+ unit_m3(matrix_i);
+ zero_m3(expect);
+ interp_m3_m3m3(result, matrix_a, matrix_i, 0.5f);
+ EXPECT_NEAR(0.0f, determinant_m3_array(result), 1e-5);
+ EXPECT_M3_NEAR(result, expect, 1e-5);
+}
diff --git a/tests/gtests/blenlib/BLI_optional_test.cc b/tests/gtests/blenlib/BLI_optional_test.cc
deleted file mode 100644
index 2fc2188563e..00000000000
--- a/tests/gtests/blenlib/BLI_optional_test.cc
+++ /dev/null
@@ -1,61 +0,0 @@
-#include "BLI_optional.hh"
-#include "BLI_strict_flags.h"
-#include "testing/testing.h"
-#include <string>
-
-using namespace blender;
-
-TEST(optional, DefaultConstructor)
-{
- Optional<int> a;
- EXPECT_FALSE(a.has_value());
-}
-
-TEST(optional, ValueConstructor)
-{
- Optional<int> a(5);
- EXPECT_TRUE(a.has_value());
- EXPECT_EQ(a.value(), 5);
-}
-
-TEST(optional, CopyConstructor)
-{
- Optional<std::string> a("Hello");
- Optional<std::string> b = a;
- EXPECT_TRUE(a.has_value());
- EXPECT_TRUE(b.has_value());
- b.value()[0] = 'T';
- EXPECT_EQ(a.value(), "Hello");
- EXPECT_EQ(b.value(), "Tello");
-}
-
-TEST(optional, Reset)
-{
- Optional<int> a(4);
- EXPECT_TRUE(a.has_value());
- a.reset();
- EXPECT_FALSE(a.has_value());
-}
-
-TEST(optional, Extract)
-{
- Optional<int> a(32);
- EXPECT_TRUE(a.has_value());
- EXPECT_EQ(a.extract(), 32);
- EXPECT_FALSE(a.has_value());
-}
-
-TEST(optional, ArrowOperator)
-{
- Optional<std::string> value = std::string("Hello");
- EXPECT_TRUE(value.has_value());
- EXPECT_EQ(value->size(), 5);
-}
-
-TEST(optional, StarOperator)
-{
- Optional<std::string> value = std::string("Hello");
- EXPECT_TRUE(value.has_value());
- std::string &s = *value;
- EXPECT_EQ(s.size(), 5);
-}
diff --git a/tests/gtests/blenlib/BLI_set_test.cc b/tests/gtests/blenlib/BLI_set_test.cc
index 2387242c94b..ac78eb786df 100644
--- a/tests/gtests/blenlib/BLI_set_test.cc
+++ b/tests/gtests/blenlib/BLI_set_test.cc
@@ -14,7 +14,7 @@ namespace blender {
TEST(set, DefaultConstructor)
{
Set<int> set;
- EXPECT_EQ(set.size(), 0);
+ EXPECT_EQ(set.size(), 0u);
EXPECT_TRUE(set.is_empty());
}
@@ -52,7 +52,7 @@ TEST(set, AddMany)
TEST(set, InitializerListConstructor)
{
Set<int> set = {4, 5, 6};
- EXPECT_EQ(set.size(), 3);
+ EXPECT_EQ(set.size(), 3u);
EXPECT_TRUE(set.contains(4));
EXPECT_TRUE(set.contains(5));
EXPECT_TRUE(set.contains(6));
@@ -77,10 +77,10 @@ TEST(set, CopyConstructor)
TEST(set, MoveConstructor)
{
Set<int> set = {1, 2, 3};
- EXPECT_EQ(set.size(), 3);
+ EXPECT_EQ(set.size(), 3u);
Set<int> set2(std::move(set));
- EXPECT_EQ(set.size(), 0);
- EXPECT_EQ(set2.size(), 3);
+ EXPECT_EQ(set.size(), 0u);
+ EXPECT_EQ(set2.size(), 3u);
}
TEST(set, CopyAssignment)
@@ -101,11 +101,11 @@ TEST(set, CopyAssignment)
TEST(set, MoveAssignment)
{
Set<int> set = {1, 2, 3};
- EXPECT_EQ(set.size(), 3);
+ EXPECT_EQ(set.size(), 3u);
Set<int> set2;
set2 = std::move(set);
- EXPECT_EQ(set.size(), 0);
- EXPECT_EQ(set2.size(), 3);
+ EXPECT_EQ(set.size(), 0u);
+ EXPECT_EQ(set2.size(), 3u);
}
TEST(set, RemoveContained)
@@ -177,7 +177,7 @@ TEST(set, AddMultiple)
a.add_multiple({2, 4, 7});
EXPECT_TRUE(a.contains(4));
EXPECT_TRUE(a.contains(2));
- EXPECT_EQ(a.size(), 4);
+ EXPECT_EQ(a.size(), 4u);
}
TEST(set, AddMultipleNew)
@@ -195,7 +195,7 @@ TEST(set, Iterator)
for (int value : set) {
vec.append(value);
}
- EXPECT_EQ(vec.size(), 5);
+ EXPECT_EQ(vec.size(), 5u);
EXPECT_TRUE(vec.contains(1));
EXPECT_TRUE(vec.contains(3));
EXPECT_TRUE(vec.contains(2));
@@ -208,9 +208,9 @@ TEST(set, OftenAddRemoveContained)
Set<int> set;
for (int i = 0; i < 100; i++) {
set.add(42);
- EXPECT_EQ(set.size(), 1);
+ EXPECT_EQ(set.size(), 1u);
set.remove_contained(42);
- EXPECT_EQ(set.size(), 0);
+ EXPECT_EQ(set.size(), 0u);
}
}
@@ -222,15 +222,15 @@ TEST(set, UniquePtrValues)
set.add_new(std::move(value1));
set.add(std::unique_ptr<int>(new int()));
- EXPECT_EQ(set.size(), 3);
+ EXPECT_EQ(set.size(), 3u);
}
TEST(set, Clear)
{
Set<int> set = {3, 4, 6, 7};
- EXPECT_EQ(set.size(), 4);
+ EXPECT_EQ(set.size(), 4u);
set.clear();
- EXPECT_EQ(set.size(), 0);
+ EXPECT_EQ(set.size(), 0u);
}
TEST(set, StringSet)
@@ -238,7 +238,7 @@ TEST(set, StringSet)
Set<std::string> set;
set.add("hello");
set.add("world");
- EXPECT_EQ(set.size(), 2);
+ EXPECT_EQ(set.size(), 2u);
EXPECT_TRUE(set.contains("hello"));
EXPECT_TRUE(set.contains("world"));
EXPECT_FALSE(set.contains("world2"));
@@ -250,7 +250,7 @@ TEST(set, PointerSet)
Set<int *> set;
set.add(&a);
set.add(&b);
- EXPECT_EQ(set.size(), 2);
+ EXPECT_EQ(set.size(), 2u);
EXPECT_TRUE(set.contains(&a));
EXPECT_TRUE(set.contains(&b));
EXPECT_FALSE(set.contains(&c));
@@ -259,14 +259,14 @@ TEST(set, PointerSet)
TEST(set, Remove)
{
Set<int> set = {1, 2, 3, 4, 5, 6};
- EXPECT_EQ(set.size(), 6);
+ EXPECT_EQ(set.size(), 6u);
EXPECT_TRUE(set.remove(2));
- EXPECT_EQ(set.size(), 5);
+ EXPECT_EQ(set.size(), 5u);
EXPECT_FALSE(set.contains(2));
EXPECT_FALSE(set.remove(2));
- EXPECT_EQ(set.size(), 5);
+ EXPECT_EQ(set.size(), 5u);
EXPECT_TRUE(set.remove(5));
- EXPECT_EQ(set.size(), 4);
+ EXPECT_EQ(set.size(), 4u);
}
struct Type1 {
diff --git a/tests/gtests/blenlib/BLI_span_test.cc b/tests/gtests/blenlib/BLI_span_test.cc
index b122e8efdb4..375cb694b7b 100644
--- a/tests/gtests/blenlib/BLI_span_test.cc
+++ b/tests/gtests/blenlib/BLI_span_test.cc
@@ -3,13 +3,13 @@
#include "BLI_vector.hh"
#include "testing/testing.h"
-using namespace blender;
+namespace blender {
TEST(span, FromSmallVector)
{
Vector<int> a = {1, 2, 3};
Span<int> a_span = a;
- EXPECT_EQ(a_span.size(), 3);
+ EXPECT_EQ(a_span.size(), 3u);
EXPECT_EQ(a_span[0], 1);
EXPECT_EQ(a_span[1], 2);
EXPECT_EQ(a_span[2], 3);
@@ -21,14 +21,14 @@ TEST(span, AddConstToPointer)
std::vector<int *> vec = {&a};
Span<int *> span = vec;
Span<const int *> const_span = span;
- EXPECT_EQ(const_span.size(), 1);
+ EXPECT_EQ(const_span.size(), 1u);
}
TEST(span, IsReferencing)
{
int array[] = {3, 5, 8};
MutableSpan<int> span(array, ARRAY_SIZE(array));
- EXPECT_EQ(span.size(), 3);
+ EXPECT_EQ(span.size(), 3u);
EXPECT_EQ(span[1], 5);
array[1] = 10;
EXPECT_EQ(span[1], 10);
@@ -38,7 +38,7 @@ TEST(span, DropBack)
{
Vector<int> a = {4, 5, 6, 7};
auto slice = Span<int>(a).drop_back(2);
- EXPECT_EQ(slice.size(), 2);
+ EXPECT_EQ(slice.size(), 2u);
EXPECT_EQ(slice[0], 4);
EXPECT_EQ(slice[1], 5);
}
@@ -47,14 +47,14 @@ TEST(span, DropBackAll)
{
Vector<int> a = {4, 5, 6, 7};
auto slice = Span<int>(a).drop_back(a.size());
- EXPECT_EQ(slice.size(), 0);
+ EXPECT_EQ(slice.size(), 0u);
}
TEST(span, DropFront)
{
Vector<int> a = {4, 5, 6, 7};
auto slice = Span<int>(a).drop_front(1);
- EXPECT_EQ(slice.size(), 3);
+ EXPECT_EQ(slice.size(), 3u);
EXPECT_EQ(slice[0], 5);
EXPECT_EQ(slice[1], 6);
EXPECT_EQ(slice[2], 7);
@@ -64,14 +64,14 @@ TEST(span, DropFrontAll)
{
Vector<int> a = {4, 5, 6, 7};
auto slice = Span<int>(a).drop_front(a.size());
- EXPECT_EQ(slice.size(), 0);
+ EXPECT_EQ(slice.size(), 0u);
}
TEST(span, TakeFront)
{
Vector<int> a = {4, 5, 6, 7};
auto slice = Span<int>(a).take_front(2);
- EXPECT_EQ(slice.size(), 2);
+ EXPECT_EQ(slice.size(), 2u);
EXPECT_EQ(slice[0], 4);
EXPECT_EQ(slice[1], 5);
}
@@ -80,7 +80,7 @@ TEST(span, TakeBack)
{
Vector<int> a = {5, 6, 7, 8};
auto slice = Span<int>(a).take_back(2);
- EXPECT_EQ(slice.size(), 2);
+ EXPECT_EQ(slice.size(), 2u);
EXPECT_EQ(slice[0], 7);
EXPECT_EQ(slice[1], 8);
}
@@ -89,7 +89,7 @@ TEST(span, Slice)
{
Vector<int> a = {4, 5, 6, 7};
auto slice = Span<int>(a).slice(1, 2);
- EXPECT_EQ(slice.size(), 2);
+ EXPECT_EQ(slice.size(), 2u);
EXPECT_EQ(slice[0], 5);
EXPECT_EQ(slice[1], 6);
}
@@ -98,14 +98,14 @@ TEST(span, SliceEmpty)
{
Vector<int> a = {4, 5, 6, 7};
auto slice = Span<int>(a).slice(2, 0);
- EXPECT_EQ(slice.size(), 0);
+ EXPECT_EQ(slice.size(), 0u);
}
TEST(span, 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.size(), 2u);
EXPECT_EQ(slice[0], 3);
EXPECT_EQ(slice[1], 4);
}
@@ -126,16 +126,16 @@ TEST(span, 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);
+ EXPECT_EQ(a_span.count(1), 0u);
+ EXPECT_EQ(a_span.count(2), 5u);
+ EXPECT_EQ(a_span.count(3), 3u);
+ EXPECT_EQ(a_span.count(4), 1u);
+ EXPECT_EQ(a_span.count(5), 0u);
}
static void test_ref_from_initializer_list(Span<int> span)
{
- EXPECT_EQ(span.size(), 4);
+ EXPECT_EQ(span.size(), 4u);
EXPECT_EQ(span[0], 3);
EXPECT_EQ(span[1], 6);
EXPECT_EQ(span[2], 8);
@@ -151,7 +151,7 @@ TEST(span, FromVector)
{
std::vector<int> a = {1, 2, 3, 4};
Span<int> a_span(a);
- EXPECT_EQ(a_span.size(), 4);
+ EXPECT_EQ(a_span.size(), 4u);
EXPECT_EQ(a_span[0], 1);
EXPECT_EQ(a_span[1], 2);
EXPECT_EQ(a_span[2], 3);
@@ -162,7 +162,7 @@ TEST(span, FromArray)
{
std::array<int, 2> a = {5, 6};
Span<int> a_span(a);
- EXPECT_EQ(a_span.size(), 2);
+ EXPECT_EQ(a_span.size(), 2u);
EXPECT_EQ(a_span[0], 5);
EXPECT_EQ(a_span[1], 6);
}
@@ -196,7 +196,7 @@ TEST(span, 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);
+ EXPECT_EQ(a_span.size_in_bytes(), 40u);
}
TEST(span, FirstLast)
@@ -244,9 +244,9 @@ TEST(span, 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);
+ EXPECT_EQ(a_span.first_index(4), 0u);
+ EXPECT_EQ(a_span.first_index(5), 1u);
+ EXPECT_EQ(a_span.first_index(2), 3u);
}
TEST(span, CastSameSize)
@@ -256,8 +256,8 @@ TEST(span, CastSameSize)
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.size(), 4u);
+ EXPECT_EQ(new_a_span.size(), 4u);
EXPECT_EQ(a_span[0], &value);
EXPECT_EQ(new_a_span[0], (float *)&value);
@@ -269,8 +269,8 @@ TEST(span, CastSmallerSize)
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);
+ EXPECT_EQ(a_span.size(), 4u);
+ EXPECT_EQ(new_a_span.size(), 8u);
}
TEST(span, CastLargerSize)
@@ -279,6 +279,8 @@ TEST(span, CastLargerSize)
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);
+ EXPECT_EQ(a_span.size(), 4u);
+ EXPECT_EQ(new_a_span.size(), 2u);
}
+
+} // namespace blender
diff --git a/tests/gtests/blenlib/BLI_stack_cxx_test.cc b/tests/gtests/blenlib/BLI_stack_cxx_test.cc
index 2fb4c11ca83..b59ac1f7ec1 100644
--- a/tests/gtests/blenlib/BLI_stack_cxx_test.cc
+++ b/tests/gtests/blenlib/BLI_stack_cxx_test.cc
@@ -3,12 +3,12 @@
#include "BLI_vector.hh"
#include "testing/testing.h"
-using namespace blender;
+namespace blender {
TEST(stack, DefaultConstructor)
{
Stack<int> stack;
- EXPECT_EQ(stack.size(), 0);
+ EXPECT_EQ(stack.size(), 0u);
EXPECT_TRUE(stack.is_empty());
}
@@ -16,7 +16,7 @@ TEST(stack, SpanConstructor)
{
std::array<int, 3> array = {4, 7, 2};
Stack<int> stack(array);
- EXPECT_EQ(stack.size(), 3);
+ EXPECT_EQ(stack.size(), 3u);
EXPECT_EQ(stack.pop(), 2);
EXPECT_EQ(stack.pop(), 7);
EXPECT_EQ(stack.pop(), 4);
@@ -27,8 +27,8 @@ TEST(stack, CopyConstructor)
{
Stack<int> stack1 = {1, 2, 3, 4, 5, 6, 7};
Stack<int> stack2 = stack1;
- EXPECT_EQ(stack1.size(), 7);
- EXPECT_EQ(stack2.size(), 7);
+ EXPECT_EQ(stack1.size(), 7u);
+ EXPECT_EQ(stack2.size(), 7u);
for (int i = 7; i >= 1; i--) {
EXPECT_FALSE(stack1.is_empty());
EXPECT_FALSE(stack2.is_empty());
@@ -43,8 +43,8 @@ TEST(stack, MoveConstructor)
{
Stack<int> stack1 = {1, 2, 3, 4, 5, 6, 7};
Stack<int> stack2 = std::move(stack1);
- EXPECT_EQ(stack1.size(), 0);
- EXPECT_EQ(stack2.size(), 7);
+ EXPECT_EQ(stack1.size(), 0u);
+ EXPECT_EQ(stack2.size(), 7u);
for (int i = 7; i >= 1; i--) {
EXPECT_EQ(stack2.pop(), i);
}
@@ -56,8 +56,8 @@ TEST(stack, CopyAssignment)
Stack<int> stack2 = {2, 3, 4, 5, 6, 7};
stack2 = stack1;
- EXPECT_EQ(stack1.size(), 7);
- EXPECT_EQ(stack2.size(), 7);
+ EXPECT_EQ(stack1.size(), 7u);
+ EXPECT_EQ(stack2.size(), 7u);
for (int i = 7; i >= 1; i--) {
EXPECT_FALSE(stack1.is_empty());
EXPECT_FALSE(stack2.is_empty());
@@ -73,8 +73,8 @@ TEST(stack, MoveAssignment)
Stack<int> stack1 = {1, 2, 3, 4, 5, 6, 7};
Stack<int> stack2 = {5, 3, 7, 2, 2};
stack2 = std::move(stack1);
- EXPECT_EQ(stack1.size(), 0);
- EXPECT_EQ(stack2.size(), 7);
+ EXPECT_EQ(stack1.size(), 0u);
+ EXPECT_EQ(stack2.size(), 7u);
for (int i = 7; i >= 1; i--) {
EXPECT_EQ(stack2.pop(), i);
}
@@ -83,19 +83,19 @@ TEST(stack, MoveAssignment)
TEST(stack, Push)
{
Stack<int> stack;
- EXPECT_EQ(stack.size(), 0);
+ EXPECT_EQ(stack.size(), 0u);
stack.push(3);
- EXPECT_EQ(stack.size(), 1);
+ EXPECT_EQ(stack.size(), 1u);
stack.push(5);
- EXPECT_EQ(stack.size(), 2);
+ EXPECT_EQ(stack.size(), 2u);
}
TEST(stack, PushMultiple)
{
Stack<int> stack;
- EXPECT_EQ(stack.size(), 0);
+ EXPECT_EQ(stack.size(), 0u);
stack.push_multiple({1, 2, 3});
- EXPECT_EQ(stack.size(), 3);
+ EXPECT_EQ(stack.size(), 3u);
EXPECT_EQ(stack.pop(), 3);
EXPECT_EQ(stack.pop(), 2);
EXPECT_EQ(stack.pop(), 1);
@@ -106,19 +106,19 @@ TEST(stack, PushPopMany)
Stack<int> stack;
for (int i = 0; i < 1000; i++) {
stack.push(i);
- EXPECT_EQ(stack.size(), i + 1);
+ EXPECT_EQ(stack.size(), static_cast<unsigned int>(i + 1));
}
for (int i = 999; i > 50; i--) {
EXPECT_EQ(stack.pop(), i);
- EXPECT_EQ(stack.size(), i);
+ EXPECT_EQ(stack.size(), static_cast<unsigned int>(i));
}
for (int i = 51; i < 5000; i++) {
stack.push(i);
- EXPECT_EQ(stack.size(), i + 1);
+ EXPECT_EQ(stack.size(), static_cast<unsigned int>(i + 1));
}
for (int i = 4999; i >= 0; i--) {
EXPECT_EQ(stack.pop(), i);
- EXPECT_EQ(stack.size(), i);
+ EXPECT_EQ(stack.size(), static_cast<unsigned int>(i));
}
}
@@ -137,7 +137,7 @@ TEST(stack, PushMultipleAfterPop)
values.append(i);
}
stack.push_multiple(values);
- EXPECT_EQ(stack.size(), 5000);
+ EXPECT_EQ(stack.size(), 5000u);
for (int i = 4999; i >= 0; i--) {
EXPECT_EQ(stack.pop(), i);
@@ -182,3 +182,5 @@ TEST(stack, OveralignedValues)
EXPECT_EQ((uintptr_t)&stack.peek() % 512, 0);
}
}
+
+} // namespace blender
diff --git a/tests/gtests/blenlib/BLI_string_ref_test.cc b/tests/gtests/blenlib/BLI_string_ref_test.cc
index 5bb0c396288..1f84b8577b4 100644
--- a/tests/gtests/blenlib/BLI_string_ref_test.cc
+++ b/tests/gtests/blenlib/BLI_string_ref_test.cc
@@ -3,14 +3,12 @@
#include "BLI_vector.hh"
#include "testing/testing.h"
-using blender::StringRef;
-using blender::StringRefNull;
-using blender::Vector;
+namespace blender {
TEST(string_ref_null, DefaultConstructor)
{
StringRefNull ref;
- EXPECT_EQ(ref.size(), 0);
+ EXPECT_EQ(ref.size(), 0u);
EXPECT_EQ(ref[0], '\0');
}
@@ -18,7 +16,7 @@ TEST(string_ref_null, CStringConstructor)
{
const char *str = "Hello";
StringRefNull ref(str);
- EXPECT_EQ(ref.size(), 5);
+ EXPECT_EQ(ref.size(), 5u);
EXPECT_EQ(ref.data(), str);
}
@@ -26,21 +24,21 @@ TEST(string_ref_null, CStringLengthConstructor)
{
const char *str = "Hello";
StringRefNull ref(str, 5);
- EXPECT_EQ(ref.size(), 5);
+ EXPECT_EQ(ref.size(), 5u);
EXPECT_EQ(ref.data(), str);
}
TEST(string_ref, DefaultConstructor)
{
StringRef ref;
- EXPECT_EQ(ref.size(), 0);
+ EXPECT_EQ(ref.size(), 0u);
}
TEST(string_ref, StartEndConstructor)
{
const char *text = "hello world";
StringRef ref(text, text + 5);
- EXPECT_EQ(ref.size(), 5);
+ EXPECT_EQ(ref.size(), 5u);
EXPECT_TRUE(ref == "hello");
EXPECT_FALSE(ref == "hello ");
}
@@ -48,7 +46,7 @@ TEST(string_ref, StartEndConstructor)
TEST(string_ref, StartEndConstructorNullptr)
{
StringRef ref(nullptr, nullptr);
- EXPECT_EQ(ref.size(), 0);
+ EXPECT_EQ(ref.size(), 0u);
EXPECT_TRUE(ref == "");
}
@@ -56,7 +54,7 @@ TEST(string_ref, StartEndConstructorSame)
{
const char *text = "hello world";
StringRef ref(text, text);
- EXPECT_EQ(ref.size(), 0);
+ EXPECT_EQ(ref.size(), 0u);
EXPECT_TRUE(ref == "");
}
@@ -64,7 +62,7 @@ TEST(string_ref, CStringConstructor)
{
const char *str = "Test";
StringRef ref(str);
- EXPECT_EQ(ref.size(), 4);
+ EXPECT_EQ(ref.size(), 4u);
EXPECT_EQ(ref.data(), str);
}
@@ -72,7 +70,7 @@ TEST(string_ref, PointerWithLengthConstructor)
{
const char *str = "Test";
StringRef ref(str, 2);
- EXPECT_EQ(ref.size(), 2);
+ EXPECT_EQ(ref.size(), 2u);
EXPECT_EQ(ref.data(), str);
}
@@ -80,14 +78,14 @@ TEST(string_ref, StdStringConstructor)
{
std::string str = "Test";
StringRef ref(str);
- EXPECT_EQ(ref.size(), 4);
+ EXPECT_EQ(ref.size(), 4u);
EXPECT_EQ(ref.data(), str.data());
}
TEST(string_ref, SubscriptOperator)
{
StringRef ref("hello");
- EXPECT_EQ(ref.size(), 5);
+ EXPECT_EQ(ref.size(), 5u);
EXPECT_EQ(ref[0], 'h');
EXPECT_EQ(ref[1], 'e');
EXPECT_EQ(ref[2], 'l');
@@ -99,7 +97,7 @@ TEST(string_ref, ToStdString)
{
StringRef ref("test");
std::string str = ref;
- EXPECT_EQ(str.size(), 4);
+ EXPECT_EQ(str.size(), 4u);
EXPECT_EQ(str, "test");
}
@@ -204,7 +202,7 @@ TEST(string_ref, Iterate)
for (char c : ref) {
chars.append(c);
}
- EXPECT_EQ(chars.size(), 4);
+ EXPECT_EQ(chars.size(), 4u);
EXPECT_EQ(chars[0], 't');
EXPECT_EQ(chars[1], 'e');
EXPECT_EQ(chars[2], 's');
@@ -240,8 +238,8 @@ TEST(string_ref, DropPrefixN)
StringRef ref("test");
StringRef ref2 = ref.drop_prefix(2);
StringRef ref3 = ref2.drop_prefix(2);
- EXPECT_EQ(ref2.size(), 2);
- EXPECT_EQ(ref3.size(), 0);
+ EXPECT_EQ(ref2.size(), 2u);
+ EXPECT_EQ(ref3.size(), 0u);
EXPECT_EQ(ref2, "st");
EXPECT_EQ(ref3, "");
}
@@ -250,7 +248,7 @@ TEST(string_ref, DropPrefix)
{
StringRef ref("test");
StringRef ref2 = ref.drop_prefix("tes");
- EXPECT_EQ(ref2.size(), 1);
+ EXPECT_EQ(ref2.size(), 1u);
EXPECT_EQ(ref2, "t");
}
@@ -273,3 +271,5 @@ TEST(string_ref, Copy)
EXPECT_EQ(dst[6], 0xFF);
EXPECT_EQ(ref, dst);
}
+
+} // namespace blender
diff --git a/tests/gtests/blenlib/BLI_vector_set_test.cc b/tests/gtests/blenlib/BLI_vector_set_test.cc
index 1f8a830d134..982081f4b4c 100644
--- a/tests/gtests/blenlib/BLI_vector_set_test.cc
+++ b/tests/gtests/blenlib/BLI_vector_set_test.cc
@@ -2,19 +2,19 @@
#include "BLI_vector_set.hh"
#include "testing/testing.h"
-using blender::VectorSet;
+namespace blender {
TEST(vector_set, DefaultConstructor)
{
VectorSet<int> set;
- EXPECT_EQ(set.size(), 0);
+ EXPECT_EQ(set.size(), 0u);
EXPECT_TRUE(set.is_empty());
}
TEST(vector_set, InitializerListConstructor_WithoutDuplicates)
{
VectorSet<int> set = {1, 4, 5};
- EXPECT_EQ(set.size(), 3);
+ EXPECT_EQ(set.size(), 3u);
EXPECT_EQ(set[0], 1);
EXPECT_EQ(set[1], 4);
EXPECT_EQ(set[2], 5);
@@ -23,7 +23,7 @@ TEST(vector_set, InitializerListConstructor_WithoutDuplicates)
TEST(vector_set, InitializerListConstructor_WithDuplicates)
{
VectorSet<int> set = {1, 3, 3, 2, 1, 5};
- EXPECT_EQ(set.size(), 4);
+ EXPECT_EQ(set.size(), 4u);
EXPECT_EQ(set[0], 1);
EXPECT_EQ(set[1], 3);
EXPECT_EQ(set[2], 2);
@@ -34,10 +34,10 @@ TEST(vector_set, Copy)
{
VectorSet<int> set1 = {1, 2, 3};
VectorSet<int> set2 = set1;
- EXPECT_EQ(set1.size(), 3);
- EXPECT_EQ(set2.size(), 3);
- EXPECT_EQ(set1.index_of(2), 1);
- EXPECT_EQ(set2.index_of(2), 1);
+ EXPECT_EQ(set1.size(), 3u);
+ EXPECT_EQ(set2.size(), 3u);
+ EXPECT_EQ(set1.index_of(2), 1u);
+ EXPECT_EQ(set2.index_of(2), 1u);
}
TEST(vector_set, CopyAssignment)
@@ -45,18 +45,18 @@ TEST(vector_set, CopyAssignment)
VectorSet<int> set1 = {1, 2, 3};
VectorSet<int> set2 = {};
set2 = set1;
- EXPECT_EQ(set1.size(), 3);
- EXPECT_EQ(set2.size(), 3);
- EXPECT_EQ(set1.index_of(2), 1);
- EXPECT_EQ(set2.index_of(2), 1);
+ EXPECT_EQ(set1.size(), 3u);
+ EXPECT_EQ(set2.size(), 3u);
+ EXPECT_EQ(set1.index_of(2), 1u);
+ EXPECT_EQ(set2.index_of(2), 1u);
}
TEST(vector_set, Move)
{
VectorSet<int> set1 = {1, 2, 3};
VectorSet<int> set2 = std::move(set1);
- EXPECT_EQ(set1.size(), 0);
- EXPECT_EQ(set2.size(), 3);
+ EXPECT_EQ(set1.size(), 0u);
+ EXPECT_EQ(set2.size(), 3u);
}
TEST(vector_set, MoveAssignment)
@@ -64,36 +64,36 @@ TEST(vector_set, MoveAssignment)
VectorSet<int> set1 = {1, 2, 3};
VectorSet<int> set2 = {};
set2 = std::move(set1);
- EXPECT_EQ(set1.size(), 0);
- EXPECT_EQ(set2.size(), 3);
+ EXPECT_EQ(set1.size(), 0u);
+ EXPECT_EQ(set2.size(), 3u);
}
TEST(vector_set, AddNewIncreasesSize)
{
VectorSet<int> set;
EXPECT_TRUE(set.is_empty());
- EXPECT_EQ(set.size(), 0);
+ EXPECT_EQ(set.size(), 0u);
set.add(5);
EXPECT_FALSE(set.is_empty());
- EXPECT_EQ(set.size(), 1);
+ EXPECT_EQ(set.size(), 1u);
}
TEST(vector_set, AddExistingDoesNotIncreaseSize)
{
VectorSet<int> set;
- EXPECT_EQ(set.size(), 0);
+ EXPECT_EQ(set.size(), 0u);
EXPECT_TRUE(set.add(5));
- EXPECT_EQ(set.size(), 1);
+ EXPECT_EQ(set.size(), 1u);
EXPECT_FALSE(set.add(5));
- EXPECT_EQ(set.size(), 1);
+ EXPECT_EQ(set.size(), 1u);
}
TEST(vector_set, Index)
{
VectorSet<int> set = {3, 6, 4};
- EXPECT_EQ(set.index_of(6), 1);
- EXPECT_EQ(set.index_of(3), 0);
- EXPECT_EQ(set.index_of(4), 2);
+ EXPECT_EQ(set.index_of(6), 1u);
+ EXPECT_EQ(set.index_of(3), 0u);
+ EXPECT_EQ(set.index_of(4), 2u);
}
TEST(vector_set, IndexTry)
@@ -108,21 +108,21 @@ TEST(vector_set, IndexTry)
TEST(vector_set, RemoveContained)
{
VectorSet<int> set = {4, 5, 6, 7};
- EXPECT_EQ(set.size(), 4);
+ EXPECT_EQ(set.size(), 4u);
set.remove_contained(5);
- EXPECT_EQ(set.size(), 3);
+ EXPECT_EQ(set.size(), 3u);
EXPECT_EQ(set[0], 4);
EXPECT_EQ(set[1], 7);
EXPECT_EQ(set[2], 6);
set.remove_contained(6);
- EXPECT_EQ(set.size(), 2);
+ EXPECT_EQ(set.size(), 2u);
EXPECT_EQ(set[0], 4);
EXPECT_EQ(set[1], 7);
set.remove_contained(4);
- EXPECT_EQ(set.size(), 1);
+ EXPECT_EQ(set.size(), 1u);
EXPECT_EQ(set[0], 7);
set.remove_contained(7);
- EXPECT_EQ(set.size(), 0);
+ EXPECT_EQ(set.size(), 0u);
}
TEST(vector_set, AddMultipleTimes)
@@ -158,3 +158,5 @@ TEST(vector_set, Remove)
EXPECT_FALSE(set.remove(5));
EXPECT_FALSE(set.contains(5));
}
+
+} // namespace blender
diff --git a/tests/gtests/blenlib/BLI_vector_test.cc b/tests/gtests/blenlib/BLI_vector_test.cc
index 4a04d002580..ea4711ca015 100644
--- a/tests/gtests/blenlib/BLI_vector_test.cc
+++ b/tests/gtests/blenlib/BLI_vector_test.cc
@@ -3,18 +3,18 @@
#include "testing/testing.h"
#include <forward_list>
-using namespace blender;
+namespace blender {
TEST(vector, DefaultConstructor)
{
Vector<int> vec;
- EXPECT_EQ(vec.size(), 0);
+ EXPECT_EQ(vec.size(), 0u);
}
TEST(vector, SizeConstructor)
{
Vector<int> vec(3);
- EXPECT_EQ(vec.size(), 3);
+ EXPECT_EQ(vec.size(), 3u);
}
/**
@@ -40,7 +40,7 @@ TEST(vector, TrivialTypeSizeConstructor)
TEST(vector, SizeValueConstructor)
{
Vector<int> vec(4, 10);
- EXPECT_EQ(vec.size(), 4);
+ EXPECT_EQ(vec.size(), 4u);
EXPECT_EQ(vec[0], 10);
EXPECT_EQ(vec[1], 10);
EXPECT_EQ(vec[2], 10);
@@ -50,7 +50,7 @@ TEST(vector, SizeValueConstructor)
TEST(vector, InitializerListConstructor)
{
Vector<int> vec = {1, 3, 4, 6};
- EXPECT_EQ(vec.size(), 4);
+ EXPECT_EQ(vec.size(), 4u);
EXPECT_EQ(vec[0], 1);
EXPECT_EQ(vec[1], 3);
EXPECT_EQ(vec[2], 4);
@@ -74,7 +74,7 @@ TEST(vector, ListBaseConstructor)
BLI_addtail(&list, value3);
Vector<TestListValue *> vec(list);
- EXPECT_EQ(vec.size(), 3);
+ EXPECT_EQ(vec.size(), 3u);
EXPECT_EQ(vec[0]->value, 4);
EXPECT_EQ(vec[1]->value, 5);
EXPECT_EQ(vec[2]->value, 6);
@@ -92,7 +92,7 @@ TEST(vector, ContainerConstructor)
list.push_front(5);
Vector<int> vec = Vector<int>::FromContainer(list);
- EXPECT_EQ(vec.size(), 3);
+ EXPECT_EQ(vec.size(), 3u);
EXPECT_EQ(vec[0], 5);
EXPECT_EQ(vec[1], 1);
EXPECT_EQ(vec[2], 3);
@@ -102,7 +102,7 @@ TEST(vector, CopyConstructor)
{
Vector<int> vec1 = {1, 2, 3};
Vector<int> vec2(vec1);
- EXPECT_EQ(vec2.size(), 3);
+ EXPECT_EQ(vec2.size(), 3u);
EXPECT_EQ(vec2[0], 1);
EXPECT_EQ(vec2[1], 2);
EXPECT_EQ(vec2[2], 3);
@@ -117,8 +117,8 @@ TEST(vector, CopyConstructor2)
Vector<int, 2> vec1 = {1, 2, 3, 4};
Vector<int, 3> vec2(vec1);
- EXPECT_EQ(vec1.size(), 4);
- EXPECT_EQ(vec2.size(), 4);
+ EXPECT_EQ(vec1.size(), 4u);
+ EXPECT_EQ(vec2.size(), 4u);
EXPECT_NE(vec1.data(), vec2.data());
EXPECT_EQ(vec2[0], 1);
EXPECT_EQ(vec2[1], 2);
@@ -131,8 +131,8 @@ TEST(vector, CopyConstructor3)
Vector<int, 20> vec1 = {1, 2, 3, 4};
Vector<int, 1> vec2(vec1);
- EXPECT_EQ(vec1.size(), 4);
- EXPECT_EQ(vec2.size(), 4);
+ EXPECT_EQ(vec1.size(), 4u);
+ EXPECT_EQ(vec2.size(), 4u);
EXPECT_NE(vec1.data(), vec2.data());
EXPECT_EQ(vec2[2], 3);
}
@@ -142,8 +142,8 @@ TEST(vector, CopyConstructor4)
Vector<int, 5> vec1 = {1, 2, 3, 4};
Vector<int, 6> vec2(vec1);
- EXPECT_EQ(vec1.size(), 4);
- EXPECT_EQ(vec2.size(), 4);
+ EXPECT_EQ(vec1.size(), 4u);
+ EXPECT_EQ(vec2.size(), 4u);
EXPECT_NE(vec1.data(), vec2.data());
EXPECT_EQ(vec2[3], 4);
}
@@ -153,8 +153,8 @@ TEST(vector, MoveConstructor)
Vector<int> vec1 = {1, 2, 3, 4};
Vector<int> vec2(std::move(vec1));
- EXPECT_EQ(vec1.size(), 0);
- EXPECT_EQ(vec2.size(), 4);
+ EXPECT_EQ(vec1.size(), 0u);
+ EXPECT_EQ(vec2.size(), 4u);
EXPECT_EQ(vec2[0], 1);
EXPECT_EQ(vec2[1], 2);
EXPECT_EQ(vec2[2], 3);
@@ -166,8 +166,8 @@ TEST(vector, MoveConstructor2)
Vector<int, 2> vec1 = {1, 2, 3, 4};
Vector<int, 3> vec2(std::move(vec1));
- EXPECT_EQ(vec1.size(), 0);
- EXPECT_EQ(vec2.size(), 4);
+ EXPECT_EQ(vec1.size(), 0u);
+ EXPECT_EQ(vec2.size(), 4u);
EXPECT_EQ(vec2[0], 1);
EXPECT_EQ(vec2[1], 2);
EXPECT_EQ(vec2[2], 3);
@@ -179,8 +179,8 @@ TEST(vector, MoveConstructor3)
Vector<int, 20> vec1 = {1, 2, 3, 4};
Vector<int, 1> vec2(std::move(vec1));
- EXPECT_EQ(vec1.size(), 0);
- EXPECT_EQ(vec2.size(), 4);
+ EXPECT_EQ(vec1.size(), 0u);
+ EXPECT_EQ(vec2.size(), 4u);
EXPECT_EQ(vec2[2], 3);
}
@@ -189,20 +189,20 @@ TEST(vector, MoveConstructor4)
Vector<int, 5> vec1 = {1, 2, 3, 4};
Vector<int, 6> vec2(std::move(vec1));
- EXPECT_EQ(vec1.size(), 0);
- EXPECT_EQ(vec2.size(), 4);
+ EXPECT_EQ(vec1.size(), 0u);
+ EXPECT_EQ(vec2.size(), 4u);
EXPECT_EQ(vec2[3], 4);
}
TEST(vector, MoveAssignment)
{
Vector<int> vec = {1, 2};
- EXPECT_EQ(vec.size(), 2);
+ EXPECT_EQ(vec.size(), 2u);
EXPECT_EQ(vec[0], 1);
EXPECT_EQ(vec[1], 2);
vec = Vector<int>({5});
- EXPECT_EQ(vec.size(), 1);
+ EXPECT_EQ(vec.size(), 1u);
EXPECT_EQ(vec[0], 5);
}
@@ -210,11 +210,11 @@ TEST(vector, CopyAssignment)
{
Vector<int> vec1 = {1, 2, 3};
Vector<int> vec2 = {4, 5};
- EXPECT_EQ(vec1.size(), 3);
- EXPECT_EQ(vec2.size(), 2);
+ EXPECT_EQ(vec1.size(), 3u);
+ EXPECT_EQ(vec2.size(), 2u);
vec2 = vec1;
- EXPECT_EQ(vec2.size(), 3);
+ EXPECT_EQ(vec2.size(), 3u);
vec1[0] = 7;
EXPECT_EQ(vec1[0], 7);
@@ -227,7 +227,7 @@ TEST(vector, Append)
vec.append(3);
vec.append(6);
vec.append(7);
- EXPECT_EQ(vec.size(), 3);
+ EXPECT_EQ(vec.size(), 3u);
EXPECT_EQ(vec[0], 3);
EXPECT_EQ(vec[1], 6);
EXPECT_EQ(vec[2], 7);
@@ -236,40 +236,40 @@ TEST(vector, Append)
TEST(vector, AppendAndGetIndex)
{
Vector<int> vec;
- EXPECT_EQ(vec.append_and_get_index(10), 0);
- EXPECT_EQ(vec.append_and_get_index(10), 1);
- EXPECT_EQ(vec.append_and_get_index(10), 2);
+ EXPECT_EQ(vec.append_and_get_index(10), 0u);
+ EXPECT_EQ(vec.append_and_get_index(10), 1u);
+ EXPECT_EQ(vec.append_and_get_index(10), 2u);
vec.append(10);
- EXPECT_EQ(vec.append_and_get_index(10), 4);
+ EXPECT_EQ(vec.append_and_get_index(10), 4u);
}
TEST(vector, AppendNonDuplicates)
{
Vector<int> vec;
vec.append_non_duplicates(4);
- EXPECT_EQ(vec.size(), 1);
+ EXPECT_EQ(vec.size(), 1u);
vec.append_non_duplicates(5);
- EXPECT_EQ(vec.size(), 2);
+ EXPECT_EQ(vec.size(), 2u);
vec.append_non_duplicates(4);
- EXPECT_EQ(vec.size(), 2);
+ EXPECT_EQ(vec.size(), 2u);
}
TEST(vector, ExtendNonDuplicates)
{
Vector<int> vec;
vec.extend_non_duplicates({1, 2});
- EXPECT_EQ(vec.size(), 2);
+ EXPECT_EQ(vec.size(), 2u);
vec.extend_non_duplicates({3, 4});
- EXPECT_EQ(vec.size(), 4);
+ EXPECT_EQ(vec.size(), 4u);
vec.extend_non_duplicates({0, 1, 2, 3});
- EXPECT_EQ(vec.size(), 5);
+ EXPECT_EQ(vec.size(), 5u);
}
TEST(vector, Fill)
{
Vector<int> vec(5);
vec.fill(3);
- EXPECT_EQ(vec.size(), 5);
+ EXPECT_EQ(vec.size(), 5u);
EXPECT_EQ(vec[0], 3);
EXPECT_EQ(vec[1], 3);
EXPECT_EQ(vec[2], 3);
@@ -304,9 +304,9 @@ TEST(vector, BecomeLarge)
for (int i = 0; i < 100; i++) {
vec.append(i * 5);
}
- EXPECT_EQ(vec.size(), 100);
+ EXPECT_EQ(vec.size(), 100u);
for (uint i = 0; i < 100; i++) {
- EXPECT_EQ(vec[i], i * 5);
+ EXPECT_EQ(vec[i], static_cast<int>(i * 5));
}
}
@@ -318,7 +318,7 @@ static Vector<int> return_by_value_helper()
TEST(vector, ReturnByValue)
{
Vector<int> vec = return_by_value_helper();
- EXPECT_EQ(vec.size(), 3);
+ EXPECT_EQ(vec.size(), 3u);
EXPECT_EQ(vec[0], 3);
EXPECT_EQ(vec[1], 5);
EXPECT_EQ(vec[2], 1);
@@ -327,12 +327,12 @@ TEST(vector, ReturnByValue)
TEST(vector, VectorOfVectors_Append)
{
Vector<Vector<int>> vec;
- EXPECT_EQ(vec.size(), 0);
+ EXPECT_EQ(vec.size(), 0u);
Vector<int> v({1, 2});
vec.append(v);
vec.append({7, 8});
- EXPECT_EQ(vec.size(), 2);
+ EXPECT_EQ(vec.size(), 2u);
EXPECT_EQ(vec[0][0], 1);
EXPECT_EQ(vec[0][1], 2);
EXPECT_EQ(vec[1][0], 7);
@@ -355,11 +355,11 @@ TEST(vector, VectorOfVectors_Fill)
TEST(vector, RemoveLast)
{
Vector<int> vec = {5, 6};
- EXPECT_EQ(vec.size(), 2);
+ EXPECT_EQ(vec.size(), 2u);
vec.remove_last();
- EXPECT_EQ(vec.size(), 1);
+ EXPECT_EQ(vec.size(), 1u);
vec.remove_last();
- EXPECT_EQ(vec.size(), 0);
+ EXPECT_EQ(vec.size(), 0u);
}
TEST(vector, IsEmpty)
@@ -401,7 +401,7 @@ TEST(vector, RemoveFirstOccurrenceAndReorder)
vec.remove_first_occurrence_and_reorder(4);
EXPECT_EQ(vec[0], 7);
vec.remove_first_occurrence_and_reorder(7);
- EXPECT_EQ(vec.size(), 0);
+ EXPECT_EQ(vec.size(), 0u);
}
TEST(vector, Remove)
@@ -426,7 +426,7 @@ TEST(vector, ExtendSmallVector)
Vector<int> a = {2, 3, 4};
Vector<int> b = {11, 12};
b.extend(a);
- EXPECT_EQ(b.size(), 5);
+ EXPECT_EQ(b.size(), 5u);
EXPECT_EQ(b[0], 11);
EXPECT_EQ(b[1], 12);
EXPECT_EQ(b[2], 2);
@@ -441,7 +441,7 @@ TEST(vector, ExtendArray)
Vector<int> a;
a.extend(array, 2);
- EXPECT_EQ(a.size(), 2);
+ EXPECT_EQ(a.size(), 2u);
EXPECT_EQ(a[0], 3);
EXPECT_EQ(a[1], 4);
}
@@ -457,7 +457,7 @@ TEST(vector, AppendNTimes)
Vector<int> a;
a.append_n_times(5, 3);
a.append_n_times(2, 2);
- EXPECT_EQ(a.size(), 5);
+ EXPECT_EQ(a.size(), 5u);
EXPECT_EQ(a[0], 5);
EXPECT_EQ(a[1], 5);
EXPECT_EQ(a[2], 5);
@@ -472,13 +472,13 @@ TEST(vector, UniquePtrValue)
vec.append(std::unique_ptr<int>(new int()));
vec.append(std::unique_ptr<int>(new int()));
vec.append(std::unique_ptr<int>(new int()));
- EXPECT_EQ(vec.size(), 4);
+ EXPECT_EQ(vec.size(), 4u);
std::unique_ptr<int> &a = vec.last();
std::unique_ptr<int> b = vec.pop_last();
vec.remove_and_reorder(0);
vec.remove(0);
- EXPECT_EQ(vec.size(), 1);
+ EXPECT_EQ(vec.size(), 1u);
UNUSED_VARS(a, b);
}
@@ -593,29 +593,29 @@ TEST(vector, Resize)
{
std::string long_string = "012345678901234567890123456789";
Vector<std::string> vec;
- EXPECT_EQ(vec.size(), 0);
+ EXPECT_EQ(vec.size(), 0u);
vec.resize(2);
- EXPECT_EQ(vec.size(), 2);
+ EXPECT_EQ(vec.size(), 2u);
EXPECT_EQ(vec[0], "");
EXPECT_EQ(vec[1], "");
vec.resize(5, long_string);
- EXPECT_EQ(vec.size(), 5);
+ EXPECT_EQ(vec.size(), 5u);
EXPECT_EQ(vec[0], "");
EXPECT_EQ(vec[1], "");
EXPECT_EQ(vec[2], long_string);
EXPECT_EQ(vec[3], long_string);
EXPECT_EQ(vec[4], long_string);
vec.resize(1);
- EXPECT_EQ(vec.size(), 1);
+ EXPECT_EQ(vec.size(), 1u);
EXPECT_EQ(vec[0], "");
}
TEST(vector, FirstIndexOf)
{
Vector<int> vec = {2, 3, 5, 7, 5, 9};
- EXPECT_EQ(vec.first_index_of(2), 0);
- EXPECT_EQ(vec.first_index_of(5), 2);
- EXPECT_EQ(vec.first_index_of(9), 5);
+ EXPECT_EQ(vec.first_index_of(2), 0u);
+ EXPECT_EQ(vec.first_index_of(5), 2u);
+ EXPECT_EQ(vec.first_index_of(9), 5u);
}
TEST(vector, FirstIndexTryOf)
@@ -636,3 +636,5 @@ TEST(vector, OveralignedValues)
EXPECT_EQ((uintptr_t)&vec.last() % 512, 0);
}
}
+
+} // namespace blender
diff --git a/tests/gtests/blenlib/CMakeLists.txt b/tests/gtests/blenlib/CMakeLists.txt
index 8ddb2702b83..ba493b22b42 100644
--- a/tests/gtests/blenlib/CMakeLists.txt
+++ b/tests/gtests/blenlib/CMakeLists.txt
@@ -60,9 +60,9 @@ BLENDER_TEST(BLI_math_base "bf_blenlib")
BLENDER_TEST(BLI_math_bits "bf_blenlib")
BLENDER_TEST(BLI_math_color "bf_blenlib")
BLENDER_TEST(BLI_math_geom "bf_blenlib")
+BLENDER_TEST(BLI_math_matrix "bf_blenlib")
BLENDER_TEST(BLI_math_vector "bf_blenlib")
BLENDER_TEST(BLI_memiter "bf_blenlib")
-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")
diff --git a/tests/gtests/functions/CMakeLists.txt b/tests/gtests/functions/CMakeLists.txt
index 413761ed0c8..1246bbd5599 100644
--- a/tests/gtests/functions/CMakeLists.txt
+++ b/tests/gtests/functions/CMakeLists.txt
@@ -36,4 +36,10 @@ if(WITH_BUILDINFO)
set(BUILDINFO buildinfoobj)
endif()
+BLENDER_TEST(FN_array_spans "bf_blenlib;bf_functions;${BUILDINFO}")
+BLENDER_TEST(FN_attributes_ref "bf_blenlib;bf_functions;${BUILDINFO}")
BLENDER_TEST(FN_cpp_type "bf_blenlib;bf_functions;${BUILDINFO}")
+BLENDER_TEST(FN_generic_vector_array "bf_blenlib;bf_functions;${BUILDINFO}")
+BLENDER_TEST(FN_multi_function "bf_blenlib;bf_functions;${BUILDINFO}")
+BLENDER_TEST(FN_multi_function_network "bf_blenlib;bf_functions;${BUILDINFO}")
+BLENDER_TEST(FN_spans "bf_blenlib;bf_functions;${BUILDINFO}")
diff --git a/tests/gtests/functions/FN_array_spans_test.cc b/tests/gtests/functions/FN_array_spans_test.cc
new file mode 100644
index 00000000000..21e52a90e4b
--- /dev/null
+++ b/tests/gtests/functions/FN_array_spans_test.cc
@@ -0,0 +1,149 @@
+/*
+ * 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 "testing/testing.h"
+
+#include "FN_array_spans.hh"
+#include "FN_cpp_types.hh"
+#include "FN_generic_vector_array.hh"
+
+#include "BLI_array.hh"
+
+namespace blender {
+namespace fn {
+
+TEST(virtual_array_span, EmptyConstructor)
+{
+ VArraySpan<int> span;
+ EXPECT_EQ(span.size(), 0);
+ EXPECT_TRUE(span.is_empty());
+
+ GVArraySpan converted(span);
+ EXPECT_EQ(converted.type(), CPPType::get<int>());
+ EXPECT_EQ(converted.size(), 0);
+}
+
+TEST(virtual_array_span, SingleArrayConstructor)
+{
+ std::array<int, 4> values = {3, 4, 5, 6};
+ VArraySpan<int> span{Span<int>(values), 3};
+ EXPECT_EQ(span.size(), 3);
+ EXPECT_FALSE(span.is_empty());
+ EXPECT_EQ(span[0].size(), 4);
+ EXPECT_EQ(span[1].size(), 4);
+ EXPECT_EQ(span[2].size(), 4);
+ EXPECT_EQ(span[0][0], 3);
+ EXPECT_EQ(span[0][1], 4);
+ EXPECT_EQ(span[0][2], 5);
+ EXPECT_EQ(span[0][3], 6);
+ EXPECT_EQ(span[1][3], 6);
+ EXPECT_EQ(span[2][1], 4);
+
+ GVArraySpan converted(span);
+ EXPECT_EQ(converted.type(), CPPType::get<int>());
+ EXPECT_EQ(converted.size(), 3);
+ EXPECT_EQ(converted[0].size(), 4);
+ EXPECT_EQ(converted[1].size(), 4);
+ EXPECT_EQ(converted[1][2], &values[2]);
+}
+
+TEST(virtual_array_span, MultipleArrayConstructor)
+{
+ std::array<int, 4> values0 = {1, 2, 3, 4};
+ std::array<int, 2> values1 = {6, 7};
+ std::array<int, 1> values2 = {8};
+ std::array<const int *, 3> starts = {values0.data(), values1.data(), values2.data()};
+ std::array<uint, 3> sizes{values0.size(), values1.size(), values2.size()};
+
+ VArraySpan<int> span{starts, sizes};
+ EXPECT_EQ(span.size(), 3);
+ EXPECT_FALSE(span.is_empty());
+ EXPECT_EQ(span[0].size(), 4);
+ EXPECT_EQ(span[1].size(), 2);
+ EXPECT_EQ(span[2].size(), 1);
+ EXPECT_EQ(&span[0][0], values0.data());
+ EXPECT_EQ(&span[1][0], values1.data());
+ EXPECT_EQ(&span[2][0], values2.data());
+ EXPECT_EQ(span[2][0], 8);
+ EXPECT_EQ(span[1][1], 7);
+
+ GVArraySpan converted(span);
+ EXPECT_EQ(converted.type(), CPPType::get<int>());
+ EXPECT_EQ(converted.size(), 3);
+ EXPECT_EQ(converted[0].size(), 4);
+ EXPECT_EQ(converted[1].size(), 2);
+ EXPECT_EQ(converted[2].size(), 1);
+ EXPECT_EQ(converted[0][0], values0.data());
+ EXPECT_EQ(converted[1][1], values1.data() + 1);
+}
+
+TEST(generic_virtual_array_span, TypeConstructor)
+{
+ GVArraySpan span{CPPType_int32};
+ EXPECT_EQ(span.size(), 0);
+ EXPECT_TRUE(span.is_empty());
+
+ VArraySpan converted = span.typed<int>();
+ EXPECT_EQ(converted.size(), 0);
+}
+
+TEST(generic_virtual_array_span, GSpanConstructor)
+{
+ std::array<std::string, 3> values = {"hello", "world", "test"};
+ GVArraySpan span{GSpan(CPPType_string, values.data(), 3), 5};
+ EXPECT_EQ(span.size(), 5);
+ EXPECT_FALSE(span.is_empty());
+ EXPECT_EQ(span[0][0], values.data());
+ EXPECT_EQ(span[1][0], values.data());
+ EXPECT_EQ(span[4][0], values.data());
+ EXPECT_EQ(span[0].size(), 3);
+ EXPECT_EQ(span[2].size(), 3);
+ EXPECT_EQ(*(std::string *)span[3][1], "world");
+
+ VArraySpan converted = span.typed<std::string>();
+ EXPECT_EQ(converted.size(), 5);
+ EXPECT_EQ(converted[0][0], "hello");
+ EXPECT_EQ(converted[1][0], "hello");
+ EXPECT_EQ(converted[4][0], "hello");
+ EXPECT_EQ(converted[0].size(), 3);
+ EXPECT_EQ(converted[2].size(), 3);
+}
+
+TEST(generic_virtual_array_span, IsSingleArray1)
+{
+ Array<int> values = {5, 6, 7};
+ GVArraySpan span{GSpan(values.as_span()), 4};
+ EXPECT_TRUE(span.is_single_array());
+
+ VArraySpan converted = span.typed<int>();
+ EXPECT_TRUE(converted.is_single_array());
+}
+
+TEST(generic_virtual_array_span, IsSingleArray2)
+{
+ GVectorArray vectors{CPPType_int32, 3};
+ GVectorArrayRef<int> vectors_ref = vectors;
+ vectors_ref.append(1, 4);
+
+ GVArraySpan span = vectors;
+ EXPECT_FALSE(span.is_single_array());
+
+ VArraySpan converted = span.typed<int>();
+ EXPECT_FALSE(converted.is_single_array());
+}
+
+} // namespace fn
+} // namespace blender
diff --git a/tests/gtests/functions/FN_attributes_ref_test.cc b/tests/gtests/functions/FN_attributes_ref_test.cc
new file mode 100644
index 00000000000..111190564e5
--- /dev/null
+++ b/tests/gtests/functions/FN_attributes_ref_test.cc
@@ -0,0 +1,114 @@
+/*
+ * 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 "BLI_float3.hh"
+#include "FN_attributes_ref.hh"
+#include "FN_cpp_types.hh"
+
+#include "testing/testing.h"
+
+namespace blender {
+namespace fn {
+
+TEST(attributes_info, BuildEmpty)
+{
+ AttributesInfoBuilder info_builder;
+ AttributesInfo info{info_builder};
+
+ EXPECT_EQ(info.size(), 0);
+}
+
+TEST(attributes_info, AddSameNameTwice)
+{
+ AttributesInfoBuilder info_builder;
+ info_builder.add<int>("A", 4);
+ info_builder.add<int>("A", 5);
+ AttributesInfo info{info_builder};
+ EXPECT_EQ(info.size(), 1);
+ EXPECT_TRUE(info.has_attribute("A", CPPType::get<int>()));
+ EXPECT_FALSE(info.has_attribute("B", CPPType::get<int>()));
+ EXPECT_FALSE(info.has_attribute("A", CPPType::get<float>()));
+ EXPECT_EQ(info.default_of<int>("A"), 4);
+ EXPECT_EQ(info.name_of(0), "A");
+ EXPECT_EQ(info.index_range().start(), 0);
+ EXPECT_EQ(info.index_range().one_after_last(), 1);
+}
+
+TEST(attributes_info, BuildWithDefaultString)
+{
+ AttributesInfoBuilder info_builder;
+ info_builder.add("A", CPPType::get<std::string>());
+ AttributesInfo info{info_builder};
+ EXPECT_EQ(info.default_of<std::string>("A"), "");
+}
+
+TEST(attributes_info, BuildWithGivenDefault)
+{
+ AttributesInfoBuilder info_builder;
+ info_builder.add<std::string>("A", "hello world");
+ AttributesInfo info{info_builder};
+ const void *default_value = info.default_of("A");
+ EXPECT_EQ(*(const std::string *)default_value, "hello world");
+ EXPECT_EQ(info.type_of("A"), CPPType::get<std::string>());
+}
+
+TEST(mutable_attributes_ref, ComplexTest)
+{
+ AttributesInfoBuilder info_builder;
+ info_builder.add<float3>("Position", {0, 0, 10});
+ info_builder.add<uint>("ID", 0);
+ info_builder.add<float>("Size", 0.5f);
+ info_builder.add<std::string>("Name", "<no name>");
+ AttributesInfo info{info_builder};
+
+ uint amount = 5;
+ Array<float3> positions(amount);
+ Array<uint> ids(amount, 0);
+ Array<float> sizes(amount);
+ Array<std::string> names(amount);
+
+ Array<void *> buffers = {positions.data(), ids.data(), sizes.data(), names.data()};
+ MutableAttributesRef attributes{info, buffers, IndexRange(1, 3)};
+ EXPECT_EQ(attributes.size(), 3);
+ EXPECT_EQ(attributes.info().size(), 4);
+ EXPECT_EQ(attributes.get("Position").buffer(), positions.data() + 1);
+ EXPECT_EQ(attributes.get("ID").buffer(), ids.data() + 1);
+ EXPECT_EQ(attributes.get("Size").buffer(), sizes.data() + 1);
+ EXPECT_EQ(attributes.get("Name").buffer(), names.data() + 1);
+
+ EXPECT_EQ(attributes.get("ID").size(), 3);
+ EXPECT_EQ(attributes.get<uint>("ID").size(), 3);
+
+ EXPECT_EQ(ids[2], 0);
+ MutableSpan<uint> ids_span = attributes.get<uint>("ID");
+ ids_span[1] = 42;
+ EXPECT_EQ(ids[2], 42);
+
+ EXPECT_FALSE(attributes.try_get<int>("not existant").has_value());
+ EXPECT_FALSE(attributes.try_get<int>("Position").has_value());
+ EXPECT_TRUE(attributes.try_get<float3>("Position").has_value());
+ EXPECT_FALSE(attributes.try_get("not existant", CPPType::get<int>()).has_value());
+ EXPECT_FALSE(attributes.try_get("Position", CPPType::get<int>()).has_value());
+ EXPECT_TRUE(attributes.try_get("Position", CPPType::get<float3>()).has_value());
+
+ MutableAttributesRef sliced = attributes.slice(IndexRange(1, 2));
+ EXPECT_EQ(sliced.size(), 2);
+ sliced.get<uint>("ID")[0] = 100;
+ EXPECT_EQ(ids[2], 100);
+}
+
+} // namespace fn
+} // namespace blender
diff --git a/tests/gtests/functions/FN_cpp_type_test.cc b/tests/gtests/functions/FN_cpp_type_test.cc
index 811e1a5d783..33e6fbee7f6 100644
--- a/tests/gtests/functions/FN_cpp_type_test.cc
+++ b/tests/gtests/functions/FN_cpp_type_test.cc
@@ -12,7 +12,6 @@
* 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 "testing/testing.h"
@@ -20,7 +19,7 @@
#include "FN_cpp_type.hh"
namespace blender {
-namespace FN {
+namespace fn {
static const int default_constructed_value = 1;
static const int copy_constructed_value = 2;
@@ -85,6 +84,12 @@ TEST(cpp_type, Alignment)
EXPECT_EQ(CPPType_TestType.alignment(), alignof(TestType));
}
+TEST(cpp_type, Is)
+{
+ EXPECT_TRUE(CPPType_TestType.is<TestType>());
+ EXPECT_FALSE(CPPType_TestType.is<int>());
+}
+
TEST(cpp_type, DefaultConstruction)
{
int buffer[10] = {0};
@@ -301,5 +306,5 @@ TEST(cpp_type, FillUninitialized)
EXPECT_EQ(buffer2[9], 0);
}
-} // namespace FN
+} // namespace fn
} // namespace blender
diff --git a/tests/gtests/functions/FN_generic_vector_array_test.cc b/tests/gtests/functions/FN_generic_vector_array_test.cc
new file mode 100644
index 00000000000..c701fb9f678
--- /dev/null
+++ b/tests/gtests/functions/FN_generic_vector_array_test.cc
@@ -0,0 +1,118 @@
+/*
+ * 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 "FN_cpp_types.hh"
+#include "FN_generic_vector_array.hh"
+
+#include "testing/testing.h"
+
+namespace blender {
+namespace fn {
+
+TEST(generic_vector_array, Constructor)
+{
+ GVectorArray vectors{CPPType_int32, 3};
+ EXPECT_EQ(vectors.size(), 3);
+ EXPECT_EQ(vectors.lengths().size(), 3);
+ EXPECT_EQ(vectors.starts().size(), 3);
+ EXPECT_EQ(vectors.lengths()[0], 0);
+ EXPECT_EQ(vectors.lengths()[1], 0);
+ EXPECT_EQ(vectors.lengths()[2], 0);
+ EXPECT_EQ(vectors.type(), CPPType_int32);
+}
+
+TEST(generic_vector_array, Append)
+{
+ GVectorArray vectors{CPPType_string, 3};
+ std::string value = "hello";
+ vectors.append(0, &value);
+ value = "world";
+ vectors.append(0, &value);
+ vectors.append(2, &value);
+
+ EXPECT_EQ(vectors.lengths()[0], 2);
+ EXPECT_EQ(vectors.lengths()[1], 0);
+ EXPECT_EQ(vectors.lengths()[2], 1);
+ EXPECT_EQ(vectors[0].size(), 2);
+ EXPECT_EQ(vectors[0].typed<std::string>()[0], "hello");
+ EXPECT_EQ(vectors[0].typed<std::string>()[1], "world");
+ EXPECT_EQ(vectors[2].typed<std::string>()[0], "world");
+}
+
+TEST(generic_vector_array, AsArraySpan)
+{
+ GVectorArray vectors{CPPType_int32, 3};
+ int value = 3;
+ vectors.append(0, &value);
+ vectors.append(0, &value);
+ value = 5;
+ vectors.append(2, &value);
+ vectors.append(2, &value);
+ vectors.append(2, &value);
+
+ GVArraySpan span = vectors;
+ EXPECT_EQ(span.type(), CPPType_int32);
+ EXPECT_EQ(span.size(), 3);
+ EXPECT_EQ(span[0].size(), 2);
+ EXPECT_EQ(span[1].size(), 0);
+ EXPECT_EQ(span[2].size(), 3);
+ EXPECT_EQ(span[0].typed<int>()[1], 3);
+ EXPECT_EQ(span[2].typed<int>()[0], 5);
+}
+
+TEST(generic_vector_array, TypedRef)
+{
+ GVectorArray vectors{CPPType_int32, 4};
+ GVectorArrayRef<int> ref = vectors.typed<int>();
+ ref.append(0, 2);
+ ref.append(0, 6);
+ ref.append(0, 7);
+ ref.append(2, 1);
+ ref.append(2, 1);
+ ref.append(3, 5);
+ ref.append(3, 6);
+
+ EXPECT_EQ(ref[0].size(), 3);
+ EXPECT_EQ(vectors[0].size(), 3);
+ EXPECT_EQ(ref[0][0], 2);
+ EXPECT_EQ(ref[0][1], 6);
+ EXPECT_EQ(ref[0][2], 7);
+ EXPECT_EQ(ref[1].size(), 0);
+ EXPECT_EQ(ref[2][0], 1);
+ EXPECT_EQ(ref[2][1], 1);
+ EXPECT_EQ(ref[3][0], 5);
+ EXPECT_EQ(ref[3][1], 6);
+}
+
+TEST(generic_vector_array, Extend)
+{
+ GVectorArray vectors{CPPType_int32, 3};
+ GVectorArrayRef<int> ref = vectors;
+
+ ref.extend(1, {5, 6, 7});
+ ref.extend(0, {3});
+
+ EXPECT_EQ(vectors[0].size(), 1);
+ EXPECT_EQ(vectors[1].size(), 3);
+ EXPECT_EQ(vectors[2].size(), 0);
+ EXPECT_EQ(ref[1][0], 5);
+ EXPECT_EQ(ref[1][1], 6);
+ EXPECT_EQ(ref[1][2], 7);
+ EXPECT_EQ(ref[0][0], 3);
+}
+
+} // namespace fn
+} // namespace blender
diff --git a/tests/gtests/functions/FN_multi_function_network_test.cc b/tests/gtests/functions/FN_multi_function_network_test.cc
new file mode 100644
index 00000000000..a5fe3c4fb07
--- /dev/null
+++ b/tests/gtests/functions/FN_multi_function_network_test.cc
@@ -0,0 +1,270 @@
+/*
+ * 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 "testing/testing.h"
+
+#include "FN_cpp_types.hh"
+#include "FN_multi_function_builder.hh"
+#include "FN_multi_function_network.hh"
+#include "FN_multi_function_network_evaluation.hh"
+
+namespace blender {
+namespace fn {
+
+TEST(multi_function_network, Test1)
+{
+ CustomMF_SI_SO<int, int> add_10_fn("add 10", [](int value) { return value + 10; });
+ CustomMF_SI_SI_SO<int, int, int> multiply_fn("multiply", [](int a, int b) { return a * b; });
+
+ MFNetwork network;
+
+ MFNode &node1 = network.add_function(add_10_fn);
+ MFNode &node2 = network.add_function(multiply_fn);
+ MFOutputSocket &input_socket = network.add_input("Input", MFDataType::ForSingle<int>());
+ MFInputSocket &output_socket = network.add_output("Output", MFDataType::ForSingle<int>());
+ network.add_link(node1.output(0), node2.input(0));
+ network.add_link(node1.output(0), node2.input(1));
+ network.add_link(node2.output(0), output_socket);
+ network.add_link(input_socket, node1.input(0));
+
+ MFNetworkEvaluator network_fn{{&input_socket}, {&output_socket}};
+
+ {
+ Array<int> values = {4, 6, 1, 2, 0};
+ Array<int> results(values.size(), 0);
+
+ MFParamsBuilder params(network_fn, values.size());
+ params.add_readonly_single_input(values.as_span());
+ params.add_uninitialized_single_output(results.as_mutable_span());
+
+ MFContextBuilder context;
+
+ network_fn.call({0, 2, 3, 4}, params, context);
+
+ EXPECT_EQ(results[0], 14 * 14);
+ EXPECT_EQ(results[1], 0);
+ EXPECT_EQ(results[2], 11 * 11);
+ EXPECT_EQ(results[3], 12 * 12);
+ EXPECT_EQ(results[4], 10 * 10);
+ }
+ {
+ int value = 3;
+ Array<int> results(5, 0);
+
+ MFParamsBuilder params(network_fn, results.size());
+ params.add_readonly_single_input(&value);
+ params.add_uninitialized_single_output(results.as_mutable_span());
+
+ MFContextBuilder context;
+
+ network_fn.call({1, 2, 4}, params, context);
+
+ EXPECT_EQ(results[0], 0);
+ EXPECT_EQ(results[1], 13 * 13);
+ EXPECT_EQ(results[2], 13 * 13);
+ EXPECT_EQ(results[3], 0);
+ EXPECT_EQ(results[4], 13 * 13);
+ }
+}
+
+class ConcatVectorsFunction : public MultiFunction {
+ public:
+ ConcatVectorsFunction()
+ {
+ MFSignatureBuilder signature = this->get_builder("Concat Vectors");
+ signature.vector_mutable<int>("A");
+ signature.vector_input<int>("B");
+ }
+
+ void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override
+ {
+ GVectorArrayRef<int> a = params.vector_mutable<int>(0);
+ VArraySpan<int> b = params.readonly_vector_input<int>(1);
+
+ for (uint i : mask) {
+ a.extend(i, b[i]);
+ }
+ }
+};
+
+class AppendFunction : public MultiFunction {
+ public:
+ AppendFunction()
+ {
+ MFSignatureBuilder signature = this->get_builder("Append");
+ signature.vector_mutable<int>("Vector");
+ signature.single_input<int>("Value");
+ }
+
+ void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override
+ {
+ GVectorArrayRef<int> vectors = params.vector_mutable<int>(0);
+ VSpan<int> values = params.readonly_single_input<int>(1);
+
+ for (uint i : mask) {
+ vectors.append(i, values[i]);
+ }
+ }
+};
+
+class SumVectorFunction : public MultiFunction {
+ public:
+ SumVectorFunction()
+ {
+ MFSignatureBuilder signature = this->get_builder("Sum Vector");
+ signature.vector_input<int>("Vector");
+ signature.single_output<int>("Sum");
+ }
+
+ void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override
+ {
+ VArraySpan<int> vectors = params.readonly_vector_input<int>(0);
+ MutableSpan<int> sums = params.uninitialized_single_output<int>(1);
+
+ for (uint i : mask) {
+ int sum = 0;
+ VSpan<int> vector = vectors[i];
+ for (uint j = 0; j < vector.size(); j++) {
+ sum += vector[j];
+ }
+ sums[i] = sum;
+ }
+ }
+};
+
+class CreateRangeFunction : public MultiFunction {
+ public:
+ CreateRangeFunction()
+ {
+ MFSignatureBuilder builder = this->get_builder("Create Range");
+ builder.single_input<int>("Size");
+ builder.vector_output<int>("Range");
+ }
+
+ void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override
+ {
+ VSpan<int> sizes = params.readonly_single_input<int>(0, "Size");
+ GVectorArrayRef<int> ranges = params.vector_output<int>(1, "Range");
+
+ for (int i : mask) {
+ int size = sizes[i];
+ for (int j : IndexRange(size)) {
+ ranges.append(i, j);
+ }
+ }
+ }
+};
+
+TEST(multi_function_network, Test2)
+{
+ CustomMF_SI_SO<int, int> add_3_fn("add 3", [](int value) { return value + 3; });
+
+ ConcatVectorsFunction concat_vectors_fn;
+ AppendFunction append_fn;
+ SumVectorFunction sum_fn;
+ CreateRangeFunction create_range_fn;
+
+ MFNetwork network;
+
+ MFOutputSocket &input1 = network.add_input("Input 1", MFDataType::ForVector<int>());
+ MFOutputSocket &input2 = network.add_input("Input 2", MFDataType::ForSingle<int>());
+ MFInputSocket &output1 = network.add_output("Output 1", MFDataType::ForVector<int>());
+ MFInputSocket &output2 = network.add_output("Output 2", MFDataType::ForSingle<int>());
+
+ MFNode &node1 = network.add_function(add_3_fn);
+ MFNode &node2 = network.add_function(create_range_fn);
+ MFNode &node3 = network.add_function(concat_vectors_fn);
+ MFNode &node4 = network.add_function(sum_fn);
+ MFNode &node5 = network.add_function(append_fn);
+ MFNode &node6 = network.add_function(sum_fn);
+
+ network.add_link(input2, node1.input(0));
+ network.add_link(node1.output(0), node2.input(0));
+ network.add_link(node2.output(0), node3.input(1));
+ network.add_link(input1, node3.input(0));
+ network.add_link(input1, node4.input(0));
+ network.add_link(node4.output(0), node5.input(1));
+ network.add_link(node3.output(0), node5.input(0));
+ network.add_link(node5.output(0), node6.input(0));
+ network.add_link(node3.output(0), output1);
+ network.add_link(node6.output(0), output2);
+
+ // std::cout << network.to_dot() << "\n\n";
+
+ MFNetworkEvaluator network_fn{{&input1, &input2}, {&output1, &output2}};
+
+ {
+ Array<int> input_value_1 = {3, 6};
+ int input_value_2 = 4;
+
+ GVectorArray output_value_1(CPPType_int32, 5);
+ Array<int> output_value_2(5, -1);
+
+ MFParamsBuilder params(network_fn, 5);
+ params.add_readonly_vector_input(GVArraySpan(input_value_1.as_span(), 5));
+ params.add_readonly_single_input(&input_value_2);
+ params.add_vector_output(output_value_1);
+ params.add_uninitialized_single_output(output_value_2.as_mutable_span());
+
+ MFContextBuilder context;
+
+ network_fn.call({1, 2, 4}, params, context);
+
+ EXPECT_EQ(output_value_1[0].size(), 0);
+ EXPECT_EQ(output_value_1[1].size(), 9);
+ EXPECT_EQ(output_value_1[2].size(), 9);
+ EXPECT_EQ(output_value_1[3].size(), 0);
+ EXPECT_EQ(output_value_1[4].size(), 9);
+
+ EXPECT_EQ(output_value_2[0], -1);
+ EXPECT_EQ(output_value_2[1], 39);
+ EXPECT_EQ(output_value_2[2], 39);
+ EXPECT_EQ(output_value_2[3], -1);
+ EXPECT_EQ(output_value_2[4], 39);
+ }
+ {
+ GVectorArray input_value_1(CPPType_int32, 3);
+ GVectorArrayRef<int> input_value_ref_1 = input_value_1;
+ input_value_ref_1.extend(0, {3, 4, 5});
+ input_value_ref_1.extend(1, {1, 2});
+
+ Array<int> input_value_2 = {4, 2, 3};
+
+ GVectorArray output_value_1(CPPType_int32, 3);
+ Array<int> output_value_2(3, -1);
+
+ MFParamsBuilder params(network_fn, 3);
+ params.add_readonly_vector_input(input_value_1);
+ params.add_readonly_single_input(input_value_2.as_span());
+ params.add_vector_output(output_value_1);
+ params.add_uninitialized_single_output(output_value_2.as_mutable_span());
+
+ MFContextBuilder context;
+
+ network_fn.call({0, 1, 2}, params, context);
+
+ EXPECT_EQ(output_value_1[0].size(), 10);
+ EXPECT_EQ(output_value_1[1].size(), 7);
+ EXPECT_EQ(output_value_1[2].size(), 6);
+
+ EXPECT_EQ(output_value_2[0], 45);
+ EXPECT_EQ(output_value_2[1], 16);
+ EXPECT_EQ(output_value_2[2], 15);
+ }
+}
+
+} // namespace fn
+} // namespace blender
diff --git a/tests/gtests/functions/FN_multi_function_test.cc b/tests/gtests/functions/FN_multi_function_test.cc
new file mode 100644
index 00000000000..903c385ea67
--- /dev/null
+++ b/tests/gtests/functions/FN_multi_function_test.cc
@@ -0,0 +1,334 @@
+/*
+ * 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 "testing/testing.h"
+
+#include "FN_cpp_types.hh"
+#include "FN_multi_function.hh"
+#include "FN_multi_function_builder.hh"
+
+namespace blender {
+namespace fn {
+
+class AddFunction : public MultiFunction {
+ public:
+ AddFunction()
+ {
+ MFSignatureBuilder builder = this->get_builder("Add");
+ builder.single_input<int>("A");
+ builder.single_input<int>("B");
+ builder.single_output<int>("Result");
+ }
+
+ void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override
+ {
+ VSpan<int> a = params.readonly_single_input<int>(0, "A");
+ VSpan<int> b = params.readonly_single_input<int>(1, "B");
+ MutableSpan<int> result = params.uninitialized_single_output<int>(2, "Result");
+
+ for (uint i : mask) {
+ result[i] = a[i] + b[i];
+ }
+ }
+};
+
+TEST(multi_function, AddFunction)
+{
+ AddFunction fn;
+
+ Array<int> input1 = {4, 5, 6};
+ Array<int> input2 = {10, 20, 30};
+ Array<int> output(3, -1);
+
+ MFParamsBuilder params(fn, 3);
+ params.add_readonly_single_input(input1.as_span());
+ params.add_readonly_single_input(input2.as_span());
+ params.add_uninitialized_single_output(output.as_mutable_span());
+
+ MFContextBuilder context;
+
+ fn.call({0, 2}, params, context);
+
+ EXPECT_EQ(output[0], 14);
+ EXPECT_EQ(output[1], -1);
+ EXPECT_EQ(output[2], 36);
+}
+
+class AddPrefixFunction : public MultiFunction {
+ public:
+ AddPrefixFunction()
+ {
+ MFSignatureBuilder builder = this->get_builder("Add Prefix");
+ builder.single_input<std::string>("Prefix");
+ builder.single_mutable<std::string>("Strings");
+ }
+
+ void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override
+ {
+ VSpan<std::string> prefixes = params.readonly_single_input<std::string>(0, "Prefix");
+ MutableSpan<std::string> strings = params.single_mutable<std::string>(1, "Strings");
+
+ for (uint i : mask) {
+ strings[i] = prefixes[i] + strings[i];
+ }
+ }
+};
+
+TEST(multi_function, AddPrefixFunction)
+{
+ AddPrefixFunction fn;
+
+ Array<std::string> strings = {
+ "Hello",
+ "World",
+ "This is a test",
+ "Another much longer string to trigger an allocation",
+ };
+
+ std::string prefix = "AB";
+
+ MFParamsBuilder params(fn, strings.size());
+ params.add_readonly_single_input(&prefix);
+ params.add_single_mutable(strings.as_mutable_span());
+
+ MFContextBuilder context;
+
+ fn.call({0, 2, 3}, params, context);
+
+ EXPECT_EQ(strings[0], "ABHello");
+ EXPECT_EQ(strings[1], "World");
+ EXPECT_EQ(strings[2], "ABThis is a test");
+ EXPECT_EQ(strings[3], "ABAnother much longer string to trigger an allocation");
+}
+
+class CreateRangeFunction : public MultiFunction {
+ public:
+ CreateRangeFunction()
+ {
+ MFSignatureBuilder builder = this->get_builder("Create Range");
+ builder.single_input<uint>("Size");
+ builder.vector_output<uint>("Range");
+ }
+
+ void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override
+ {
+ VSpan<uint> sizes = params.readonly_single_input<uint>(0, "Size");
+ GVectorArrayRef<uint> ranges = params.vector_output<uint>(1, "Range");
+
+ for (uint i : mask) {
+ uint size = sizes[i];
+ for (uint j : IndexRange(size)) {
+ ranges.append(i, j);
+ }
+ }
+ }
+};
+
+TEST(multi_function, CreateRangeFunction)
+{
+ CreateRangeFunction fn;
+
+ GVectorArray ranges(CPPType_uint32, 5);
+ GVectorArrayRef<uint> ranges_ref(ranges);
+ Array<uint> sizes = {3, 0, 6, 1, 4};
+
+ MFParamsBuilder params(fn, ranges.size());
+ params.add_readonly_single_input(sizes.as_span());
+ params.add_vector_output(ranges);
+
+ MFContextBuilder context;
+
+ fn.call({0, 1, 2, 3}, params, context);
+
+ EXPECT_EQ(ranges_ref[0].size(), 3);
+ EXPECT_EQ(ranges_ref[1].size(), 0);
+ EXPECT_EQ(ranges_ref[2].size(), 6);
+ EXPECT_EQ(ranges_ref[3].size(), 1);
+ EXPECT_EQ(ranges_ref[4].size(), 0);
+
+ EXPECT_EQ(ranges_ref[0][0], 0);
+ EXPECT_EQ(ranges_ref[0][1], 1);
+ EXPECT_EQ(ranges_ref[0][2], 2);
+ EXPECT_EQ(ranges_ref[2][0], 0);
+ EXPECT_EQ(ranges_ref[2][1], 1);
+}
+
+class GenericAppendFunction : public MultiFunction {
+ public:
+ GenericAppendFunction(const CPPType &type)
+ {
+ MFSignatureBuilder builder = this->get_builder("Append");
+ builder.vector_mutable("Vector", type);
+ builder.single_input("Value", type);
+ }
+
+ void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override
+ {
+ GVectorArray &vectors = params.vector_mutable(0, "Vector");
+ GVSpan values = params.readonly_single_input(1, "Value");
+
+ for (uint i : mask) {
+ vectors.append(i, values[i]);
+ }
+ }
+};
+
+TEST(multi_function, GenericAppendFunction)
+{
+ GenericAppendFunction fn(CPPType_int32);
+
+ GVectorArray vectors(CPPType_int32, 4);
+ GVectorArrayRef<int> vectors_ref(vectors);
+ vectors_ref.append(0, 1);
+ vectors_ref.append(0, 2);
+ vectors_ref.append(2, 6);
+ Array<int> values = {5, 7, 3, 1};
+
+ MFParamsBuilder params(fn, vectors.size());
+ params.add_vector_mutable(vectors);
+ params.add_readonly_single_input(values.as_span());
+
+ MFContextBuilder context;
+
+ fn.call(IndexRange(vectors.size()), params, context);
+
+ EXPECT_EQ(vectors_ref[0].size(), 3);
+ EXPECT_EQ(vectors_ref[1].size(), 1);
+ EXPECT_EQ(vectors_ref[2].size(), 2);
+ EXPECT_EQ(vectors_ref[3].size(), 1);
+
+ EXPECT_EQ(vectors_ref[0][0], 1);
+ EXPECT_EQ(vectors_ref[0][1], 2);
+ EXPECT_EQ(vectors_ref[0][2], 5);
+ EXPECT_EQ(vectors_ref[1][0], 7);
+ EXPECT_EQ(vectors_ref[2][0], 6);
+ EXPECT_EQ(vectors_ref[2][1], 3);
+ EXPECT_EQ(vectors_ref[3][0], 1);
+}
+
+TEST(multi_function, CustomMF_SI_SO)
+{
+ CustomMF_SI_SO<std::string, uint> fn("strlen",
+ [](const std::string &str) { return str.size(); });
+
+ Array<std::string> strings = {"hello", "world", "test", "another test"};
+ Array<uint> sizes(strings.size(), 0);
+
+ MFParamsBuilder params(fn, strings.size());
+ params.add_readonly_single_input(strings.as_span());
+ params.add_uninitialized_single_output(sizes.as_mutable_span());
+
+ MFContextBuilder context;
+
+ fn.call(IndexRange(strings.size()), params, context);
+
+ EXPECT_EQ(sizes[0], 5);
+ EXPECT_EQ(sizes[1], 5);
+ EXPECT_EQ(sizes[2], 4);
+ EXPECT_EQ(sizes[3], 12);
+}
+
+TEST(multi_function, CustomMF_SI_SI_SO)
+{
+ CustomMF_SI_SI_SO<int, int, int> fn("mul", [](int a, int b) { return a * b; });
+
+ Array<int> values_a = {4, 6, 8, 9};
+ int value_b = 10;
+ Array<int> outputs(values_a.size(), -1);
+
+ MFParamsBuilder params(fn, values_a.size());
+ params.add_readonly_single_input(values_a.as_span());
+ params.add_readonly_single_input(&value_b);
+ params.add_uninitialized_single_output(outputs.as_mutable_span());
+
+ MFContextBuilder context;
+
+ fn.call({0, 1, 3}, params, context);
+
+ EXPECT_EQ(outputs[0], 40);
+ EXPECT_EQ(outputs[1], 60);
+ EXPECT_EQ(outputs[2], -1);
+ EXPECT_EQ(outputs[3], 90);
+}
+
+TEST(multi_function, CustomMF_SI_SI_SI_SO)
+{
+ CustomMF_SI_SI_SI_SO<int, std::string, bool, uint> fn{
+ "custom",
+ [](int a, const std::string &b, bool c) { return (uint)((uint)a + b.size() + (uint)c); }};
+
+ Array<int> values_a = {5, 7, 3, 8};
+ Array<std::string> values_b = {"hello", "world", "another", "test"};
+ Array<bool> values_c = {true, false, false, true};
+ Array<uint> outputs(values_a.size(), 0);
+
+ MFParamsBuilder params(fn, values_a.size());
+ params.add_readonly_single_input(values_a.as_span());
+ params.add_readonly_single_input(values_b.as_span());
+ params.add_readonly_single_input(values_c.as_span());
+ params.add_uninitialized_single_output(outputs.as_mutable_span());
+
+ MFContextBuilder context;
+
+ fn.call({1, 2, 3}, params, context);
+
+ EXPECT_EQ(outputs[0], 0);
+ EXPECT_EQ(outputs[1], 12);
+ EXPECT_EQ(outputs[2], 10);
+ EXPECT_EQ(outputs[3], 13);
+}
+
+TEST(multi_function, CustomMF_SM)
+{
+ CustomMF_SM<std::string> fn("AddSuffix", [](std::string &value) { value += " test"; });
+
+ Array<std::string> values = {"a", "b", "c", "d", "e"};
+
+ MFParamsBuilder params(fn, values.size());
+ params.add_single_mutable(values.as_mutable_span());
+
+ MFContextBuilder context;
+
+ fn.call({1, 2, 3}, params, context);
+
+ EXPECT_EQ(values[0], "a");
+ EXPECT_EQ(values[1], "b test");
+ EXPECT_EQ(values[2], "c test");
+ EXPECT_EQ(values[3], "d test");
+ EXPECT_EQ(values[4], "e");
+}
+
+TEST(multi_function, CustomMF_Constant)
+{
+ CustomMF_Constant<int> fn{42};
+
+ Array<int> outputs(4, 0);
+
+ MFParamsBuilder params(fn, outputs.size());
+ params.add_uninitialized_single_output(outputs.as_mutable_span());
+
+ MFContextBuilder context;
+
+ fn.call({0, 2, 3}, params, context);
+
+ EXPECT_EQ(outputs[0], 42);
+ EXPECT_EQ(outputs[1], 0);
+ EXPECT_EQ(outputs[2], 42);
+ EXPECT_EQ(outputs[3], 42);
+}
+
+} // namespace fn
+} // namespace blender
diff --git a/tests/gtests/functions/FN_spans_test.cc b/tests/gtests/functions/FN_spans_test.cc
new file mode 100644
index 00000000000..59797f69309
--- /dev/null
+++ b/tests/gtests/functions/FN_spans_test.cc
@@ -0,0 +1,231 @@
+/*
+ * 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 "testing/testing.h"
+
+#include "FN_cpp_types.hh"
+#include "FN_spans.hh"
+
+namespace blender {
+namespace fn {
+
+TEST(generic_span, TypeConstructor)
+{
+ GSpan span(CPPType_float);
+ EXPECT_EQ(span.size(), 0);
+ EXPECT_EQ(span.typed<float>().size(), 0);
+ EXPECT_TRUE(span.is_empty());
+}
+
+TEST(generic_span, BufferAndSizeConstructor)
+{
+ int values[4] = {6, 7, 3, 2};
+ void *buffer = (void *)values;
+ GSpan span(CPPType_int32, buffer, 4);
+ EXPECT_EQ(span.size(), 4);
+ EXPECT_FALSE(span.is_empty());
+ EXPECT_EQ(span.typed<int>().size(), 4);
+ EXPECT_EQ(span[0], &values[0]);
+ EXPECT_EQ(span[1], &values[1]);
+ EXPECT_EQ(span[2], &values[2]);
+ EXPECT_EQ(span[3], &values[3]);
+}
+
+TEST(generic_mutable_span, TypeConstructor)
+{
+ GMutableSpan span(CPPType_int32);
+ EXPECT_EQ(span.size(), 0);
+ EXPECT_TRUE(span.is_empty());
+}
+
+TEST(generic_mutable_span, BufferAndSizeConstructor)
+{
+ int values[4] = {4, 7, 3, 5};
+ void *buffer = (void *)values;
+ GMutableSpan span(CPPType_int32, buffer, 4);
+ EXPECT_EQ(span.size(), 4);
+ EXPECT_FALSE(span.is_empty());
+ EXPECT_EQ(span.typed<int>().size(), 4);
+ EXPECT_EQ(values[2], 3);
+ *(int *)span[2] = 10;
+ EXPECT_EQ(values[2], 10);
+ span.typed<int>()[2] = 20;
+ EXPECT_EQ(values[2], 20);
+}
+
+TEST(virtual_span, EmptyConstructor)
+{
+ VSpan<int> span;
+ EXPECT_EQ(span.size(), 0);
+ EXPECT_TRUE(span.is_empty());
+ EXPECT_FALSE(span.is_single_element());
+
+ GVSpan converted(span);
+ EXPECT_EQ(converted.type(), CPPType::get<int>());
+ EXPECT_EQ(converted.size(), 0);
+}
+
+TEST(virtual_span, SpanConstructor)
+{
+ std::array<int, 5> values = {7, 3, 8, 6, 4};
+ Span<int> span = values;
+ VSpan<int> virtual_span = span;
+ EXPECT_EQ(virtual_span.size(), 5);
+ EXPECT_FALSE(virtual_span.is_empty());
+ EXPECT_EQ(virtual_span[0], 7);
+ EXPECT_EQ(virtual_span[2], 8);
+ EXPECT_EQ(virtual_span[3], 6);
+ EXPECT_FALSE(virtual_span.is_single_element());
+
+ GVSpan converted(span);
+ EXPECT_EQ(converted.type(), CPPType::get<int>());
+ EXPECT_EQ(converted.size(), 5);
+}
+
+TEST(virtual_span, PointerSpanConstructor)
+{
+ int x0 = 3;
+ int x1 = 6;
+ int x2 = 7;
+ std::array<const int *, 3> pointers = {&x0, &x2, &x1};
+ VSpan<int> span = Span<const int *>(pointers);
+ EXPECT_EQ(span.size(), 3);
+ EXPECT_FALSE(span.is_empty());
+ EXPECT_EQ(span[0], 3);
+ EXPECT_EQ(span[1], 7);
+ EXPECT_EQ(span[2], 6);
+ EXPECT_EQ(&span[1], &x2);
+ EXPECT_FALSE(span.is_single_element());
+
+ GVSpan converted(span);
+ EXPECT_EQ(converted.type(), CPPType::get<int>());
+ EXPECT_EQ(converted.size(), 3);
+ EXPECT_EQ(converted[0], &x0);
+ EXPECT_EQ(converted[1], &x2);
+ EXPECT_EQ(converted[2], &x1);
+}
+
+TEST(virtual_span, SingleConstructor)
+{
+ int value = 5;
+ VSpan<int> span = VSpan<int>::FromSingle(&value, 3);
+ EXPECT_EQ(span.size(), 3);
+ EXPECT_FALSE(span.is_empty());
+ EXPECT_EQ(span[0], 5);
+ EXPECT_EQ(span[1], 5);
+ EXPECT_EQ(span[2], 5);
+ EXPECT_EQ(&span[0], &value);
+ EXPECT_EQ(&span[1], &value);
+ EXPECT_EQ(&span[2], &value);
+ EXPECT_TRUE(span.is_single_element());
+
+ GVSpan converted(span);
+ EXPECT_EQ(converted.type(), CPPType::get<int>());
+ EXPECT_EQ(converted.size(), 3);
+ EXPECT_EQ(converted[0], &value);
+ EXPECT_EQ(converted[1], &value);
+ EXPECT_EQ(converted[2], &value);
+}
+
+TEST(generic_virtual_span, TypeConstructor)
+{
+ GVSpan span(CPPType_int32);
+ EXPECT_EQ(span.size(), 0);
+ EXPECT_TRUE(span.is_empty());
+ EXPECT_FALSE(span.is_single_element());
+
+ VSpan<int> converted = span.typed<int>();
+ EXPECT_EQ(converted.size(), 0);
+}
+
+TEST(generic_virtual_span, GenericSpanConstructor)
+{
+ int values[4] = {3, 4, 5, 6};
+ GVSpan span{GSpan(CPPType_int32, values, 4)};
+ EXPECT_EQ(span.size(), 4);
+ EXPECT_FALSE(span.is_empty());
+ EXPECT_EQ(span[0], &values[0]);
+ EXPECT_EQ(span[1], &values[1]);
+ EXPECT_EQ(span[2], &values[2]);
+ EXPECT_EQ(span[3], &values[3]);
+ EXPECT_FALSE(span.is_single_element());
+
+ int materialized[4] = {0};
+ span.materialize_to_uninitialized(materialized);
+ EXPECT_EQ(materialized[0], 3);
+ EXPECT_EQ(materialized[1], 4);
+ EXPECT_EQ(materialized[2], 5);
+ EXPECT_EQ(materialized[3], 6);
+
+ VSpan<int> converted = span.typed<int>();
+ EXPECT_EQ(converted.size(), 4);
+ EXPECT_EQ(converted[0], 3);
+ EXPECT_EQ(converted[1], 4);
+ EXPECT_EQ(converted[2], 5);
+ EXPECT_EQ(converted[3], 6);
+}
+
+TEST(generic_virtual_span, SpanConstructor)
+{
+ std::array<int, 3> values = {6, 7, 8};
+ GVSpan span{Span<int>(values)};
+ EXPECT_EQ(span.type(), CPPType_int32);
+ EXPECT_EQ(span.size(), 3);
+ EXPECT_EQ(span[0], &values[0]);
+ EXPECT_EQ(span[1], &values[1]);
+ EXPECT_EQ(span[2], &values[2]);
+ EXPECT_FALSE(span.is_single_element());
+
+ int materialized[3] = {0};
+ span.materialize_to_uninitialized(materialized);
+ EXPECT_EQ(materialized[0], 6);
+ EXPECT_EQ(materialized[1], 7);
+ EXPECT_EQ(materialized[2], 8);
+
+ VSpan<int> converted = span.typed<int>();
+ EXPECT_EQ(converted.size(), 3);
+ EXPECT_EQ(converted[0], 6);
+ EXPECT_EQ(converted[1], 7);
+ EXPECT_EQ(converted[2], 8);
+}
+
+TEST(generic_virtual_span, SingleConstructor)
+{
+ int value = 5;
+ GVSpan span = GVSpan::FromSingle(CPPType_int32, &value, 3);
+ EXPECT_EQ(span.size(), 3);
+ EXPECT_FALSE(span.is_empty());
+ EXPECT_EQ(span[0], &value);
+ EXPECT_EQ(span[1], &value);
+ EXPECT_EQ(span[2], &value);
+ EXPECT_TRUE(span.is_single_element());
+ EXPECT_EQ(span.as_single_element(), &value);
+
+ int materialized[3] = {0};
+ span.materialize_to_uninitialized({1, 2}, materialized);
+ EXPECT_EQ(materialized[0], 0);
+ EXPECT_EQ(materialized[1], 5);
+ EXPECT_EQ(materialized[2], 5);
+
+ VSpan<int> converted = span.typed<int>();
+ EXPECT_EQ(converted.size(), 3);
+ EXPECT_EQ(converted[0], 5);
+ EXPECT_EQ(converted[1], 5);
+ EXPECT_EQ(converted[2], 5);
+}
+
+} // namespace fn
+} // namespace blender
diff --git a/tests/gtests/usd/CMakeLists.txt b/tests/gtests/usd/CMakeLists.txt
index 56759f4ccea..d2bfe5e1306 100644
--- a/tests/gtests/usd/CMakeLists.txt
+++ b/tests/gtests/usd/CMakeLists.txt
@@ -35,6 +35,7 @@ set(INC
..
../../../source/blender/blenlib
../../../source/blender/blenkernel
+ ../../../source/blender/io/common
../../../source/blender/io/usd
../../../source/blender/makesdna
../../../source/blender/depsgraph
@@ -52,6 +53,7 @@ set(LIB
bf_gpu
bf_usd
+ bf_io_common
${BOOST_LIBRARIES}
${TBB_LIBRARIES}
diff --git a/tests/gtests/usd/abstract_hierarchy_iterator_test.cc b/tests/gtests/usd/abstract_hierarchy_iterator_test.cc
index 160dd52f39a..d9148a7b289 100644
--- a/tests/gtests/usd/abstract_hierarchy_iterator_test.cc
+++ b/tests/gtests/usd/abstract_hierarchy_iterator_test.cc
@@ -16,8 +16,8 @@
* The Original Code is Copyright (C) 2019 Blender Foundation.
* All rights reserved.
*/
+#include "IO_abstract_hierarchy_iterator.h"
#include "blenloader/blendfile_loading_base_test.h"
-#include "intern/abstract_hierarchy_iterator.h"
extern "C" {
#include "BLI_math.h"
@@ -30,16 +30,16 @@ extern "C" {
/* Mapping from ID.name to set of export hierarchy path. Duplicated objects can be exported
* multiple times with different export paths, hence the set. */
-typedef std::map<std::string, std::set<std::string>> created_writers;
+typedef std::map<std::string, std::set<std::string>> used_writers;
-using namespace USD;
+using namespace blender::io;
class TestHierarchyWriter : public AbstractHierarchyWriter {
public:
std::string writer_type;
- created_writers &writers_map;
+ used_writers &writers_map;
- TestHierarchyWriter(const std::string &writer_type, created_writers &writers_map)
+ TestHierarchyWriter(const std::string &writer_type, used_writers &writers_map)
: writer_type(writer_type), writers_map(writers_map)
{
}
@@ -47,7 +47,7 @@ class TestHierarchyWriter : public AbstractHierarchyWriter {
void write(HierarchyContext &context) override
{
const char *id_name = context.object->id.name;
- created_writers::mapped_type &writers = writers_map[id_name];
+ used_writers::mapped_type &writers = writers_map[id_name];
if (writers.find(context.export_path) != writers.end()) {
ADD_FAILURE() << "Unexpectedly found another " << writer_type << " writer for " << id_name
@@ -57,7 +57,7 @@ class TestHierarchyWriter : public AbstractHierarchyWriter {
}
};
-void debug_print_writers(const char *label, const created_writers &writers_map)
+void debug_print_writers(const char *label, const used_writers &writers_map)
{
printf("%s:\n", label);
for (auto idname_writers : writers_map) {
@@ -70,10 +70,10 @@ void debug_print_writers(const char *label, const created_writers &writers_map)
class TestingHierarchyIterator : public AbstractHierarchyIterator {
public: /* Public so that the test cases can directly inspect the created writers. */
- created_writers transform_writers;
- created_writers data_writers;
- created_writers hair_writers;
- created_writers particle_writers;
+ used_writers transform_writers;
+ used_writers data_writers;
+ used_writers hair_writers;
+ used_writers particle_writers;
public:
explicit TestingHierarchyIterator(Depsgraph *depsgraph) : AbstractHierarchyIterator(depsgraph)
@@ -151,7 +151,7 @@ TEST_F(USDHierarchyIteratorTest, ExportHierarchyTest)
iterator->iterate_and_write();
// Mapping from object name to set of export paths.
- created_writers expected_transforms = {
+ used_writers expected_transforms = {
{"OBCamera", {"/Camera"}},
{"OBDupli1", {"/Dupli1"}},
{"OBDupli2", {"/ParentOfDupli2/Dupli2"}},
@@ -177,7 +177,7 @@ TEST_F(USDHierarchyIteratorTest, ExportHierarchyTest)
{"OBParentOfDupli2", {"/ParentOfDupli2"}}};
EXPECT_EQ(expected_transforms, iterator->transform_writers);
- created_writers expected_data = {
+ used_writers expected_data = {
{"OBCamera", {"/Camera/Camera"}},
{"OBGEO_Ear_L",
{"/Dupli1/GEO_Head-0/GEO_Ear_L-1/Ear",
@@ -204,4 +204,124 @@ TEST_F(USDHierarchyIteratorTest, ExportHierarchyTest)
// The scene has no hair or particle systems.
EXPECT_EQ(0, iterator->hair_writers.size());
EXPECT_EQ(0, iterator->particle_writers.size());
+
+ // On the second iteration, everything should be written as well.
+ // This tests the default value of iterator->export_subset_.
+ iterator->transform_writers.clear();
+ iterator->data_writers.clear();
+ iterator->iterate_and_write();
+ EXPECT_EQ(expected_transforms, iterator->transform_writers);
+ EXPECT_EQ(expected_data, iterator->data_writers);
+}
+
+TEST_F(USDHierarchyIteratorTest, ExportSubsetTest)
+{
+ // The scene has no hair or particle systems, and this is already covered by ExportHierarchyTest,
+ // so not included here. Update this test when hair & particle systems are included.
+
+ /* Load the test blend file. */
+ if (!blendfile_load("usd/usd_hierarchy_export_test.blend")) {
+ return;
+ }
+ depsgraph_create(DAG_EVAL_RENDER);
+ iterator_create();
+
+ // Mapping from object name to set of export paths.
+ used_writers expected_transforms = {
+ {"OBCamera", {"/Camera"}},
+ {"OBDupli1", {"/Dupli1"}},
+ {"OBDupli2", {"/ParentOfDupli2/Dupli2"}},
+ {"OBGEO_Ear_L",
+ {"/Dupli1/GEO_Head-0/GEO_Ear_L-1",
+ "/Ground plane/OutsideDupliGrandParent/OutsideDupliParent/GEO_Head/GEO_Ear_L",
+ "/ParentOfDupli2/Dupli2/GEO_Head-0/GEO_Ear_L-1"}},
+ {"OBGEO_Ear_R",
+ {"/Dupli1/GEO_Head-0/GEO_Ear_R-2",
+ "/Ground plane/OutsideDupliGrandParent/OutsideDupliParent/GEO_Head/GEO_Ear_R",
+ "/ParentOfDupli2/Dupli2/GEO_Head-0/GEO_Ear_R-2"}},
+ {"OBGEO_Head",
+ {"/Dupli1/GEO_Head-0",
+ "/Ground plane/OutsideDupliGrandParent/OutsideDupliParent/GEO_Head",
+ "/ParentOfDupli2/Dupli2/GEO_Head-0"}},
+ {"OBGEO_Nose",
+ {"/Dupli1/GEO_Head-0/GEO_Nose-3",
+ "/Ground plane/OutsideDupliGrandParent/OutsideDupliParent/GEO_Head/GEO_Nose",
+ "/ParentOfDupli2/Dupli2/GEO_Head-0/GEO_Nose-3"}},
+ {"OBGround plane", {"/Ground plane"}},
+ {"OBOutsideDupliGrandParent", {"/Ground plane/OutsideDupliGrandParent"}},
+ {"OBOutsideDupliParent", {"/Ground plane/OutsideDupliGrandParent/OutsideDupliParent"}},
+ {"OBParentOfDupli2", {"/ParentOfDupli2"}}};
+
+ used_writers expected_data = {
+ {"OBCamera", {"/Camera/Camera"}},
+ {"OBGEO_Ear_L",
+ {"/Dupli1/GEO_Head-0/GEO_Ear_L-1/Ear",
+ "/Ground plane/OutsideDupliGrandParent/OutsideDupliParent/GEO_Head/GEO_Ear_L/Ear",
+ "/ParentOfDupli2/Dupli2/GEO_Head-0/GEO_Ear_L-1/Ear"}},
+ {"OBGEO_Ear_R",
+ {"/Dupli1/GEO_Head-0/GEO_Ear_R-2/Ear",
+ "/Ground plane/OutsideDupliGrandParent/OutsideDupliParent/GEO_Head/GEO_Ear_R/Ear",
+ "/ParentOfDupli2/Dupli2/GEO_Head-0/GEO_Ear_R-2/Ear"}},
+ {"OBGEO_Head",
+ {"/Dupli1/GEO_Head-0/Face",
+ "/Ground plane/OutsideDupliGrandParent/OutsideDupliParent/GEO_Head/Face",
+ "/ParentOfDupli2/Dupli2/GEO_Head-0/Face"}},
+ {"OBGEO_Nose",
+ {"/Dupli1/GEO_Head-0/GEO_Nose-3/Nose",
+ "/Ground plane/OutsideDupliGrandParent/OutsideDupliParent/GEO_Head/GEO_Nose/Nose",
+ "/ParentOfDupli2/Dupli2/GEO_Head-0/GEO_Nose-3/Nose"}},
+ {"OBGround plane", {"/Ground plane/Plane"}},
+ {"OBParentOfDupli2", {"/ParentOfDupli2/Icosphere"}},
+ };
+
+ // Even when only asking an export of transforms, on the first frame everything should be
+ // exported.
+ {
+ ExportSubset export_subset = {0};
+ export_subset.transforms = true;
+ export_subset.shapes = false;
+ iterator->set_export_subset(export_subset);
+ }
+ iterator->iterate_and_write();
+ EXPECT_EQ(expected_transforms, iterator->transform_writers);
+ EXPECT_EQ(expected_data, iterator->data_writers);
+
+ // Clear data to prepare for the next iteration.
+ iterator->transform_writers.clear();
+ iterator->data_writers.clear();
+
+ // Second iteration, should only write transforms now.
+ iterator->iterate_and_write();
+ EXPECT_EQ(expected_transforms, iterator->transform_writers);
+ EXPECT_EQ(0, iterator->data_writers.size());
+
+ // Clear data to prepare for the next iteration.
+ iterator->transform_writers.clear();
+ iterator->data_writers.clear();
+
+ // Third iteration, should only write data now.
+ {
+ ExportSubset export_subset = {0};
+ export_subset.transforms = false;
+ export_subset.shapes = true;
+ iterator->set_export_subset(export_subset);
+ }
+ iterator->iterate_and_write();
+ EXPECT_EQ(0, iterator->transform_writers.size());
+ EXPECT_EQ(expected_data, iterator->data_writers);
+
+ // Clear data to prepare for the next iteration.
+ iterator->transform_writers.clear();
+ iterator->data_writers.clear();
+
+ // Fourth iteration, should export everything now.
+ {
+ ExportSubset export_subset = {0};
+ export_subset.transforms = true;
+ export_subset.shapes = true;
+ iterator->set_export_subset(export_subset);
+ }
+ iterator->iterate_and_write();
+ EXPECT_EQ(expected_transforms, iterator->transform_writers);
+ EXPECT_EQ(expected_data, iterator->data_writers);
}
diff --git a/tests/gtests/usd/hierarchy_context_order_test.cc b/tests/gtests/usd/hierarchy_context_order_test.cc
index 4111fc7511e..25cda6d8670 100644
--- a/tests/gtests/usd/hierarchy_context_order_test.cc
+++ b/tests/gtests/usd/hierarchy_context_order_test.cc
@@ -16,7 +16,7 @@
* The Original Code is Copyright (C) 2019 Blender Foundation.
* All rights reserved.
*/
-#include "intern/abstract_hierarchy_iterator.h"
+#include "IO_abstract_hierarchy_iterator.h"
#include "testing/testing.h"
@@ -24,7 +24,7 @@ extern "C" {
#include "BLI_utildefines.h"
}
-using namespace USD;
+using namespace blender::io;
class HierarchyContextOrderTest : public testing::Test {
};