1 /* Copyright (c) 2016-2023. The SimGrid Team.
2 * All rights reserved. */
4 /* This program is free software; you can redistribute it and/or modify it
5 * under the terms of the license (GNU LGPL) which comes with this package. */
7 #ifndef XBT_UTILITY_HPP
8 #define XBT_UTILITY_HPP
13 #include <type_traits>
16 /** @brief Helper macro to declare enum class
18 * Declares an enum class EnumType, and a function "const char* to_c_str(EnumType)" to retrieve a C-string description
21 #define XBT_DECLARE_ENUM_CLASS(EnumType, ...) \
22 enum class EnumType; \
23 static constexpr char const* to_c_str(EnumType value) \
25 constexpr std::array<const char*, _XBT_COUNT_ARGS(__VA_ARGS__)> names{{_XBT_STRINGIFY_ARGS(__VA_ARGS__)}}; \
26 return names.at(static_cast<int>(value)); \
28 static constexpr bool is_valid_##EnumType(int raw_value) \
30 return raw_value >= 0 && raw_value < _XBT_COUNT_ARGS(__VA_ARGS__); \
32 enum class EnumType { __VA_ARGS__ } /* defined here to handle trailing semicolon */
37 /** @brief Replacement for C++20's std::type_identity_t
39 #if __cplusplus >= 201806L // __cpp_lib_type_identity
40 template <class T> using type_identity_t = typename std::type_identity_t<T>;
42 template <class T> struct type_identity {
46 template <class T> using type_identity_t = typename type_identity<T>::type;
49 /** @brief A hash which works with more stuff
51 * It can hash pairs: the standard hash currently doesn't include this.
53 template <class X> class hash : public std::hash<X> {
56 template <class X, class Y> class hash<std::pair<X, Y>> {
58 std::size_t operator()(std::pair<X, Y> const& x) const
62 return h1(x.first) ^ h2(x.second);
66 /** @brief Comparator class for using with std::priority_queue or boost::heap.
68 * Compare two std::pair by their first element (of type double), and return true when the first is greater than the
69 * second. Useful to have priority queues with the smallest element on top.
71 template <class Pair> class HeapComparator {
73 bool operator()(const Pair& a, const Pair& b) const { return a.first > b.first; }
76 /** @brief Erase an element given by reference from a boost::intrusive::list.
78 template <class List, class Elem> inline void intrusive_erase(List& list, Elem& elem)
80 list.erase(list.iterator_to(elem));
84 } // namespace simgrid