Line data Source code
1 0 : // Distributed under the MIT License.
2 : // See LICENSE.txt for details.
3 :
4 : #pragma once
5 :
6 : #include <boost/functional/hash.hpp>
7 : #include <ckarrayindex.h>
8 : #include <cstddef>
9 : #include <functional>
10 : #include <string>
11 : #include <type_traits>
12 :
13 : #include "Parallel/ArrayIndex.hpp"
14 : #include "Utilities/PrettyType.hpp"
15 :
16 : namespace PUP {
17 : class er;
18 : } // namespace PUP
19 :
20 : namespace Parallel {
21 : /*!
22 : * \brief An ID type that identifies both the parallel component and the index
23 : * in the parallel component.
24 : *
25 : * A specialization of `std::hash` is provided to allow using `ArrayComponentId`
26 : * as a key in associative containers.
27 : */
28 1 : class ArrayComponentId {
29 : public:
30 0 : ArrayComponentId() = default; // Needed for Charm++ serialization
31 :
32 : template <typename ParallelComponent>
33 0 : ArrayComponentId(const ParallelComponent* /*meta*/,
34 : const CkArrayIndex& index);
35 :
36 : // NOLINTNEXTLINE(google-runtime-references)
37 0 : void pup(PUP::er& p);
38 :
39 0 : size_t component_id() const { return component_id_; }
40 :
41 0 : const CkArrayIndex& array_index() const { return array_index_; }
42 :
43 : private:
44 0 : size_t component_id_{0};
45 0 : CkArrayIndex array_index_{};
46 : };
47 :
48 : template <typename ParallelComponent>
49 : ArrayComponentId::ArrayComponentId(const ParallelComponent* const /*meta*/,
50 : const CkArrayIndex& index)
51 : : array_index_(index) {
52 : // Hashing the pretty name demangles it, which is very expensive for the
53 : // long template names of parallel components. Since the result is the same
54 : // for every instance of `ParallelComponent`, compute it only once.
55 : static const size_t cached_component_id =
56 : std::hash<std::string>{}(pretty_type::get_name<ParallelComponent>());
57 : component_id_ = cached_component_id;
58 : }
59 :
60 0 : bool operator==(const ArrayComponentId& lhs, const ArrayComponentId& rhs);
61 :
62 0 : bool operator!=(const ArrayComponentId& lhs, const ArrayComponentId& rhs);
63 :
64 0 : std::ostream& operator<<(std::ostream& os,
65 : const ArrayComponentId& array_component_id);
66 :
67 : /*!
68 : * \brief A convenience function that will make an `ArrayComponentId` from the
69 : * templated `ParallelComponent` and the passed in `array_index`.
70 : */
71 : template <typename ParallelComponent, typename ArrayIndexType>
72 1 : ArrayComponentId make_array_component_id(const ArrayIndexType& array_index) {
73 : return ArrayComponentId{std::add_pointer_t<ParallelComponent>{nullptr},
74 : Parallel::ArrayIndex<ArrayIndexType>(array_index)};
75 : }
76 : } // namespace Parallel
77 :
78 : namespace std {
79 : template <>
80 : struct hash<Parallel::ArrayComponentId> {
81 : size_t operator()(const Parallel::ArrayComponentId& t) const {
82 : size_t result = t.component_id();
83 : boost::hash_combine(result, t.array_index().hash());
84 : return result;
85 : }
86 : };
87 : } // namespace std
|