134 lines
No EOL
3.6 KiB
C++
134 lines
No EOL
3.6 KiB
C++
#include <algorithm>
|
|
#include <iostream>
|
|
#include <type_traits>
|
|
#include <vector>
|
|
|
|
template <typename Key, typename Value>
|
|
class VectorMap {
|
|
std::vector<Key> keys_;
|
|
std::vector<Value> values_;
|
|
|
|
static_assert(std::is_default_constructible<Value>::value, "Value should have the default constructor");
|
|
static_assert(std::is_default_constructible_v<Value>, "Value should have the default constructor");
|
|
|
|
public:
|
|
using K = Key;
|
|
using V = Value;
|
|
template <typename T>
|
|
using iterator = typename std::vector<T>::iterator;
|
|
|
|
void insert(const Key& k, const Value& v) {
|
|
keys_.emplace_back(k);
|
|
values_.emplace_back(v);
|
|
}
|
|
|
|
static constexpr bool isIntKey() {
|
|
// if (std::is_integral_v<Key>) {
|
|
if (std::is_same_v<Key, int>) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
Value& operator[](const Key& k);
|
|
Value& at(const Key& k);
|
|
|
|
static constexpr bool is_int_key = std::is_same_v<Key, int>;
|
|
};
|
|
|
|
template <typename Key, typename Value>
|
|
Value& VectorMap<Key, Value>::operator[](const Key& k) {
|
|
auto it = std::find(std::begin(keys_), std::end(keys_), k);
|
|
if (it == std::end(keys_)) {
|
|
keys_.emplace_back(k);
|
|
values_.emplace_back(Value{});
|
|
return values_.back();
|
|
}
|
|
auto dist = std::distance(keys_.begin(), it);
|
|
return values_[dist];
|
|
}
|
|
|
|
template <typename Key, typename Value>
|
|
Value& VectorMap<Key, Value>::at(const Key& k) {
|
|
auto it = std::find(std::begin(keys_), std::end(keys_), k);
|
|
if (it == std::end(keys_)) {
|
|
throw std::out_of_range("This key does not exist");
|
|
}
|
|
auto dist = std::distance(keys_.begin(), it);
|
|
return values_[dist];
|
|
}
|
|
|
|
|
|
template <typename ValueType>
|
|
class VectorMap<bool, ValueType> { // specialization
|
|
static_assert(std::is_default_constructible<ValueType>::value,
|
|
"ValueType must have the default constructor");
|
|
|
|
ValueType t_;
|
|
ValueType f_;
|
|
|
|
public:
|
|
static constexpr bool is_int_key = false; // type_traits #2
|
|
|
|
VectorMap() {
|
|
std::cout << "bool specialization used\n";
|
|
}
|
|
|
|
void insert(bool key, ValueType&& value) {
|
|
if (key) {
|
|
t_ = value;
|
|
} else {
|
|
f_ = value;
|
|
}
|
|
}
|
|
|
|
ValueType& operator[](bool key) {
|
|
if (key) {
|
|
return t_;
|
|
}
|
|
return f_;
|
|
}
|
|
|
|
ValueType& at(bool key) {
|
|
if (key) {
|
|
return t_;
|
|
}
|
|
return f_;
|
|
}
|
|
};
|
|
|
|
template<typename T>
|
|
constexpr bool is_int_key_v = T::is_int_key;
|
|
|
|
template <typename Key, typename Value>
|
|
constexpr bool is_int_key_v1 = VectorMap<Key,Value>::is_int_key;
|
|
|
|
int main() {
|
|
VectorMap<int, char> map;
|
|
// VectorMap<int, char>::iterator<K> k;
|
|
map.insert(1, 'c');
|
|
std::cout << map[1] << '\n';
|
|
map[1] = 'e'; // replaces value under 1
|
|
std::cout << map[1] << '\n'; // prints 'e'
|
|
// map.at(2); // throw std::out_of_range
|
|
std::cout << std::boolalpha << map.isIntKey() << '\n';
|
|
std::cout << std::boolalpha << map.is_int_key << '\n';
|
|
|
|
VectorMap<char, char> map3;
|
|
std::cout << std::boolalpha << map3.isIntKey() << '\n';
|
|
|
|
VectorMap<bool, int> map4;
|
|
map4.insert(true, 3);
|
|
map4.insert(false, 0);
|
|
std::cout << map4[true] << '\n';
|
|
map4[true] = 10; // replaces value under 1
|
|
std::cout << map4[true] << '\n'; // prints 'e'
|
|
std::cout << std::boolalpha << is_int_key_v<decltype(map4)> << '\n';
|
|
std::cout << std::boolalpha << is_int_key_v<decltype(map)> << '\n';
|
|
std::cout << std::boolalpha << is_int_key_v<K> << '\n';
|
|
|
|
std::vector<int> v{1, 2, 3};
|
|
find(begin(v), end(v), 2);
|
|
|
|
return 0;
|
|
} |