Created
September 19, 2024 17:32
-
-
Save TymianekPL/e258025c45938fa8fe63bfb4d7849476 to your computer and use it in GitHub Desktop.
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
#ifndef LOOKUPVECTOR_H | |
#define LOOKUPVECTOR_H | |
#include <memory> | |
#include <vector> | |
namespace Utilities | |
{ | |
template<typename T, typename = void> | |
struct auto_const_reference | |
{ | |
using type = T; | |
}; | |
template<typename T> | |
struct auto_const_reference <T, std::enable_if_t <(sizeof(T) > 16 || !std::is_trivially_copyable_v <T>)> > | |
{ | |
using type = std::add_lvalue_reference_t <std::add_const_t <T> >; | |
}; | |
template<typename T> | |
using auto_const_reference_t = typename auto_const_reference <T>::type; | |
template<typename T, typename TLook> | |
concept is_lookable = requires(T&& v) { { v->getIdentifier() } -> std::same_as <TLook>; }; | |
template<typename T, typename TKey> | |
requires is_lookable <T, TKey> && std::is_copy_assignable_v <T> | |
class lookup_vector final | |
{ | |
public: | |
lookup_vector(void) = default; | |
lookup_vector(std::initializer_list <T> list) : _value(std::move(list)) {} | |
lookup_vector(const lookup_vector& other) : _value(other._value) {} | |
lookup_vector(lookup_vector&& other) noexcept = default; | |
lookup_vector& operator=(const lookup_vector& other) | |
{ | |
if (this != &other) | |
_value = other._value; | |
return *this; | |
} | |
lookup_vector& operator=(lookup_vector&& other) noexcept = default; | |
~lookup_vector(void) = default; | |
std::optional <T> get(auto_const_reference_t <TKey> key) const noexcept(std::declval <T>().getIdentifier()) | |
{ | |
for (auto& value : this->_value) | |
if (value->getIdentifier() == key) return value; | |
return std::nullopt; | |
} | |
std::vector <T>& vector(void) noexcept { return this->_value; } | |
template<typename TS> | |
requires std::convertible_to <TS, T> | |
void push(TS&& value) { _value.push_back(std::forward <TS>(value)); } | |
bool remove(auto_const_reference_t <TKey> key) noexcept | |
{ | |
auto it = std::remove_if(this->_value.begin(), this->_value.end(), | |
[&key](const T& value) { return value->getIdentifier() == key; }); | |
if (it != this->_value.end()) | |
{ | |
this->_value.erase(it, this->_value.end()); | |
return true; | |
} | |
return false; | |
} | |
std::optional <std::size_t> findIndex(auto_const_reference_t <TKey> key) const noexcept | |
{ | |
for (std::size_t i = 0; i < this->_value.size(); ++i) | |
if (this->_value[i]->getIdentifier() == key) | |
return i; | |
return std::nullopt; | |
} | |
T& operator[](auto_const_reference_t <TKey> key) | |
{ | |
static_assert(std::is_constructible_v <T, TKey>); | |
for (auto& value : this->_value) | |
if (value->getIdentifier() == key) return value; | |
return _value.push_back(std::forward <T>({})); | |
} | |
const T& operator[](auto_const_reference_t <TKey> key) const | |
{ | |
static_assert(std::is_constructible_v <T, TKey>); | |
for (auto& value : this->_value) | |
if (value->getIdentifier() == key) return value; | |
return _value.push_back(std::forward <T>({})); | |
} | |
private: | |
std::vector <T> _value; | |
}; | |
} // Utilities | |
#endif //LOOKUPVECTOR_H |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment