Skip to content

Instantly share code, notes, and snippets.

@zethon
Created June 22, 2021 13:26
Show Gist options
  • Save zethon/ff1fd16f917db67bb9ee3b714af16c8e to your computer and use it in GitHub Desktop.
Save zethon/ff1fd16f917db67bb9ee3b714af16c8e to your computer and use it in GitHub Desktop.
Writing a Custom Iterator for a Container with Ephemeral Objects
#include <iostream>
#include <string>
#include <vector>
#include <memory>
class Database
{
std::vector<int> _data;
public:
void add(int data) { _data.push_back(data); }
int read(std::size_t idx) const { return _data[idx] + 2; }
std::size_t size() const { return _data.size(); }
};
class Dataview
{
std::unique_ptr<Database> _db;
public:
struct Iterator
{
friend class Dataview;
using iterator_category = std::forward_iterator_tag;
using difference_type = std::size_t;
using value_type = int;
using pointer = value_type*;
using reference = value_type&;
using const_pointer = const pointer;
using const_reference = const reference;
Iterator() noexcept = default;
Iterator(const Iterator &) noexcept = default;
~Iterator() = default;
Iterator& operator++()
{
_idx++;
return *this;
}
Iterator operator++(int x)
{
auto temp = *this;
++(*this);
return temp;
}
const_reference operator*() const
{
_temp = _dbptr->read(_idx);
return _temp;
}
const_pointer operator->() const
{
_temp = _dbptr->read(_idx);
return &_temp;
}
bool operator!=(const Iterator& rhs) const noexcept
{
return rhs._idx != _idx;
}
private:
Iterator(const Dataview& dbptr, std::size_t idx = 0)
: _dbptr{&dbptr}, _idx {idx}
{
}
mutable value_type _temp;
const Dataview* _dbptr = nullptr;
std::size_t _idx = 0;
};
Dataview(const std::vector<int>& data)
{
_db = std::make_unique<Database>();
for (auto d : data)
{
_db->add(d);
}
}
void add(int data) { _db->add(data); }
int read(std::size_t idx) const { return _db->read(idx); }
std::size_t size() const { return _db->size(); }
Iterator begin() const noexcept
{
return Iterator{*this};
}
Iterator end() const noexcept
{
return Iterator{*this, _db->size()};
}
};
int main()
{
Dataview dv{{1,2,3,4,5}};
for (auto idx = 0u; idx < dv.size(); ++idx)
{
std::cout << idx << " : " << dv.read(idx) << '\n';
}
std::cout << "begin\n";
for (const auto& x : dv)
{
std::cout << "-> " << x << '\n';
}
std::cout << "end\n";
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment