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