Low-Level Abstraction of Memory Access
RecordCoord.hpp
Go to the documentation of this file.
1 // Copyright 2022 Alexander Matthes, Bernhard Manfred Gruber
2 // SPDX-License-Identifier: MPL-2.0
3 
4 #pragma once
5 
6 #include "Meta.hpp"
7 #include "macros.hpp"
8 
9 #include <array>
10 #include <ostream>
11 #include <type_traits>
12 
13 namespace llama
14 {
18  template<std::size_t... Coords>
19  struct RecordCoord
20  {
22  using List = mp_list_c<std::size_t, Coords...>;
23 
24  static constexpr std::size_t front = mp_front<List>::value;
25  static constexpr std::size_t back = mp_back<List>::value;
26  static constexpr std::size_t size = sizeof...(Coords);
27  };
28 
30  template<>
31  struct RecordCoord<>
32  {
33  using List = mp_list_c<std::size_t>;
34 
35  static constexpr std::size_t size = 0;
36  };
37 
39  template<std::size_t... CoordsA, std::size_t... CoordsB>
41  {
42  return false;
43  }
44 
46  template<std::size_t... Coords>
48  {
49  return true;
50  }
51 
53  template<std::size_t... CoordsA, std::size_t... CoordsB>
55  {
56  return !(a == b);
57  }
58 
60  template<typename T>
61  inline constexpr bool isRecordCoord = false;
62 
64  template<std::size_t... Coords>
65  inline constexpr bool isRecordCoord<RecordCoord<Coords...>> = true;
66 
68  template<std::size_t... RCs>
69  auto operator<<(std::ostream& os, RecordCoord<RCs...>) -> std::ostream&
70  {
71  os << "RecordCoord<";
72  bool first = true;
73  for(auto rc : std::array<std::size_t, sizeof...(RCs)>{RCs...})
74  {
75  if(first)
76  first = false;
77  else
78  os << ", ";
79  os << rc;
80  }
81  os << ">";
82  return os;
83  }
84 
85  inline namespace literals
86  {
89  template<char... Digits>
90  constexpr auto operator"" _RC()
91  {
92  constexpr auto coord = []() constexpr
93  {
94  const char digits[] = {(Digits - 48)...};
95  std::size_t acc = 0;
96  std ::size_t powerOf10 = 1;
97  for(int i = sizeof...(Digits) - 1; i >= 0; i--)
98  {
99  acc += digits[i] * powerOf10;
100  powerOf10 *= 10;
101  }
102  return acc;
103  }();
104  return RecordCoord<coord>{};
105  }
106  } // namespace literals
107 
110  template<typename L>
112 
115  template<typename... RecordCoords>
116  using Cat = RecordCoordFromList<mp_append<typename RecordCoords::List...>>;
117 
120  template<typename... RecordCoords>
121  LLAMA_FN_HOST_ACC_INLINE constexpr auto cat(RecordCoords...)
122  {
123  return Cat<RecordCoords...>{};
124  }
125 
128  template<typename RecordCoord>
130 
131  namespace internal
132  {
133  template<std::size_t... Coords1, std::size_t... Coords2>
135  {
136  // CTAD does not work if Coords1/2 is an empty pack
137  std::array<std::size_t, sizeof...(Coords1)> a1{Coords1...};
138  std::array<std::size_t, sizeof...(Coords2)> a2{Coords2...};
139  for(std::size_t i = 0; i < std::min(a1.size(), a2.size()); i++)
140  {
141  if(a1[i] > a2[i])
142  return true;
143  if(a1[i] < a2[i])
144  return false;
145  }
146  return false;
147  };
148  } // namespace internal
149 
152  template<typename First, typename Second>
153  inline constexpr auto recordCoordCommonPrefixIsBigger
155 
156  namespace internal
157  {
158  template<std::size_t... Coords1, std::size_t... Coords2>
160  {
161  // CTAD does not work if Coords1/2 is an empty pack
162  std::array<std::size_t, sizeof...(Coords1)> a1{Coords1...};
163  std::array<std::size_t, sizeof...(Coords2)> a2{Coords2...};
164  for(std::size_t i = 0; i < std::min(a1.size(), a2.size()); i++)
165  if(a1[i] != a2[i])
166  return false;
167  return true;
168  };
169  } // namespace internal
170 
173  template<typename First, typename Second>
174  inline constexpr auto recordCoordCommonPrefixIsSame
175  = internal::recordCoordCommonPrefixIsSameImpl(First{}, Second{});
176 } // namespace llama
#define LLAMA_EXPORT
Definition: macros.hpp:192
#define LLAMA_FN_HOST_ACC_INLINE
Definition: macros.hpp:96
constexpr auto recordCoordCommonPrefixIsBiggerImpl(RecordCoord< Coords1... >, RecordCoord< Coords2... >) -> bool
constexpr auto recordCoordCommonPrefixIsSameImpl(RecordCoord< Coords1... >, RecordCoord< Coords2... >) -> bool
typename mp_unwrap_values_into_impl< FromList, ToList >::type mp_unwrap_values_into
Definition: Meta.hpp:36
constexpr auto cat(RecordCoords...)
Concatenate a set of RecordCoords instances.
constexpr auto operator==(ArrayIndex< TA, Dim > a, ArrayIndex< TB, Dim > b) -> bool
constexpr auto recordCoordCommonPrefixIsSame
Checks whether two RecordCoords are the same or one is the prefix of the other.
RecordCoordFromList< mp_pop_front< typename RecordCoord::List > > PopFront
RecordCoord without first coordinate component.
constexpr bool isRecordCoord
Definition: RecordCoord.hpp:61
auto operator<<(std::ostream &os, const Array< T, N > &a) -> std::ostream &
Definition: Array.hpp:249
constexpr auto recordCoordCommonPrefixIsBigger
Checks wether the first RecordCoord is bigger than the second.
constexpr auto operator!=(ArrayIndex< TA, Dim > a, ArrayIndex< TB, Dim > b) -> bool
RecordCoordFromList< mp_append< typename RecordCoords::List... > > Cat
Concatenate a set of RecordCoords.
internal::mp_unwrap_values_into< L, RecordCoord > RecordCoordFromList
Converts a type list of integral constants into a RecordCoord.
mp_list_c< std::size_t > List
Definition: RecordCoord.hpp:33
static constexpr std::size_t size
Definition: RecordCoord.hpp:26
static constexpr std::size_t back
Definition: RecordCoord.hpp:25
mp_list_c< std::size_t, Coords... > List
The list of integral coordinates as mp_list.
Definition: RecordCoord.hpp:22
static constexpr std::size_t front
Definition: RecordCoord.hpp:24