From 0cc163ceed19feb813955f79761c70cf8ec4e9bc Mon Sep 17 00:00:00 2001 From: Masataro Asai Date: Fri, 19 Jan 2024 18:49:27 -0500 Subject: [PATCH 1/5] made StateID hashable --- src/search/state_id.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/search/state_id.h b/src/search/state_id.h index 6e9dc3a02d..da06e936ad 100644 --- a/src/search/state_id.h +++ b/src/search/state_id.h @@ -1,6 +1,8 @@ #ifndef STATE_ID_H #define STATE_ID_H +#include "utils/hash.h" + #include // For documentation on classes relevant to storing and working with registered @@ -35,7 +37,16 @@ class StateID { bool operator!=(const StateID &other) const { return !(*this == other); } + int hash() const { + return value; + } }; +namespace utils { +inline void feed(HashState &hash_state, StateID id) { + feed(hash_state, id.hash()); +} +} + #endif From 0c73bdb8e35fc5781df133c7d566fcf96575a938 Mon Sep 17 00:00:00 2001 From: Masataro Asai Date: Thu, 8 Feb 2024 15:50:18 -0500 Subject: [PATCH 2/5] made StateID comparable --- src/search/state_id.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/search/state_id.h b/src/search/state_id.h index da06e936ad..4b69df64b2 100644 --- a/src/search/state_id.h +++ b/src/search/state_id.h @@ -37,6 +37,11 @@ class StateID { bool operator!=(const StateID &other) const { return !(*this == other); } + + bool operator<(const StateID &other) const { + return value < other.value; + } + int hash() const { return value; } From 1c37498e3c9af5fc7d11a8d0e46781e4c7cd29fb Mon Sep 17 00:00:00 2001 From: Masataro Asai Date: Fri, 5 Jul 2024 14:25:43 -0400 Subject: [PATCH 3/5] made std::array hashable --- src/search/utils/hash.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/search/utils/hash.h b/src/search/utils/hash.h index bc755d7558..a0a2c3aa55 100644 --- a/src/search/utils/hash.h +++ b/src/search/utils/hash.h @@ -263,6 +263,21 @@ void feed(HashState &hash_state, const std::tuple &t) { std::apply([&](auto &&... element) {((feed(hash_state, element)), ...);}, t); } +template +void feed(HashState &hash_state, const std::array &vec) { + /* + Feed vector size to ensure that no two different vectors of the same type + have the same code prefix. + + Using uint64_t is wasteful on 32-bit platforms but feeding a size_t breaks + the build on MacOS (see msg7812). + */ + feed(hash_state, static_cast(vec.size())); + for (const T &item : vec) { + feed(hash_state, item); + } +} + /* Public hash functions. From 40960cf345fb72722493b013ffc737f329bc855d Mon Sep 17 00:00:00 2001 From: Masataro Asai Date: Sun, 12 Jan 2025 12:56:18 -0500 Subject: [PATCH 4/5] made std::unordered/ordered_set/map hashable --- src/search/utils/hash.h | 61 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/src/search/utils/hash.h b/src/search/utils/hash.h index a0a2c3aa55..6559e532b1 100644 --- a/src/search/utils/hash.h +++ b/src/search/utils/hash.h @@ -8,6 +8,8 @@ #include #include #include +#include +#include namespace utils { /* @@ -278,6 +280,65 @@ void feed(HashState &hash_state, const std::array &vec) { } } +template +void feed(HashState &hash_state, const std::set &vec) { + /* + Feed vector size to ensure that no two different vectors of the same type + have the same code prefix. + + Using uint64_t is wasteful on 32-bit platforms but feeding a size_t breaks + the build on MacOS (see msg7812). + */ + feed(hash_state, static_cast(vec.size())); + for (const T &item : vec) { + feed(hash_state, item); + } +} + +template +void feed(HashState &hash_state, const std::unordered_set &vec) { + /* + Feed vector size to ensure that no two different vectors of the same type + have the same code prefix. + + Using uint64_t is wasteful on 32-bit platforms but feeding a size_t breaks + the build on MacOS (see msg7812). + */ + feed(hash_state, static_cast(vec.size())); + for (const T &item : vec) { + feed(hash_state, item); + } +} + +template +void feed(HashState &hash_state, const std::map &map) { + /* + Feed vector size to ensure that no two different vectors of the same type + have the same code prefix. + + Using uint64_t is wasteful on 32-bit platforms but feeding a size_t breaks + the build on MacOS (see msg7812). + */ + feed(hash_state, static_cast(map.size())); + for (const std::pair *it : map) { + feed(hash_state, *it); + } +} + +template +void feed(HashState &hash_state, const std::unordered_map &map) { + /* + Feed vector size to ensure that no two different vectors of the same type + have the same code prefix. + + Using uint64_t is wasteful on 32-bit platforms but feeding a size_t breaks + the build on MacOS (see msg7812). + */ + feed(hash_state, static_cast(map.size())); + for (const std::pair *it : map) { + feed(hash_state, *it); + } +} /* Public hash functions. From 1213205cada2f00d54d6b1d70ef61e249b906c7f Mon Sep 17 00:00:00 2001 From: Masataro Asai Date: Fri, 16 Feb 2024 11:56:35 -0500 Subject: [PATCH 5/5] made various std:: collections printable --- src/search/CMakeLists.txt | 1 + src/search/utils/printer.h | 174 +++++++++++++++++++++++++++++++++++++ 2 files changed, 175 insertions(+) create mode 100644 src/search/utils/printer.h diff --git a/src/search/CMakeLists.txt b/src/search/CMakeLists.txt index 2ed853265b..303f8caa8f 100644 --- a/src/search/CMakeLists.txt +++ b/src/search/CMakeLists.txt @@ -139,6 +139,7 @@ create_fast_downward_library( utils/markup utils/math utils/memory + utils/printer utils/rng utils/rng_options utils/strings diff --git a/src/search/utils/printer.h b/src/search/utils/printer.h new file mode 100644 index 0000000000..563c6999e4 --- /dev/null +++ b/src/search/utils/printer.h @@ -0,0 +1,174 @@ +#pragma once + +#include + +#include +#include // for pair + +#include +#include +#include + +#include +#include +#include +#include + +#include + +namespace utils { + +template +std::ostream& operator<<(std::ostream &os, const std::pair &thing) { + os << "[" << thing.first << ", " << thing.second << "]" ; + return os; +} + +// Helper functions to iterate over tuples +template +struct TupleIterator { + template + static void print(std::ostream& os, const Tuple& tuple, std::index_sequence) { + os << std::get<0>(tuple); + ((os << ", " << std::get(tuple)), ...); + } +}; + +template +std::ostream& operator<<(std::ostream& os, const std::tuple& tuple) { + constexpr std::size_t tuple_size = std::tuple_size>::value; + os << "["; + if constexpr (tuple_size > 0) { + TupleIterator>::print(os, tuple, std::index_sequence_for()); + } + os << "]"; + return os; +} + + +template +std::ostream& operator<<(std::ostream &os, const std::deque &thing) { + os << "["; + bool first = true; + for (auto elem : thing) { + if (! first) { + os << ", "; + } + os << elem; + first = false; + } + os << "]" ; + return os; +} + + +template +std::ostream& operator<<(std::ostream &os, const std::vector &thing) { + os << "["; + bool first = true; + for (auto elem : thing) { + if (! first) { + os << ", "; + } + os << elem; + first = false; + } + os << "]" ; + return os; +} + + +template +std::ostream& operator<<(std::ostream &os, const std::array &thing) { + os << "["; + bool first = true; + for (auto elem : thing) { + if (! first) { + os << ", "; + } + os << elem; + first = false; + } + os << "]" ; + return os; +} + + +template +std::ostream& operator<<(std::ostream &os, const std::set &thing) { + os << "{"; + bool first = true; + for (auto elem : thing) { + if (! first) { + os << ", "; + } + os << elem; + first = false; + } + os << "}" ; + return os; +} + +template +std::ostream& operator<<(std::ostream &os, const std::unordered_set &thing) { + os << "{"; + bool first = true; + for (auto elem : thing) { + if (! first) { + os << ", "; + } + os << elem; + first = false; + } + os << "}" ; + return os; +} + +template +std::ostream& operator<<(std::ostream &os, const std::map &thing) { + os << "{"; + bool first = true; + for (auto elem : thing) { + if (! first) { + os << ", "; + } + os << elem.first + << " : " + << elem.second ; + first = false; + } + os << "}" ; + return os; +} + +template +std::ostream& operator<<(std::ostream &os, const std::unordered_map &thing) { + os << "{"; + bool first = true; + for (auto elem : thing) { + if (! first) { + os << ", "; + } + os << elem.first + << " : " + << elem.second ; + first = false; + } + os << "}" ; + return os; +} + + +template +std::ostream& operator<<(std::ostream &os, const std::shared_ptr &thing) { + os << "@(" << reinterpret_cast(thing.get()) << ", c=" << thing.use_count() << ")"; + return os; +} + +// template +// std::ostream& operator<<(std::ostream &os, const T* thing) { +// os << "@"s << (thing); +// return os; +// } + +}