blob: 910b0ce3acd944f91f8b5ef8b8beb33d7e105eb5 [file] [log] [blame]
#ifndef RR_GRAPH_OBJ_UTILS_H
#define RR_GRAPH_OBJ_UTILS_H
/* Include header files which include data structures used by
* the function declaration
*/
#include <vector>
#include "vtr_vector_map.h"
/*
*
* Templated utility functions for cleaning and reordering IdMaps
*
*/
//Returns true if all elements are contiguously ascending values (i.e. equal to their index)
template<typename Container>
bool are_contiguous(const Container& values) {
using T = typename Container::value_type;
size_t i = 0;
for (T val : values) {
if (val != T(i)) {
return false;
}
++i;
}
return true;
}
//Returns true if all elements in the vector 'values' evaluate true
template<typename Container>
bool all_valid(const Container& values) {
for (auto val : values) {
if (!val) {
return false;
}
}
return true;
}
//Builds a mapping from old to new ids by skipping values marked invalid
template<typename Container>
Container compress_ids(const Container& ids) {
using Id = typename Container::value_type;
Container id_map(ids.size());
size_t i = 0;
for (auto id : ids) {
if (id) {
//Valid
id_map[id] = Id(i);
++i;
}
}
return id_map;
}
//Returns a vector based on 'values', which has had entries dropped & re-ordered according according to 'id_map'.
//Each entry in id_map corresponds to the assoicated element in 'values'.
//The value of the id_map entry is the new ID of the entry in values.
//
//If it is an invalid ID, the element in values is dropped.
//Otherwise the element is moved to the new ID location.
template<typename ValueContainer, typename IdContainer>
ValueContainer clean_and_reorder_values(const ValueContainer& values, const IdContainer& id_map) {
using Id = typename IdContainer::value_type;
VTR_ASSERT(values.size() == id_map.size());
//Allocate space for the values that will not be dropped
ValueContainer result(values.size());
//Move over the valid entries to their new locations
size_t new_count = 0;
for (size_t cur_idx = 0; cur_idx < values.size(); ++cur_idx) {
Id old_id = Id(cur_idx);
Id new_id = id_map[old_id];
if (new_id) {
//There is a valid mapping
result[new_id] = std::move(values[old_id]);
++new_count;
}
}
result.resize(new_count);
return result;
}
//Returns the set of new valid Ids defined by 'id_map'
//TODO: merge with clean_and_reorder_values
template<typename Container>
Container clean_and_reorder_ids(const Container& id_map) {
//For IDs, the values are the new id's stored in the map
using Id = typename Container::value_type;
//Allocate a new vector to store the values that have been not dropped
Container result(id_map.size());
//Move over the valid entries to their new locations
size_t new_count = 0;
for (size_t cur_idx = 0; cur_idx < id_map.size(); ++cur_idx) {
Id old_id = Id(cur_idx);
Id new_id = id_map[old_id];
if (new_id) {
result[new_id] = new_id;
++new_count;
}
}
result.resize(new_count);
return result;
}
//Count how many of the Id's referenced in 'range' have a valid
//new mapping in 'id_map'
template<typename R, typename Id>
size_t count_valid_refs(R range, const vtr::vector_map<Id, Id>& id_map) {
size_t valid_count = 0;
for (Id old_id : range) {
if (id_map[old_id]) {
++valid_count;
}
}
return valid_count;
}
//Updates the Ids in 'values' based on id_map, even if the original or new mapping is not valid
template<typename Container, typename ValId>
Container update_all_refs(const Container& values, const vtr::vector_map<ValId, ValId>& id_map) {
Container updated;
for (ValId orig_val : values) {
//The original item was valid
ValId new_val = id_map[orig_val];
//The original item exists in the new mapping
updated.emplace_back(new_val);
}
return updated;
}
template<typename ValueContainer, typename IdContainer>
ValueContainer update_valid_refs(const ValueContainer& values, const IdContainer& id_map) {
ValueContainer updated;
for (auto orig_val : values) {
if (orig_val) {
//Original item valid
auto new_val = id_map[orig_val];
if (new_val) {
//The original item exists in the new mapping
updated.emplace_back(new_val);
}
}
}
return updated;
}
#endif