aboutsummaryrefslogtreecommitdiff
path: root/src/openvic-simulation/utility
diff options
context:
space:
mode:
Diffstat (limited to 'src/openvic-simulation/utility')
-rw-r--r--src/openvic-simulation/utility/BMP.cpp3
-rw-r--r--src/openvic-simulation/utility/TslHelper.hpp129
-rw-r--r--src/openvic-simulation/utility/Utility.hpp48
3 files changed, 179 insertions, 1 deletions
diff --git a/src/openvic-simulation/utility/BMP.cpp b/src/openvic-simulation/utility/BMP.cpp
index 4c220da..c615aea 100644
--- a/src/openvic-simulation/utility/BMP.cpp
+++ b/src/openvic-simulation/utility/BMP.cpp
@@ -3,6 +3,7 @@
#include <cstring>
#include <set>
+#include "openvic-simulation/types/OrderedContainers.hpp"
#include "openvic-simulation/utility/Logger.hpp"
using namespace OpenVic;
@@ -91,7 +92,7 @@ bool BMP::read_header() {
// Validate colours
#define VALID_BITS_PER_PIXEL 1, 2, 4, 8, 16, 24, 32
#define STR(x) #x
- static const std::set<uint16_t> BITS_PER_PIXEL { VALID_BITS_PER_PIXEL };
+ static const ordered_set<uint16_t> BITS_PER_PIXEL { VALID_BITS_PER_PIXEL };
if (!BITS_PER_PIXEL.contains(header.bits_per_pixel)) {
Logger::error("Invalid BMP bits per pixel: ", header.bits_per_pixel, " (must be one of " STR(VALID_BITS_PER_PIXEL) ")");
header_validated = false;
diff --git a/src/openvic-simulation/utility/TslHelper.hpp b/src/openvic-simulation/utility/TslHelper.hpp
new file mode 100644
index 0000000..9d1ae77
--- /dev/null
+++ b/src/openvic-simulation/utility/TslHelper.hpp
@@ -0,0 +1,129 @@
+#pragma once
+
+#include <type_traits>
+
+#include <tsl/ordered_map.h>
+#include <tsl/ordered_set.h>
+
+#include "openvic-simulation/types/OrderedContainers.hpp"
+#include "openvic-simulation/utility/Utility.hpp"
+
+namespace OpenVic {
+ template<IsOrderedMap Map, typename Key = typename Map::key_type, typename Mapped = typename Map::mapped_type>
+ struct _OrderedMapMutable {
+ using map_type = Map;
+ struct ordered_iterator {
+ using key_type = Key;
+ using mapped_type = Mapped;
+ using pair_type = std::pair<key_type const&, mapped_type&>;
+ using value_type = pair_type;
+ using iterator = typename map_type::iterator;
+
+ using iterator_category = std::random_access_iterator_tag;
+ using difference_type = typename map_type::values_container_type::iterator::difference_type;
+
+ pair_type operator*() {
+ return { m_iterator.key(), m_iterator.value() };
+ }
+
+ ordered_iterator& operator++() {
+ ++m_iterator;
+ return *this;
+ }
+ ordered_iterator& operator--() {
+ --m_iterator;
+ return *this;
+ }
+
+ ordered_iterator operator++(int) {
+ ordered_iterator tmp(*this);
+ ++(*this);
+ return tmp;
+ }
+ ordered_iterator operator--(int) {
+ ordered_iterator tmp(*this);
+ --(*this);
+ return tmp;
+ }
+
+ pair_type operator[](difference_type n) {
+ return *(*this + n);
+ }
+
+ ordered_iterator& operator+=(difference_type n) {
+ m_iterator += n;
+ return *this;
+ }
+ ordered_iterator& operator-=(difference_type n) {
+ m_iterator -= n;
+ return *this;
+ }
+
+ ordered_iterator operator+(difference_type n) {
+ ordered_iterator tmp(*this);
+ tmp += n;
+ return tmp;
+ }
+ ordered_iterator operator-(difference_type n) {
+ ordered_iterator tmp(*this);
+ tmp -= n;
+ return tmp;
+ }
+
+ bool operator==(const ordered_iterator& rhs) const {
+ return m_iterator == rhs.m_iterator;
+ }
+
+ bool operator!=(const ordered_iterator& rhs) const {
+ return m_iterator != rhs.m_iterator;
+ }
+
+ bool operator<(const ordered_iterator& rhs) const {
+ return m_iterator < rhs.m_iterator;
+ }
+
+ bool operator>(const ordered_iterator& rhs) const {
+ return m_iterator > rhs.m_iterator;
+ }
+
+ bool operator<=(const ordered_iterator& rhs) const {
+ return m_iterator <= rhs.m_iterator;
+ }
+
+ bool operator>=(const ordered_iterator& rhs) const {
+ return m_iterator >= rhs.m_iterator;
+ }
+
+ friend ordered_iterator operator+(difference_type n, const ordered_iterator& it) {
+ return n + it.m_iterator;
+ }
+
+ ordered_iterator operator+(const ordered_iterator& rhs) const {
+ return m_iterator + rhs.m_iterator;
+ }
+
+ difference_type operator-(const ordered_iterator& rhs) const {
+ return m_iterator - rhs.m_iterator;
+ }
+
+ iterator m_iterator;
+ };
+
+ _OrderedMapMutable(map_type& map) : _map(map) {}
+
+ ordered_iterator begin() {
+ return ordered_iterator { _map.begin() };
+ }
+ ordered_iterator end() {
+ return ordered_iterator { _map.end() };
+ }
+
+ private:
+ map_type& _map;
+ };
+
+ template<IsOrderedMap Map, typename Key = typename Map::key_type, typename Mapped = typename Map::mapped_type>
+ _OrderedMapMutable<Map, Key, Mapped> mutable_iterator(Map& map) {
+ return _OrderedMapMutable<Map, Key, Mapped> { map };
+ }
+}
diff --git a/src/openvic-simulation/utility/Utility.hpp b/src/openvic-simulation/utility/Utility.hpp
index e8d7205..0387e7f 100644
--- a/src/openvic-simulation/utility/Utility.hpp
+++ b/src/openvic-simulation/utility/Utility.hpp
@@ -1,5 +1,9 @@
#pragma once
+#include <climits>
+#include <functional>
+#include <type_traits>
+
namespace OpenVic::utility {
[[noreturn]] inline void unreachable() {
// Uses compiler specific extensions if possible.
@@ -11,4 +15,48 @@ namespace OpenVic::utility {
__assume(false);
#endif
}
+
+ template<class T>
+ constexpr inline void hash_combine(std::size_t& s, const T& v) {
+ std::hash<T> h;
+ s ^= h(v) + 0x9e3779b9 + (s << 6) + (s >> 2);
+ }
+
+ template<size_t Shift, class T>
+ constexpr inline void hash_combine_index(std::size_t& s, const T& v) {
+ std::hash<T> h;
+ if constexpr(Shift == 0) {
+ s = h(v);
+ } else {
+ s ^= h(v) << Shift;
+ }
+ }
+
+ template<class T, typename ...Args>
+ constexpr void perfect_hash(std::size_t& s, T&& v, Args&&... args) {
+ static_assert(sizeof(T) + (sizeof(Args) + ...) <= sizeof(std::size_t), "Perfect hashes must be able to fit into size_t");
+ std::hash<T> h;
+ if constexpr(sizeof...(args) == 0) {
+ s = h(v);
+ } else {
+ const std::tuple arg_tuple { args... };
+ s = h(v) << (sizeof(T) * CHAR_BIT);
+ ([&]{
+ // If args is not last pointer of args
+ if (static_cast<const void*>(&(std::get<sizeof...(args) - 1>(arg_tuple))) != static_cast<const void*>(&args)) {
+ s <<= sizeof(Args) * CHAR_BIT;
+ }
+ s |= std::hash<Args>{}(args);
+ }(), ...);
+ }
+ }
+
+ template<typename T, template<typename...> class Z>
+ struct is_specialization_of : std::false_type {};
+
+ template<typename... Args, template<typename...> class Z>
+ struct is_specialization_of<Z<Args...>, Z> : std::true_type {};
+
+ template<typename T, template<typename...> class Z>
+ inline constexpr bool is_specialization_of_v = is_specialization_of<T, Z>::value;
}