diff options
Diffstat (limited to 'src/openvic-simulation/types')
-rw-r--r-- | src/openvic-simulation/types/Colour.hpp | 4 | ||||
-rw-r--r-- | src/openvic-simulation/types/Date.hpp | 13 | ||||
-rw-r--r-- | src/openvic-simulation/types/OrderedContainers.hpp | 101 | ||||
-rw-r--r-- | src/openvic-simulation/types/fixed_point/FixedPointMap.hpp | 3 |
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; |