Skip to content

Instantly share code, notes, and snippets.

@withs
Last active November 20, 2021 20:32
Show Gist options
  • Save withs/70d5411485b90e56e8a2e12faf3328da to your computer and use it in GitHub Desktop.
Save withs/70d5411485b90e56e8a2e12faf3328da to your computer and use it in GitHub Desktop.
poc of a simple implementation of python list Enumerate in c++ (c++ vector enumerate)
#include "vector"
#include "cstdint"
// poc of a simple implementation of python list Enumerate in c++
// I choosed to use struct over std::tuple like in (python) because of the way to get the data, i prefer use name over numbers:
// elem.pos > std::get<0>(elem)
template<class T>
class Enumerate {
private:
struct _enum {
private:
Enumerate<T>& _parent;
public:
uint32_t pos;
T& elem;
_enum(uint32_t atPos, T& withElem, Enumerate<T>& andParent) noexcept
: pos(atPos),
elem(withElem),
_parent(andParent) { }
void erase() noexcept {
_parent._safeDeleteQueue.push_back(pos);
}
};
std::vector<_enum> _vec { };
std::vector<uint32_t> _safeDeleteQueue { };
std::vector<T>& _oVec;
public:
Enumerate(std::vector<T>& vec) noexcept : _oVec(vec) {
uint32_t count = 0;
for ( auto& elem: vec ) {
this->_vec.push_back(_enum{ count, elem, *this });
count++;
}
}
~Enumerate() noexcept {
uint32_t count = 0;
for ( auto& toDelPos: this->_safeDeleteQueue ) {
this->_oVec.erase(this->_oVec.begin() + (toDelPos - count));
count++;
}
}
typename std::vector<_enum>::iterator begin() noexcept {
return this->_vec.begin();
}
typename std::vector<_enum>::iterator end() noexcept {
return this->_vec.end();
}
};
int32_t main() {
std::vector<std::string> abc = { "hello", "nuit", "pomme", "maison" };
for ( auto& elem: Enumerate<std::string>(abc) ) {
std::cout << elem.pos << " - " << elem.elem << "\n";
// Use elem.erase() instead af deleting directly from the vector
// because it will re-arrange the items and all elem.pos after the deletion will be incorrect
// use elem.erase() wich will store the item to delete and delete it at the deconstruction of the Enumerate object
if ( elem.pos == 0 )
elem.erase();
// elem.elem is a direct reference to the elem in the given vector that mean
// you can change value directly from elem.elem
if ( elem.pos == 1 )
elem.elem = "bonjour";
}
/* Output:
0 - hello
1 - nuit
2 - pomme
3 - maison
*/
for ( auto elem: Enumerate<std::string>(abc) ) {
std::cout << elem.pos << " - " << elem.elem << "\n";
}
/* Output:
0 - bonjour
1 - pomme
2 - maison
*/
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment