multiindex.h
Go to the documentation of this file.
1 //
2 // Created by Eduard Valeyev on 10/21/22.
3 //
4 
5 #ifndef TTG_UTIL_MULTIINDEX_H
6 #define TTG_UTIL_MULTIINDEX_H
7 
9 
10 namespace ttg {
11 
12  template <std::size_t Rank, typename Int = int>
13  struct MultiIndex {
14  static constexpr const std::size_t max_index = 1 << 21;
15  static constexpr const std::size_t max_index_square = max_index * max_index;
16  MultiIndex() = default;
17  template <typename Integer, typename = std::enable_if_t<std::is_integral_v<Int>>>
18  MultiIndex(std::initializer_list<Integer> ilist) {
19  std::copy(ilist.begin(), ilist.end(), data_.begin());
20  assert(valid());
21  }
22  template <typename... Ints, typename = std::enable_if_t<(std::is_integral_v<Ints> && ...)>>
23  MultiIndex(Ints... ilist) : data_{{static_cast<Int>(ilist)...}} {
24  assert(valid());
25  }
26  explicit MultiIndex(std::size_t hash) {
27  static_assert(Rank == 1 || Rank == 2 || Rank == 3,
28  "MultiIndex<Rank>::MultiIndex(hash) only implemented for Rank={1,2,3}");
29  if (Rank == 1) {
30  assert(hash < max_index);
31  (*this)[0] = hash;
32  }
33  if (Rank == 2) {
34  (*this)[0] = hash / max_index;
35  (*this)[1] = hash % max_index;
36  } else if (Rank == 3) {
37  (*this)[0] = hash / max_index_square;
38  (*this)[1] = (hash % max_index_square) / max_index;
39  (*this)[2] = hash % max_index;
40  }
41  }
42  std::size_t hash() const {
43  static_assert(Rank == 1 || Rank == 2 || Rank == 3, "MultiIndex<Rank>::hash only implemented for Rank={1,2,3}");
44  if constexpr (Rank == 1)
45  return (*this)[0];
46  else if constexpr (Rank == 2) {
47  return (*this)[0] * max_index + (*this)[1];
48  } else if constexpr (Rank == 3) {
49  return ((*this)[0] * max_index + (*this)[1]) * max_index + (*this)[2];
50  }
51  }
52 
53  const auto &operator[](std::size_t idx) const {
54  if (idx >= Rank) assert(idx < Rank);
55  return data_[idx];
56  }
57 
58  template <typename Archive>
59  void serialize(Archive &ar, const unsigned int version = 0) {
60  ar &data_;
61  }
62 
63  private:
64  bool valid() {
65  bool result = true;
66  for (const auto &idx : data_) {
67  result = result && (idx < max_index);
68  }
69  return result;
70  }
71 
72  std::array<Int, Rank> data_;
73 
74  friend bool operator==(const MultiIndex<Rank> &lhs, const MultiIndex<Rank> &rhs) {
75  return lhs.data_ == rhs.data_;
76  }
77  friend bool operator!=(const MultiIndex<Rank> &lhs, const MultiIndex<Rank> &rhs) {
78  return !(lhs == rhs);
79  }
80  };
81 
82  template <std::size_t Rank>
83  std::ostream &operator<<(std::ostream &os, const MultiIndex<Rank> &key) {
84  os << "{";
85  for (size_t i = 0; i != Rank; ++i) os << key[i] << (i + 1 != Rank ? "," : "");
86  os << "}";
87  return os;
88  }
89 
90 } // namespace ttg
91 
92 #ifdef TTG_SERIALIZATION_SUPPORTS_MADNESS
93 namespace madness {
94  namespace archive {
95  template <class Archive, std::size_t Rank>
96  struct ArchiveStoreImpl<Archive, ttg::MultiIndex<Rank>> {
97  static inline void store(const Archive& ar, const ttg::MultiIndex<Rank>& mi) {
98  for (size_t i = 0; i != Rank; ++i) ar << mi[i];
99  }
100  };
101 
102  template <class Archive, std::size_t Rank>
103  struct ArchiveLoadImpl<Archive, ttg::MultiIndex<Rank>> {
104  static inline void load(const Archive& ar, ttg::MultiIndex<Rank>& mi) {
105  for (size_t i = 0; i != Rank; ++i) ar >> mi[i];
106  }
107  };
108  } // namespace archive
109 } // namespace madness
110 
111 static_assert(madness::is_serializable_v<madness::archive::BufferOutputArchive, ttg::MultiIndex<3>>);
112 
113 #endif // TTG_SERIALIZATION_SUPPORTS_MADNESS
114 
115 #endif // TTG_UTIL_MULTIINDEX_H
top-level TTG namespace contains runtime-neutral functionality
Definition: keymap.h:8
std::array< int, 3 > version()
Definition: version.cc:4
std::ostream & operator<<(std::ostream &os, const MultiIndex< Rank > &key)
Definition: multiindex.h:83
MultiIndex(std::size_t hash)
Definition: multiindex.h:26
MultiIndex(std::initializer_list< Integer > ilist)
Definition: multiindex.h:18
MultiIndex(Ints... ilist)
Definition: multiindex.h:23
std::size_t hash() const
Definition: multiindex.h:42
void serialize(Archive &ar, const unsigned int version=0)
Definition: multiindex.h:59
static constexpr const std::size_t max_index_square
Definition: multiindex.h:15
friend bool operator==(const MultiIndex< Rank > &lhs, const MultiIndex< Rank > &rhs)
Definition: multiindex.h:74
static constexpr const std::size_t max_index
Definition: multiindex.h:14
friend bool operator!=(const MultiIndex< Rank > &lhs, const MultiIndex< Rank > &rhs)
Definition: multiindex.h:77
const auto & operator[](std::size_t idx) const
Definition: multiindex.h:53
MultiIndex()=default
Computes hash values for objects of type T.
Definition: hash.h:81