aboutsummaryrefslogtreecommitdiff
path: root/src/openvic-simulation/types
diff options
context:
space:
mode:
Diffstat (limited to 'src/openvic-simulation/types')
-rw-r--r--src/openvic-simulation/types/Colour.hpp4
-rw-r--r--src/openvic-simulation/types/Date.hpp13
-rw-r--r--src/openvic-simulation/types/OrderedContainers.hpp101
-rw-r--r--src/openvic-simulation/types/fixed_point/FixedPointMap.hpp3
4 files changed, 117 insertions, 4 deletions
diff --git a/src/openvic-simulation/types/Colour.hpp b/src/openvic-simulation/types/Colour.hpp
index dc9c4c6..38a1468 100644
--- a/src/openvic-simulation/types/Colour.hpp
+++ b/src/openvic-simulation/types/Colour.hpp
@@ -375,9 +375,7 @@ namespace OpenVic {
};
template<typename T>
- concept IsColour = requires(T t) {
- { basic_colour_t { t } } -> std::same_as<T>;
- };
+ concept IsColour = OpenVic::utility::is_specialization_of_v<T, basic_colour_t>;
template<typename ValueT, typename IntT>
struct rgb_colour_traits : colour_traits<ValueT, IntT> {
diff --git a/src/openvic-simulation/types/Date.hpp b/src/openvic-simulation/types/Date.hpp
index 3dc6dab..2bf08e8 100644
--- a/src/openvic-simulation/types/Date.hpp
+++ b/src/openvic-simulation/types/Date.hpp
@@ -1,10 +1,12 @@
#pragma once
+#include <climits>
#include <cstdint>
#include <ostream>
#include <string>
#include "openvic-simulation/utility/Getters.hpp"
+#include "openvic-simulation/utility/Utility.hpp"
namespace OpenVic {
// A relative period between points in time, measured in days
@@ -107,3 +109,14 @@ namespace OpenVic {
};
std::ostream& operator<<(std::ostream& out, Date date);
}
+
+namespace std {
+ template<>
+ struct hash<OpenVic::Date> {
+ [[nodiscard]] size_t operator()(OpenVic::Date date) const {
+ size_t result = 0;
+ OpenVic::utility::perfect_hash(result, date.get_day(), date.get_month(), date.get_year());
+ return result;
+ }
+ };
+} \ No newline at end of file
diff --git a/src/openvic-simulation/types/OrderedContainers.hpp b/src/openvic-simulation/types/OrderedContainers.hpp
new file mode 100644
index 0000000..e90000c
--- /dev/null
+++ b/src/openvic-simulation/types/OrderedContainers.hpp
@@ -0,0 +1,101 @@
+#pragma once
+
+#include <concepts>
+#include <deque>
+#include <functional>
+#include <memory>
+
+#include <tsl/ordered_map.h>
+#include <tsl/ordered_set.h>
+
+#include "openvic-simulation/utility/Utility.hpp"
+
+namespace OpenVic {
+ struct ordered_container_string_hash {
+ using is_transparent = void;
+ [[nodiscard]] size_t operator()(const char* txt) const {
+ return std::hash<std::string_view> {}(txt);
+ }
+ [[nodiscard]] size_t operator()(std::string_view txt) const {
+ return std::hash<std::string_view> {}(txt);
+ }
+ [[nodiscard]] size_t operator()(const std::string& txt) const {
+ return std::hash<std::string> {}(txt);
+ }
+ };
+
+ template<typename T>
+ struct container_hash : std::hash<T> {};
+
+ template<>
+ struct container_hash<std::string> : ordered_container_string_hash {};
+ template<>
+ struct container_hash<std::string_view> : ordered_container_string_hash {};
+ template<>
+ struct container_hash<const char*> : ordered_container_string_hash {};
+
+ // Useful for contiguous memory
+ template<
+ class Key, class T, class Hash = container_hash<Key>, class KeyEqual = std::equal_to<>,
+ class Allocator = std::allocator<std::pair<Key, T>>, class IndexType = std::uint_least32_t>
+ using vector_ordered_map =
+ tsl::ordered_map<Key, T, Hash, KeyEqual, Allocator, std::vector<std::pair<Key, T>, Allocator>, IndexType>;
+
+ // Useful for stable memory addresses (so long as you don't remove or insert values)
+ template<
+ class Key, class T, class Hash = container_hash<Key>, class KeyEqual = std::equal_to<>,
+ class Allocator = std::allocator<std::pair<Key, T>>, class IndexType = std::uint_least32_t>
+ using deque_ordered_map =
+ tsl::ordered_map<Key, T, Hash, KeyEqual, Allocator, std::deque<std::pair<Key, T>, Allocator>, IndexType>;
+
+ template<
+ class Key, class T, class Hash = container_hash<Key>, class KeyEqual = std::equal_to<>,
+ class Allocator = std::allocator<std::pair<Key, T>>, class IndexType = std::uint_least32_t>
+ using ordered_map = vector_ordered_map<Key, T, Hash, KeyEqual, Allocator, IndexType>;
+
+ // Useful for contiguous memory
+ template<
+ class Key, class Hash = container_hash<Key>, class KeyEqual = std::equal_to<>, class Allocator = std::allocator<Key>,
+ class ValueTypeContainer = std::deque<Key, Allocator>, class IndexType = std::uint_least32_t>
+ using vector_ordered_set = tsl::ordered_set<Key, Hash, KeyEqual, Allocator, std::vector<Key, Allocator>, IndexType>;
+
+ // Useful for stable memory addresses (so long as you don't remove or insert values)
+ template<
+ class Key, class Hash = container_hash<Key>, class KeyEqual = std::equal_to<>, class Allocator = std::allocator<Key>,
+ class ValueTypeContainer = std::deque<Key, Allocator>, class IndexType = std::uint_least32_t>
+ using deque_ordered_set = tsl::ordered_set<Key, Hash, KeyEqual, Allocator, std::deque<Key, Allocator>, IndexType>;
+
+ template<
+ class Key, class Hash = container_hash<Key>, class KeyEqual = std::equal_to<>, class Allocator = std::allocator<Key>,
+ class IndexType = std::uint_least32_t>
+ using ordered_set = vector_ordered_set<Key, Hash, KeyEqual, Allocator, IndexType>;
+
+ template<typename T>
+ concept IsOrderedMap = utility::is_specialization_of_v<T, tsl::ordered_map>;
+ template<typename T>
+ concept IsOrderedSet = utility::is_specialization_of_v<T, tsl::ordered_set>;
+ template<typename T>
+ concept IsVectorOrderedMap = utility::is_specialization_of_v<T, vector_ordered_map>;
+ template<typename T>
+ concept IsVectorOrderedSet = utility::is_specialization_of_v<T, vector_ordered_set>;
+ template<typename T>
+ concept IsDequeOrderedMap = utility::is_specialization_of_v<T, deque_ordered_map>;
+ template<typename T>
+ concept IsDequeOrderedSet = utility::is_specialization_of_v<T, deque_ordered_set>;
+
+ template<typename T, typename Key, typename Value>
+ concept IsOrderedMapOf =
+ IsOrderedMap<T> && std::same_as<Key, typename T::key_type> && std::same_as<Value, typename T::mapped_type>;
+ template<typename T, typename Key>
+ concept IsOrderedSetOf = IsOrderedSet<T> && std::same_as<Key, typename T::key_type>;
+ template<typename T, typename Key, typename Value>
+ concept IsVectorOrderedMapOf =
+ IsVectorOrderedMap<T> && std::same_as<Key, typename T::key_type> && std::same_as<Value, typename T::mapped_type>;
+ template<typename T, typename Key>
+ concept IsVectorOrderedSetOf = IsVectorOrderedSet<T> && std::same_as<Key, typename T::key_type>;
+ template<typename T, typename Key, typename Value>
+ concept IsDequeOrderedMapOf =
+ IsDequeOrderedMap<T> && std::same_as<Key, typename T::key_type> && std::same_as<Value, typename T::mapped_type>;
+ template<typename T, typename Key>
+ concept IsDequeOrderedSetOf = IsDequeOrderedSet<T> && std::same_as<Key, typename T::key_type>;
+}
diff --git a/src/openvic-simulation/types/fixed_point/FixedPointMap.hpp b/src/openvic-simulation/types/fixed_point/FixedPointMap.hpp
index a7d298b..1904fec 100644
--- a/src/openvic-simulation/types/fixed_point/FixedPointMap.hpp
+++ b/src/openvic-simulation/types/fixed_point/FixedPointMap.hpp
@@ -1,11 +1,12 @@
#pragma once
+#include "openvic-simulation/types/OrderedContainers.hpp"
#include "openvic-simulation/types/fixed_point/FixedPoint.hpp"
namespace OpenVic {
template<typename T>
- using fixed_point_map_t = std::map<T, fixed_point_t>;
+ using fixed_point_map_t = ordered_map<T, fixed_point_t>;
template<typename T>
using fixed_point_map_value_t = typename fixed_point_map_t<T>::value_type;