Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Add new entry in Release_Notes.
[simgrid.git] / include / xbt / utility.hpp
1 /* Copyright (c) 2016-2023. The SimGrid Team.
2  * All rights reserved.                                                     */
3
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. */
6
7 #ifndef XBT_UTILITY_HPP
8 #define XBT_UTILITY_HPP
9
10 #include <array>
11 #include <functional>
12 #include <tuple>
13 #include <type_traits>
14 #include <xbt/base.h>
15
16 /** @brief Helper macro to declare enum class
17  *
18  * Declares an enum class EnumType, and a function "const char* to_c_str(EnumType)" to retrieve a C-string description
19  * for each value.
20  */
21 #define XBT_DECLARE_ENUM_CLASS(EnumType, ...)                                                                          \
22   enum class EnumType;                                                                                                 \
23   static constexpr char const* to_c_str(EnumType value)                                                                \
24   {                                                                                                                    \
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));                                                                          \
27   }                                                                                                                    \
28   static constexpr bool is_valid_##EnumType(int raw_value)                                                             \
29   {                                                                                                                    \
30     return raw_value >= 0 && raw_value < _XBT_COUNT_ARGS(__VA_ARGS__);                                                 \
31   }                                                                                                                    \
32   enum class EnumType { __VA_ARGS__ } /* defined here to handle trailing semicolon */
33
34 namespace simgrid::xbt {
35
36 /** @brief Replacement for C++20's std::type_identity_t
37  */
38 #if __cplusplus >= 201806L // __cpp_lib_type_identity
39 template <class T> using type_identity_t = typename std::type_identity_t<T>;
40 #else
41 template <class T> struct type_identity {
42   using type = T;
43 };
44
45 template <class T> using type_identity_t = typename type_identity<T>::type;
46 #endif
47
48 /** @brief A hash which works with more stuff
49  *
50  *  It can hash pairs: the standard hash currently doesn't include this.
51  */
52 template <class X> class hash : public std::hash<X> {
53 };
54
55 template <class X, class Y> class hash<std::pair<X, Y>> {
56 public:
57   std::size_t operator()(std::pair<X, Y> const& x) const
58   {
59     hash<X> h1;
60     hash<X> h2;
61     return h1(x.first) ^ h2(x.second);
62   }
63 };
64
65 /** @brief Comparator class for using with std::priority_queue or boost::heap.
66  *
67  * Compare two std::pair by their first element (of type double), and return true when the first is greater than the
68  * second.  Useful to have priority queues with the smallest element on top.
69  */
70 template <class Pair> class HeapComparator {
71 public:
72   bool operator()(const Pair& a, const Pair& b) const { return a.first > b.first; }
73 };
74
75 /** @brief Erase an element given by reference from a boost::intrusive::list.
76  */
77 template <class List, class Elem> inline void intrusive_erase(List& list, Elem& elem)
78 {
79   list.erase(list.iterator_to(elem));
80 }
81
82 } // namespace simgrid::xbt
83 #endif