Created
November 17, 2024 01:11
-
-
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 file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // 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