Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/search/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ create_fast_downward_library(
utils/markup
utils/math
utils/memory
utils/printer
utils/rng
utils/rng_options
utils/strings
Expand Down
16 changes: 16 additions & 0 deletions src/search/state_id.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#ifndef STATE_ID_H
#define STATE_ID_H

#include "utils/hash.h"

#include <iostream>

// For documentation on classes relevant to storing and working with registered
Expand Down Expand Up @@ -35,7 +37,21 @@ 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;
}
};

namespace utils {
inline void feed(HashState &hash_state, StateID id) {
feed(hash_state, id.hash());
}
}


#endif
76 changes: 76 additions & 0 deletions src/search/utils/hash.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
#include <unordered_set>
#include <utility>
#include <vector>
#include <set>
#include <map>

namespace utils {
/*
Expand Down Expand Up @@ -263,6 +265,80 @@ void feed(HashState &hash_state, const std::tuple<T...> &t) {
std::apply([&](auto &&... element) {((feed(hash_state, element)), ...);}, t);
}

template<typename T, std::size_t N>
void feed(HashState &hash_state, const std::array<T, N> &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<uint64_t>(vec.size()));
for (const T &item : vec) {
feed(hash_state, item);
}
}

template<typename T>
void feed(HashState &hash_state, const std::set<T> &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<uint64_t>(vec.size()));
for (const T &item : vec) {
feed(hash_state, item);
}
}

template<typename T>
void feed(HashState &hash_state, const std::unordered_set<T> &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<uint64_t>(vec.size()));
for (const T &item : vec) {
feed(hash_state, item);
}
}

template<typename K, typename V>
void feed(HashState &hash_state, const std::map<K, V> &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<uint64_t>(map.size()));
for (const std::pair<K,V> *it : map) {
feed(hash_state, *it);
}
}

template<typename K, typename V>
void feed(HashState &hash_state, const std::unordered_map<K, V> &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<uint64_t>(map.size()));
for (const std::pair<K,V> *it : map) {
feed(hash_state, *it);
}
}

/*
Public hash functions.
Expand Down
174 changes: 174 additions & 0 deletions src/search/utils/printer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
#pragma once

#include <iostream>

#include <tuple>
#include <utility> // for pair

#include <vector>
#include <deque>
#include <array>

#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>

#include <memory>

namespace utils {

template<class T, class S>
std::ostream& operator<<(std::ostream &os, const std::pair<T,S> &thing) {
os << "[" << thing.first << ", " << thing.second << "]" ;
return os;
}

// Helper functions to iterate over tuples
template <typename Tuple>
struct TupleIterator {
template <std::size_t I, std::size_t... Is>
static void print(std::ostream& os, const Tuple& tuple, std::index_sequence<I, Is...>) {
os << std::get<0>(tuple);
((os << ", " << std::get<Is>(tuple)), ...);
}
};

template <typename... Args>
std::ostream& operator<<(std::ostream& os, const std::tuple<Args...>& tuple) {
constexpr std::size_t tuple_size = std::tuple_size<std::tuple<Args...>>::value;
os << "[";
if constexpr (tuple_size > 0) {
TupleIterator<std::tuple<Args...>>::print(os, tuple, std::index_sequence_for<Args...>());
}
os << "]";
return os;
}


template<class T>
std::ostream& operator<<(std::ostream &os, const std::deque<T> &thing) {
os << "[";
bool first = true;
for (auto elem : thing) {
if (! first) {
os << ", ";
}
os << elem;
first = false;
}
os << "]" ;
return os;
}


template<class T>
std::ostream& operator<<(std::ostream &os, const std::vector<T> &thing) {
os << "[";
bool first = true;
for (auto elem : thing) {
if (! first) {
os << ", ";
}
os << elem;
first = false;
}
os << "]" ;
return os;
}


template<class T, std::size_t N>
std::ostream& operator<<(std::ostream &os, const std::array<T, N> &thing) {
os << "[";
bool first = true;
for (auto elem : thing) {
if (! first) {
os << ", ";
}
os << elem;
first = false;
}
os << "]" ;
return os;
}


template<class T, typename... Args>
std::ostream& operator<<(std::ostream &os, const std::set<T,Args...> &thing) {
os << "{";
bool first = true;
for (auto elem : thing) {
if (! first) {
os << ", ";
}
os << elem;
first = false;
}
os << "}" ;
return os;
}

template<class T, typename... Args>
std::ostream& operator<<(std::ostream &os, const std::unordered_set<T,Args...> &thing) {
os << "{";
bool first = true;
for (auto elem : thing) {
if (! first) {
os << ", ";
}
os << elem;
first = false;
}
os << "}" ;
return os;
}

template<class K, class V, typename... Args>
std::ostream& operator<<(std::ostream &os, const std::map<K,V,Args...> &thing) {
os << "{";
bool first = true;
for (auto elem : thing) {
if (! first) {
os << ", ";
}
os << elem.first
<< " : "
<< elem.second ;
first = false;
}
os << "}" ;
return os;
}

template<class K, class V, typename... Args>
std::ostream& operator<<(std::ostream &os, const std::unordered_map<K,V,Args...> &thing) {
os << "{";
bool first = true;
for (auto elem : thing) {
if (! first) {
os << ", ";
}
os << elem.first
<< " : "
<< elem.second ;
first = false;
}
os << "}" ;
return os;
}


template<class T>
std::ostream& operator<<(std::ostream &os, const std::shared_ptr<T> &thing) {
os << "@(" << reinterpret_cast<std::size_t>(thing.get()) << ", c=" << thing.use_count() << ")";
return os;
}

// template<class T>
// std::ostream& operator<<(std::ostream &os, const T* thing) {
// os << "@"s << (thing);
// return os;
// }

}