BLI: extract MapItem type to simplify iterating over map items

This commit is contained in:
Jacques Lucke 2023-04-25 12:14:43 +02:00
parent 5fde2b34ba
commit a57584e40d
12 changed files with 44 additions and 37 deletions

View File

@ -329,7 +329,7 @@ void BKE_cryptomatte_store_metadata(const struct CryptomatteSession *session,
RenderResult *render_result,
const ViewLayer *view_layer)
{
for (const blender::Map<std::string, blender::bke::cryptomatte::CryptomatteLayer>::Item item :
for (const blender::MapItem<std::string, blender::bke::cryptomatte::CryptomatteLayer> item :
session->layers.items()) {
const blender::StringRefNull layer_name(item.key);
const blender::bke::cryptomatte::CryptomatteLayer &layer = item.value;
@ -457,7 +457,7 @@ static std::string to_manifest(const CryptomatteLayer *layer)
bool is_first = true;
const blender::Map<std::string, CryptomatteHash> &const_map = layer->hashes;
manifest << "{";
for (blender::Map<std::string, CryptomatteHash>::Item item : const_map.items()) {
for (blender::MapItem<std::string, CryptomatteHash> item : const_map.items()) {
if (is_first) {
is_first = false;
}
@ -544,7 +544,7 @@ void CryptomatteLayer::add_hash(blender::StringRef name, CryptomatteHash cryptom
std::optional<std::string> CryptomatteLayer::operator[](float encoded_hash) const
{
const blender::Map<std::string, CryptomatteHash> &const_map = hashes;
for (blender::Map<std::string, CryptomatteHash>::Item item : const_map.items()) {
for (blender::MapItem<std::string, CryptomatteHash> item : const_map.items()) {
if (BKE_cryptomatte_hash_to_float(item.value.hash) == encoded_hash) {
return std::make_optional(item.key);
}

View File

@ -63,6 +63,28 @@
namespace blender {
/**
* A key-value-pair stored in a #Map. This is used when looping over Map.items().
*/
template<typename Key, typename Value> struct MapItem {
const Key &key;
const Value &value;
};
/**
* Same as #MapItem, but the value is mutable. The key is still const because changing it might
* change its hash value which would lead to undefined behavior in the #Map.
*/
template<typename Key, typename Value> struct MutableMapItem {
const Key &key;
Value &value;
operator MapItem<Key, Value>() const
{
return {this->key, this->value};
}
};
template<
/**
* Type of the keys stored in the map. Keys have to be movable. Furthermore, the hash and
@ -108,6 +130,8 @@ template<
class Map {
public:
using size_type = int64_t;
using Item = MapItem<Key, Value>;
using MutableItem = MutableMapItem<Key, Value>;
private:
/**
@ -771,21 +795,6 @@ class Map {
}
};
struct Item {
const Key &key;
const Value &value;
};
struct MutableItem {
const Key &key;
Value &value;
operator Item() const
{
return Item{key, value};
}
};
class ItemIterator final : public BaseIteratorRange<ItemIterator> {
public:
using value_type = Item;
@ -850,9 +859,8 @@ class Map {
}
/**
* Returns an iterator over all key-value-pairs in the map. The key-value-pairs are stored in
* a temporary struct with a .key and a .value field.The iterator is invalidated, when the map is
* changed.
* Returns an iterator over all key-value-pairs in the map. The key-value-pairs are stored in a
* #MapItem. The iterator is invalidated, when the map is changed.
*/
ItemIterator items() const
{
@ -860,9 +868,8 @@ class Map {
}
/**
* Returns an iterator over all key-value-pairs in the map. The key-value-pairs are stored in
* a temporary struct with a .key and a .value field. The iterator is invalidated, when the map
* is changed.
* Returns an iterator over all key-value-pairs in the map. The key-value-pairs are stored in a
* #MutableMapItem. The iterator is invalidated, when the map is changed.
*
* This iterator also allows you to modify the value (but not the key).
*/

View File

@ -240,7 +240,7 @@ TEST(map, MutableItemToItemConversion)
map.add(2, 1);
Vector<int> keys, values;
for (Map<int, int>::Item item : map.items()) {
for (MapItem<int, int> item : map.items()) {
keys.append(item.key);
values.append(item.value);
}
@ -628,7 +628,7 @@ TEST(map, RemoveDuringIteration)
Iter begin = map.items().begin();
Iter end = map.items().end();
for (Iter iter = begin; iter != end; ++iter) {
Map<int, int>::MutableItem item = *iter;
MutableMapItem<int, int> item = *iter;
if (item.value == 2) {
map.remove(iter);
}

View File

@ -45,7 +45,7 @@ void MetaData::replace_hash_neutral_cryptomatte_keys(const blender::StringRef la
void MetaData::add_to_render_result(RenderResult *render_result) const
{
for (Map<std::string, std::string>::Item entry : entries_.items()) {
for (MapItem<std::string, std::string> entry : entries_.items()) {
BKE_render_result_stamp_data(render_result, entry.key.c_str(), entry.value.c_str());
}
}

View File

@ -51,7 +51,7 @@ void NodeOperationBuilder::convert_to_operations(ExecutionSystem *system)
* so multiple operations can use the same node input.
*/
blender::MultiValueMap<NodeInput *, NodeOperationInput *> inverse_input_map;
for (Map<NodeOperationInput *, NodeInput *>::MutableItem item : input_map_.items()) {
for (MutableMapItem<NodeOperationInput *, NodeInput *> item : input_map_.items()) {
inverse_input_map.add(item.value, item.key);
}

View File

@ -263,7 +263,7 @@ void VelocityModule::end_sync()
uint32_t max_resource_id_ = 1u;
for (Map<ObjectKey, VelocityObjectData>::Item item : velocity_map.items()) {
for (MapItem<ObjectKey, VelocityObjectData> item : velocity_map.items()) {
if (item.value.obj.resource_id == uint32_t(-1)) {
deleted_obj.append(item.key);
}

View File

@ -336,7 +336,7 @@ struct MTLContextTextureUtils {
template<typename T> void free_cached_pso_map(blender::Map<T, id<MTLComputePipelineState>> &map)
{
for (typename blender::Map<T, id<MTLComputePipelineState>>::MutableItem item : map.items()) {
for (typename blender::MutableMapItem<T, id<MTLComputePipelineState>> item : map.items()) {
[item.value release];
}
map.clear();

View File

@ -44,7 +44,7 @@ static void copy_attributes(const Map<AttributeIDRef, AttributeKind> &attributes
bke::MutableAttributeAccessor dst_attributes,
const Span<eAttrDomain> domains)
{
for (Map<AttributeIDRef, AttributeKind>::Item entry : attributes.items()) {
for (MapItem<AttributeIDRef, AttributeKind> entry : attributes.items()) {
const AttributeIDRef attribute_id = entry.key;
GAttributeReader attribute = src_attributes.lookup(attribute_id);
if (!attribute) {
@ -75,7 +75,7 @@ static void copy_attributes_based_on_mask(const Map<AttributeIDRef, AttributeKin
const eAttrDomain domain,
const IndexMask mask)
{
for (Map<AttributeIDRef, AttributeKind>::Item entry : attributes.items()) {
for (MapItem<AttributeIDRef, AttributeKind> entry : attributes.items()) {
const AttributeIDRef attribute_id = entry.key;
GAttributeReader attribute = src_attributes.lookup(attribute_id);
if (!attribute) {
@ -104,7 +104,7 @@ static void copy_attributes_based_on_map(const Map<AttributeIDRef, AttributeKind
const eAttrDomain domain,
const Span<int> index_map)
{
for (Map<AttributeIDRef, AttributeKind>::Item entry : attributes.items()) {
for (MapItem<AttributeIDRef, AttributeKind> entry : attributes.items()) {
const AttributeIDRef attribute_id = entry.key;
GAttributeReader attribute = src_attributes.lookup(attribute_id);
if (!attribute) {

View File

@ -294,7 +294,7 @@ BLI_NOINLINE static void propagate_existing_attributes(
const AttributeAccessor mesh_attributes = mesh.attributes();
MutableAttributeAccessor point_attributes = points.attributes_for_write();
for (Map<AttributeIDRef, AttributeKind>::Item entry : attributes.items()) {
for (MapItem<AttributeIDRef, AttributeKind> entry : attributes.items()) {
const AttributeIDRef attribute_id = entry.key;
const eCustomDataType output_data_type = entry.value.data_type;

View File

@ -84,7 +84,7 @@ static void join_attributes(Span<const GeometryComponent *> src_components,
const Map<AttributeIDRef, AttributeMetaData> info = get_final_attribute_info(src_components,
ignored_attributes);
for (const Map<AttributeIDRef, AttributeMetaData>::Item item : info.items()) {
for (const MapItem<AttributeIDRef, AttributeMetaData> item : info.items()) {
const AttributeIDRef attribute_id = item.key;
const AttributeMetaData &meta_data = item.value;

View File

@ -112,7 +112,7 @@ static void geometry_set_mesh_to_points(GeometrySet &geometry_set,
attributes.remove("radius");
attributes.remove("position");
for (Map<AttributeIDRef, AttributeKind>::Item entry : attributes.items()) {
for (MapItem<AttributeIDRef, AttributeKind> entry : attributes.items()) {
const AttributeIDRef attribute_id = entry.key;
const eCustomDataType data_type = entry.value.data_type;
const bke::GAttributeReader src = src_attributes.lookup(attribute_id, domain, data_type);

View File

@ -63,7 +63,7 @@ static void geometry_set_points_to_vertices(
const AttributeAccessor src_attributes = points->attributes();
MutableAttributeAccessor dst_attributes = mesh->attributes_for_write();
for (Map<AttributeIDRef, AttributeKind>::Item entry : attributes.items()) {
for (MapItem<AttributeIDRef, AttributeKind> entry : attributes.items()) {
const AttributeIDRef id = entry.key;
const eCustomDataType data_type = entry.value.data_type;
const GAttributeReader src = src_attributes.lookup(id);