154 lines
4.3 KiB
C++
154 lines
4.3 KiB
C++
// commenting everything out when I commit so all commits my code technically
|
|
// compiles
|
|
#include <algorithm>
|
|
#include <initializer_list>
|
|
#include <iterator>
|
|
#include <optional>
|
|
#include <stdexcept>
|
|
#include <utility>
|
|
#include <vector>
|
|
namespace cs440 {
|
|
|
|
template <typename Key_T, typename Mapped_T> class Map {
|
|
private:
|
|
using ValueType = std::pair<const Key_T, Mapped_T>;
|
|
// idx 0 = root
|
|
// left = parent * 2 + 1
|
|
// right = parent * 2 + 2
|
|
std::vector<std::optional<ValueType>> store;
|
|
|
|
public:
|
|
// TODO: Iterator functionality
|
|
class Iterator {
|
|
public:
|
|
using underlying = typename std::vector<std::optional<ValueType>>::iterator;
|
|
|
|
private:
|
|
underlying store_iter;
|
|
|
|
public:
|
|
Iterator() = delete;
|
|
Iterator(underlying iter) : store_iter{iter} {}
|
|
};
|
|
class ConstIterator {
|
|
public:
|
|
using underlying =
|
|
typename std::vector<std::optional<ValueType>>::const_iterator;
|
|
|
|
private:
|
|
underlying store_iter;
|
|
|
|
public:
|
|
ConstIterator() = delete;
|
|
ConstIterator(underlying iter) : store_iter{iter} {}
|
|
};
|
|
class ReverseIterator {
|
|
public:
|
|
using underlying = typename std::vector<std::optional<ValueType>>::iterator;
|
|
|
|
private:
|
|
underlying store_iter;
|
|
|
|
public:
|
|
ReverseIterator() = delete;
|
|
ReverseIterator(underlying store_iter) : store_iter{store_iter} {}
|
|
};
|
|
Map() : store{} {}
|
|
Map(const Map &rhs) : store{rhs.store} {}
|
|
Map &operator=(const Map &rhs) { this->store = rhs.store; }
|
|
Map(std::initializer_list<ValueType> elems) : store{} {
|
|
this->insert(elems.begin(), elems.end());
|
|
}
|
|
// who cares we're using vector
|
|
~Map() {}
|
|
|
|
size_t size() const { return this->store.size(); }
|
|
bool empty() const { return this->store.empty(); }
|
|
// TODO: iterator creation
|
|
Iterator begin() {
|
|
std::size_t start = 0;
|
|
while (2 * (start - store.begin()) + 1 < store.size()) {
|
|
store = 2 * store + 2;
|
|
}
|
|
return Iterator(store.cbegin() + start);
|
|
}
|
|
Iterator end() { return Iterator(store.end()); }
|
|
ConstIterator begin() const {
|
|
std::size_t start = 0;
|
|
while (2 * (start - store.begin()) + 1 < store.size()) {
|
|
store = 2 * store + 2;
|
|
}
|
|
return ConstIterator(store.cbegin() + start);
|
|
}
|
|
ConstIterator end() const { return ConstIterator(store.cend()); }
|
|
ConstIterator cbegin() const { return this->begin(); }
|
|
ConstIterator cend() const { return this->end(); }
|
|
ReverseIterator rbegin() {
|
|
std::size_t start = 0;
|
|
while (2 * (start - store.begin()) + 1 < store.size()) {
|
|
store = 2 * store + 2;
|
|
}
|
|
return ReverseIterator(store.begin() + start);
|
|
}
|
|
ReverseIterator rend() { return ReverseIterator(store.end()); }
|
|
Iterator find(const Key_T &key) {
|
|
std::size_t idx = 0;
|
|
while (store[idx].first != key) {
|
|
if (idx >= store.size()) {
|
|
return this->end();
|
|
}
|
|
if (store[idx].first < key) {
|
|
idx = idx * 2 + 1;
|
|
} else {
|
|
idx = idx * 2 + 2;
|
|
}
|
|
}
|
|
}
|
|
ConstIterator find(const Key_T &key) const {
|
|
std::size_t idx = 0;
|
|
while (store[idx].first != key) {
|
|
if (idx >= store.size()) {
|
|
return this->end();
|
|
}
|
|
if (store[idx].first < key) {
|
|
idx = idx * 2 + 1;
|
|
} else {
|
|
idx = idx * 2 + 2;
|
|
}
|
|
}
|
|
}
|
|
Mapped_T &at(const Key_T &key) {}
|
|
const Mapped_T &at(const Key_T &key) const {}
|
|
Mapped_T &operator[](const Key_T &) {}
|
|
std ::pair<Iterator, bool> insert(const ValueType &) {}
|
|
template <typename IT_T> void insert(IT_T range_beg, IT_T range_end) {
|
|
std::for_each(range_beg, range_end,
|
|
[&](ValueType &val) { this->insert(val); });
|
|
}
|
|
// TODO: erase via iterator
|
|
void erase(Iterator pos) {}
|
|
void erase(const Key_T &key) { this->erase(this->find(key)); }
|
|
void clear() { this->store = {}; }
|
|
friend bool operator==(const Map &lhs, const Map &rhs) {
|
|
if (lhs.store.size() != rhs.store.size()) {
|
|
return false;
|
|
}
|
|
auto liter = lhs.cbegin();
|
|
auto riter = rhs.cbegin();
|
|
// both must be the same length so this is fine
|
|
while (liter != lhs.cend()) {
|
|
if (*liter != *riter) {
|
|
return false;
|
|
}
|
|
liter++;
|
|
riter++;
|
|
}
|
|
return true;
|
|
}
|
|
friend bool operator!=(const Map &lhs, const Map &rhs) {
|
|
return !(lhs == rhs);
|
|
}
|
|
// TODO < operator
|
|
friend bool operator<(const Map &lhs, const Map &rhs) { return false; }
|
|
};
|
|
} // namespace cs440
|