6#include <unordered_map>
8#include "testing/testing.h"
21TEST(map, DefaultConstructor)
25 EXPECT_TRUE(map.is_empty());
61TEST(map, ItemsConstructorDuplicates)
63 Map<int, int> map = {{1, 2}, {3, 4}, {1, 4}, {2, 5}, {2, 6}};
74 EXPECT_TRUE(map.is_empty());
77 EXPECT_FALSE(map.is_empty());
80 EXPECT_FALSE(map.is_empty());
86 EXPECT_FALSE(map.contains(4));
88 EXPECT_FALSE(map.contains(4));
90 EXPECT_TRUE(map.contains(4));
114 for (
int i = 0; i < 100; i++) {
125 EXPECT_TRUE(map.contains(2));
126 EXPECT_TRUE(map.contains(1));
129 EXPECT_TRUE(map.contains(2));
130 EXPECT_FALSE(map.contains(1));
133 EXPECT_FALSE(map.contains(2));
134 EXPECT_FALSE(map.contains(1));
143 std::optional<int>
value = map.pop_try(4);
145 EXPECT_FALSE(
value.has_value());
146 value = map.pop_try(2);
148 EXPECT_TRUE(
value.has_value());
176 for (
int i = 0; i < 100; i++) {
179 for (
int i = 25; i < 80; i++) {
182 for (
int i = 0; i < 100; i++) {
183 EXPECT_EQ(map.contains(i), i < 25 || i >= 80);
197 for (
float value : map.values()) {
204 EXPECT_TRUE(values.
contains(-2.0f));
218 for (
int key : map.keys()) {
241 for (
auto item : const_map.
items()) {
243 values.
add(item.value);
262 for (
int &
value : map.values()) {
276 for (
auto item : map.items()) {
277 item.value += item.key;
284TEST(map, MutableItemToItemConversion)
293 values.
append(item.value);
309TEST(map, LookupOrAddCB_SeparateFunction)
318TEST(map, LookupOrAddCB_Lambdas)
321 auto lambda1 = []() {
return 11.0f; };
322 EXPECT_EQ(map.lookup_or_add_cb(0, lambda1), 11.0f);
323 auto lambda2 = []() {
return 20.0f; };
324 EXPECT_EQ(map.lookup_or_add_cb(1, lambda2), 20.0f);
326 EXPECT_EQ(map.lookup_or_add_cb(0, lambda2), 11.0f);
327 EXPECT_EQ(map.lookup_or_add_cb(1, lambda1), 20.0f);
337 auto modify_func = [](
float *
value) {
341 EXPECT_TRUE(map.add_or_modify(1,
create_func, modify_func));
343 EXPECT_FALSE(map.add_or_modify(1,
create_func, modify_func));
351 new (
value) std::unique_ptr<int>(
new int{10});
354 auto modify_func = [](std::unique_ptr<int> *
value) ->
int & {
359 int &a = map.add_or_modify(1,
create_func, modify_func);
368 EXPECT_FALSE(map.contains(3));
369 EXPECT_TRUE(map.add_overwrite(3, 6.0f));
371 EXPECT_FALSE(map.add_overwrite(3, 7.0f));
373 EXPECT_FALSE(map.add(3, 8.0f));
382 map.lookup_or_add_default(5) = 2;
384 map.lookup_or_add_default(3) += 4;
393 map.lookup_or_add(6, 4) += 10;
404 EXPECT_EQ(map.lookup_try(3), std::nullopt);
423 for (
int i = 0; i < 100; i++) {
440 map2 = std::move(map1);
469 EXPECT_TRUE(map.contains(1));
470 EXPECT_TRUE(map.contains(2));
475 EXPECT_FALSE(map.contains(1));
476 EXPECT_FALSE(map.contains(2));
481 auto value1 = std::make_unique<int>();
482 auto value2 = std::make_unique<int>();
483 auto value3 = std::make_unique<int>();
485 int *value1_ptr = value1.get();
488 map.
add_new(1, std::move(value1));
489 map.add(2, std::move(value2));
490 map.add_overwrite(3, std::move(value3));
491 map.lookup_or_add_cb(4, []() {
return std::make_unique<int>(); });
492 map.add_new(5, std::make_unique<int>());
493 map.add(6, std::make_unique<int>());
494 map.add_overwrite(7, std::make_unique<int>());
495 map.lookup_or_add(8, std::make_unique<int>());
496 map.pop_default(9, std::make_unique<int>());
498 EXPECT_EQ(map.lookup(1).get(), value1_ptr);
507 EXPECT_FALSE(map.remove(3));
509 EXPECT_TRUE(map.remove(2));
518 EXPECT_TRUE(map.add(&a, 5));
519 EXPECT_FALSE(map.add(&a, 4));
523 EXPECT_TRUE(map.remove(&
b));
524 EXPECT_TRUE(map.add(&
b, 8));
525 EXPECT_FALSE(map.remove(&d));
526 EXPECT_TRUE(map.remove(&a));
527 EXPECT_TRUE(map.remove(&
b));
528 EXPECT_TRUE(map.remove(&c));
529 EXPECT_TRUE(map.is_empty());
536 map.add(
"45",
"643");
537 EXPECT_TRUE(map.contains(
"45"));
538 EXPECT_FALSE(map.contains(
"54"));
549 map.foreach_item([&](
int key,
int value) {
560TEST(map, CopyConstructorExceptions)
566 map.lookup(2).throw_during_copy =
true;
567 EXPECT_ANY_THROW({ MapType map_copy(map); });
570TEST(map, MoveConstructorExceptions)
576 map.lookup(1).throw_during_move =
true;
577 EXPECT_ANY_THROW({ MapType map_moved(std::move(map)); });
587 EXPECT_ANY_THROW({ map.add_new(key1, value1); });
592 EXPECT_ANY_THROW({ map.add_new(key2, value2); });
601 map.lookup(2).throw_during_move =
true;
602 EXPECT_ANY_THROW({ map.reserve(100); });
611 map.lookup(3).throw_during_move =
true;
612 EXPECT_ANY_THROW({ map.pop(3); });
618TEST(map, AddOrModifyExceptions)
623 EXPECT_ANY_THROW({ map.add_or_modify(3, create_fn, modify_fn); });
638 map.
add(TestEnum::A, 4);
639 map.add(TestEnum::B, 6);
643 EXPECT_FALSE(map.contains(TestEnum::C));
644 map.lookup(TestEnum::D) = 10;
656 EXPECT_TRUE(std::any_of(map.keys().begin(), map.keys().end(), [](
int v) { return v == 1; }));
657 EXPECT_TRUE(std::any_of(map.values().begin(), map.values().end(), [](
int v) { return v == 1; }));
658 EXPECT_TRUE(std::any_of(
659 map.items().begin(), map.items().end(), [](
auto item) { return item.value == 1; }));
660 EXPECT_EQ(std::count(map.values().begin(), map.values().end(), 2), 2);
661 EXPECT_EQ(std::count(map.values().begin(), map.values().end(), 4), 1);
662 EXPECT_EQ(std::count(map.keys().begin(), map.keys().end(), 7), 1);
668 map.
add_as(3,
"hello", 2);
669 map.add_as(2,
"test", 1);
674TEST(map, RemoveDuringIteration)
687 Iter end = map.items().
end();
688 for (Iter iter =
begin; iter != end; ++iter) {
690 if (item.
value == 2) {
707 const int64_t removed = map.remove_if([](
auto item) {
return item.key > 100; });
714 EXPECT_FALSE(map.contains(i * i));
727 EXPECT_EQ(map.lookup_key_ptr_as(
"d"),
nullptr);
728 EXPECT_EQ(map.lookup_key_ptr_as(
"b")->size(), 1);
729 EXPECT_EQ(map.lookup_key_ptr(
"a"), map.lookup_key_ptr_as(
"a"));
735 map.
add({1, 2, 3}, 100);
736 map.add({3, 2, 1}, 200);
741 EXPECT_FALSE(map.contains({1, 2}));
743 std::array<int, 3>
array = {1, 2, 3};
746 map.remove_as(
Vector<int>({1, 2, 3}).as_mutable_span());
769 std::string
value =
"a";
770 bool value_checked =
false;
771 map.lookup_or_add_cb(std::move(
value), [&]() {
773 value_checked =
true;
776 EXPECT_TRUE(value_checked);
784template<
typename MapT>
789 for (
int i = 0; i < amount; i++) {
797 for (
int value : values) {
804 for (
int value : values) {
810 for (
int value : values) {
816 std::cout <<
"Count: " <<
count <<
"\n";
823template<
typename Key,
typename Value>
class StdUnorderedMapWrapper {
825 using MapType = std::unordered_map<Key, Value, blender::DefaultHash<Key>>;
834 bool is_empty()
const
844 template<
typename ForwardKey,
typename... ForwardValue>
845 void add_new(ForwardKey &&
key, ForwardValue &&...
value)
847 map_.insert({std::forward<ForwardKey>(
key),
Value(std::forward<ForwardValue>(
value)...)});
850 template<
typename ForwardKey,
typename... ForwardValue>
851 bool add(ForwardKey &&
key, ForwardValue &&...
value)
854 .insert({std::forward<ForwardKey>(
key),
Value(std::forward<ForwardValue>(
value)...)})
858 bool contains(
const Key &
key)
const
860 return map_.find(
key) != map_.end();
863 bool remove(
const Key &
key)
865 return bool(map_.erase(
key));
870 return map_.find(
key)->second;
875 return map_.find(
key)->second;
883 void print_stats(StringRef =
"")
const {}
888 for (
int i = 0; i < 3; i++) {
889 benchmark_random_ints<blender::Map<int, int>>(
"blender::Map ", 1000000, 1);
890 benchmark_random_ints<blender::StdUnorderedMapWrapper<int, int>>(
891 "std::unordered_map", 1000000, 1);
894 for (
int i = 0; i < 3; i++) {
896 benchmark_random_ints<blender::Map<int, int>>(
"blender::Map ", 1000000, factor);
897 benchmark_random_ints<blender::StdUnorderedMapWrapper<int, int>>(
898 "std::unordered_map", 1000000, factor);
EXPECT_EQ(BLI_expr_pylike_eval(expr, nullptr, 0, &result), EXPR_PYLIKE_INVALID)
void int BLI_rng_get_int(struct RNG *rng) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
struct RNG * BLI_rng_new(unsigned int seed)
void BLI_rng_free(struct RNG *rng) ATTR_NONNULL(1)
#define SCOPED_TIMER(name)
ATTR_WARN_UNUSED_RESULT const BMVert * v
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
SubIterator begin() const
const Value * lookup_ptr(const Key &key) const
Value & lookup_or_add_default(const Key &key)
bool add(const Key &key, const Value &value)
const Value & lookup(const Key &key) const
bool add_as(ForwardKey &&key, ForwardValue &&...value)
void add_new(const Key &key, const Value &value)
ItemIterator items() const &
bool contains(const Key &key) const
bool contains(const T &value) const
void append(const T &value)
int64_t first_index_of(const T &value) const
static void clear(Message &msg)
static void add(blender::Map< std::string, std::string > &messages, Message &msg)
GAttributeReader lookup(const void *owner, const StringRef name)
static PyObject * create_func(PyObject *, PyObject *args)