Raw File
simpleshiftmap.hpp
#pragma once

template <typename key_type, typename value_type>
class SimpleShiftMap {

protected:
	key_type min_key;
	key_type max_key;
	size_t num_keys; // actual number of elements stored
	std::vector<value_type> data;
	std::vector<bool> filled;

public:
	// key range [min_key, max_key] inclusive
	SimpleShiftMap(key_type min_key, key_type max_key):
		min_key(min_key),
		max_key(max_key),
		num_keys(0),
		data((max_key - min_key)+1),
		filled((max_key - min_key)+1, false)
	{}

	bool valid_key(const key_type& k) {
		return min_key <= k && k <= max_key;
	}

	bool contains(const key_type& k) {
		if (!valid_key(k)) {
			return false;
		}
		const size_t index = key_to_index(k);
		return filled[index];
	}

	value_type get(const key_type& k, const value_type fallback) {
		if (contains(k)) {
			return at(k);
		} else {
			return fallback;
		}
	}

	void insert(const key_type& k, const value_type& v) {
		assert(valid_key(k));
		const size_t index = key_to_index(k);
		data[index] = v;
		if (!filled[index]) {
			++num_keys;
			filled[index] = true;
		}
	}

	void insert_or_max(const key_type& k, const value_type& v) {
		assert(valid_key(k));
		const size_t index = key_to_index(k);
		if (!filled[index]) {
			++num_keys;
			filled[index] = true;
			data[index] = v;
		} else {
			data[index] = std::max(data[index], v);
		}
	}

	// TODO: consider checking if set
	value_type& operator[](const key_type& k) {
		assert(valid_key(k));
		const size_t index = key_to_index(k);
		if (!filled[index]) {
			++num_keys;
			data[index] = value_type();
			filled[index] = true;
		}
		return data[index];
	}

	size_t size() {
		return num_keys;
	}

	template <typename receiving_stream_t>
	void push_mapping(receiving_stream_t& output) {
		key_type k = min_key;
		for (const value_type& v: data) {
			output.push({k, v});
			++k;
		}
	}

protected:
	value_type& at(const key_type& k) {
		return data[key_to_index(k)];
	}

	inline size_t key_to_index(const key_type& k) {
		return k - static_cast<size_t>(min_key);
	}

	inline key_type index_to_key(const size_t& i) {
		return static_cast<key_type>(i) + min_key;
	}
};
back to top