Skip to content

Instantly share code, notes, and snippets.

@Bigfoot71
Created November 17, 2024 01:11
Show Gist options
  • Select an option

  • Save Bigfoot71/ce9b9a9d99d9c772212f5e72dbac812e to your computer and use it in GitHub Desktop.

Select an option

Save Bigfoot71/ce9b9a9d99d9c772212f5e72dbac812e to your computer and use it in GitHub Desktop.
A template class that generates unique IDs and recycles removed ones for reuse.
// This code is distributed under the Unlicense license.
// For more details, please visit https://unlicense.org/
#ifndef IDMAN_HPP
#define IDMAN_HPP
#include <type_traits>
#include <set>
/**
* @brief A class to manage and generate unique IDs.
*
* This class generates unique identifiers (IDs) and allows for the removal and reuse of IDs.
* When an ID is removed, it is recycled and can be reused later, maintaining the uniqueness
* of the IDs in the system. The IDs are generated sequentially, starting from a given value.
* If an ID is recycled, the smallest available ID will be reused first.
*
* @tparam T_ID The type of the identifier. It must be an integral type.
*/
template<typename T_ID>
class IDMan
{
static_assert(std::is_integral<T_ID>::value, "T_ID must be an integral type");
public:
/**
* @brief Constructs the ID manager with a starting ID.
*
* Initializes the ID manager, setting the first ID to the provided value (or 0 if not provided).
*
* @param start The starting ID. Defaults to 0.
*/
explicit IDMan(T_ID start = 0)
: m_next_id(start)
{ }
/**
* @brief Generates a new unique ID.
*
* If there are recycled IDs, the smallest available ID is returned.
* Otherwise, a new ID is generated by incrementing the current `m_next_id`.
*
* @return The generated unique ID.
*/
T_ID generate() {
if (!m_free_ids.empty()) {
// Reuse the smallest available recycled ID
auto it = m_free_ids.begin();
T_ID id = *it;
m_free_ids.erase(it);
return id;
}
return m_next_id++;
}
/**
* @brief Removes an ID from the active pool and recycles it.
*
* The specified ID is added to the pool of recycled IDs, making it available for reuse.
*
* @param id The ID to be removed and recycled.
*/
void remove(T_ID id) {
if (id < m_next_id) {
m_free_ids.insert(id);
}
}
/**
* @brief Checks if an ID exists in the active pool.
*
* Checks if the specified ID is currently in use (i.e., it exists and has not been recycled).
*
* @param id The ID to check for existence.
* @return `true` if the ID exists, `false` otherwise.
*/
bool exist(T_ID id) const {
return id < m_next_id && m_free_ids.find(id) == m_free_ids.end();
}
private:
T_ID m_next_id; ///< The next ID to be generated.
std::set<T_ID> m_free_ids; ///< The set of recycled (free) IDs.
};
#endif // IDMAN_HPP
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment