13#include <Kokkos_Macros.hpp>
15#include "detail/macros.hpp"
16#include "detail/type_seq.hpp"
17#include "detail/utils.hpp"
19#include "discrete_vector.hpp"
31template <
class... Tags>
42template <
class... Tags>
43struct ToTypeSeq<DiscreteElement<Tags...>>
45 using type = TypeSeq<Tags...>;
51
52using DiscreteElementType = std::size_t;
55KOKKOS_FUNCTION constexpr DiscreteElementType
const&
uid(DiscreteElement<Tag>
const& tuple)
noexcept
61KOKKOS_FUNCTION constexpr DiscreteElementType&
uid(DiscreteElement<Tag>& tuple)
noexcept
66template <
class QueryTag,
class... Tags>
68 DiscreteElement<Tags...>
const& tuple)
noexcept
70 return tuple.
template uid<QueryTag>();
73template <
class QueryTag,
class... Tags>
74KOKKOS_FUNCTION constexpr DiscreteElementType&
uid(DiscreteElement<Tags...>& tuple)
noexcept
76 return tuple.
template uid<QueryTag>();
79template <
class QueryTag,
class... Tags>
81 DiscreteElement<Tags...>
const& arr,
82 DiscreteElement<QueryTag>
const& default_value)
noexcept
84 if constexpr (in_tags_v<QueryTag, detail::TypeSeq<Tags...>>) {
85 return DiscreteElement<QueryTag>(arr);
91template <
class... QueryTags,
class... Tags>
93 DiscreteElement<Tags...>
const& arr)
noexcept
95 return DiscreteElement<QueryTags...>(arr);
98template <
class... QueryTags,
class... Tags>
100 DiscreteElement<Tags...>&& arr)
noexcept
102 return DiscreteElement<QueryTags...>(std::move(arr));
111 is_discrete_element_v<HeadDElem> && (is_discrete_element_v<TailDElems> && ...),
114KOKKOS_FUNCTION constexpr auto const&
take(HeadDElem
const& head, TailDElems
const&... tail)
116 DDC_IF_NVCC_THEN_PUSH_AND_SUPPRESS(implicit_return_from_non_void_function)
117 if constexpr (type_seq_contains_v<detail::TypeSeq<QueryTag>, to_type_seq_t<HeadDElem>>) {
119 (!type_seq_contains_v<detail::TypeSeq<QueryTag>, to_type_seq_t<TailDElems>> && ...),
120 "ERROR: tag redundant");
123 static_assert(
sizeof...(TailDElems) > 0,
"ERROR: tag not found");
124 return take<QueryTag>(tail...);
132template <
class... Tags>
133KOKKOS_FUNCTION
constexpr std::array<DiscreteElementType,
sizeof...(Tags)>& array(
134 DiscreteElement<Tags...>& v)
noexcept
140template <
class... Tags>
141KOKKOS_FUNCTION
constexpr std::array<DiscreteElementType,
sizeof...(Tags)>
const& array(
142 DiscreteElement<Tags...>
const& v)
noexcept
152 return DiscreteElement<DDim>(0);
156
157
158
159template <
class... Tags>
162 using tags_seq = detail::TypeSeq<Tags...>;
165 type_seq_is_unique_v<tags_seq>,
166 "The dimensions of a DiscreteElement must be unique");
168 friend KOKKOS_FUNCTION
constexpr std::array<DiscreteElementType,
sizeof...(Tags)>& detail::
169 array<Tags...>(DiscreteElement<Tags...>& v)
noexcept;
171 friend KOKKOS_FUNCTION
constexpr std::array<DiscreteElementType,
sizeof...(Tags)>
const&
172 detail::array<Tags...>(DiscreteElement<Tags...>
const& v)
noexcept;
175 std::array<DiscreteElementType,
sizeof...(Tags)> m_values;
178 using value_type = DiscreteElementType;
182 return sizeof...(Tags);
188 KOKKOS_DEFAULTED_FUNCTION
constexpr DiscreteElement(DiscreteElement
const&) =
default;
190 KOKKOS_DEFAULTED_FUNCTION
constexpr DiscreteElement(DiscreteElement&&) =
default;
192 template <
class... DElems,
class = std::enable_if_t<(is_discrete_element_v<DElems> && ...)>>
194 : m_values {take<Tags>(delems...).
template uid<Tags>()...}
200 class = std::enable_if_t<std::is_convertible_v<IntegerType, DiscreteElementType>>>
202 std::array<IntegerType,
sizeof...(Tags)>
const& values)
noexcept
204 detail::convert_array_to<
205 DiscreteElementType>(values, std::make_index_sequence<
sizeof...(Tags)>()))
211 class = std::enable_if_t<(!is_discrete_element_v<Params> && ...)>,
212 class = std::enable_if_t<(std::is_convertible_v<Params, DiscreteElementType> && ...)>,
213 class = std::enable_if_t<
sizeof...(Params) ==
sizeof...(Tags)>>
215 : m_values {
static_cast<DiscreteElementType>(params)...}
221 KOKKOS_DEFAULTED_FUNCTION DiscreteElement&
operator=(DiscreteElement
const& other) =
default;
223 KOKKOS_DEFAULTED_FUNCTION DiscreteElement&
operator=(DiscreteElement&& other) =
default;
225 template <
class QueryTag>
228 static_assert(in_tags_v<QueryTag, tags_seq>,
"requested Tag absent from DiscreteElement");
229 return m_values[type_seq_rank_v<QueryTag, tags_seq>];
232 template <
class QueryTag>
235 static_assert(in_tags_v<QueryTag, tags_seq>,
"requested Tag absent from DiscreteElement");
236 return m_values[type_seq_rank_v<QueryTag, tags_seq>];
239 template <std::size_t N =
sizeof...(Tags)>
245 template <std::size_t N =
sizeof...(Tags)>
246 KOKKOS_FUNCTION constexpr std::enable_if_t<N == 1, value_type
const&>
uid()
const noexcept
251 template <std::size_t N =
sizeof...(Tags),
class = std::enable_if_t<N == 1>>
258 template <std::size_t N =
sizeof...(Tags),
class = std::enable_if_t<N == 1>>
261 DiscreteElement
const tmp = *
this;
266 template <std::size_t N =
sizeof...(Tags),
class = std::enable_if_t<N == 1>>
273 template <std::size_t N =
sizeof...(Tags),
class = std::enable_if_t<N == 1>>
276 DiscreteElement
const tmp = *
this;
281 template <
class... OTags>
284 static_assert(((type_seq_contains_v<detail::TypeSeq<OTags>, tags_seq>) && ...));
285 ((m_values[type_seq_rank_v<OTags, tags_seq>] += rhs.
template get<OTags>()), ...);
291 std::size_t N =
sizeof...(Tags),
292 class = std::enable_if_t<N == 1>,
293 class = std::enable_if_t<std::is_integral_v<IntegralType>>>
300 template <
class... OTags>
303 static_assert(((type_seq_contains_v<detail::TypeSeq<OTags>, tags_seq>) && ...));
304 ((m_values[type_seq_rank_v<OTags, tags_seq>] -= rhs.
template get<OTags>()), ...);
310 std::size_t N =
sizeof...(Tags),
311 class = std::enable_if_t<N == 1>,
312 class = std::enable_if_t<std::is_integral_v<IntegralType>>>
320inline std::ostream& operator<<(std::ostream& out, DiscreteElement<>
const&)
326template <
class Head,
class... Tags>
327std::ostream& operator<<(std::ostream& out, DiscreteElement<Head, Tags...>
const& arr)
330 out << uid<Head>(arr);
331 ((out <<
", " << uid<Tags>(arr)), ...);
337template <
class... Tags,
class... OTags>
339 DiscreteElement<Tags...>
const& lhs,
340 DiscreteElement<OTags...>
const& rhs)
noexcept
342 return ((lhs.
template uid<Tags>() == rhs.
template uid<Tags>()) && ...);
345#if !defined(__cpp_impl_three_way_comparison) || __cpp_impl_three_way_comparison < 201902L
358 DiscreteElement<Tag>
const& lhs,
359 DiscreteElement<Tag>
const& rhs)
361 return lhs.uid() < rhs.uid();
366 DiscreteElement<Tag>
const& lhs,
367 DiscreteElement<Tag>
const& rhs)
369 return lhs.uid() <= rhs.uid();
374 DiscreteElement<Tag>
const& lhs,
375 DiscreteElement<Tag>
const& rhs)
377 return lhs.uid() > rhs.uid();
382 DiscreteElement<Tag>
const& lhs,
383 DiscreteElement<Tag>
const& rhs)
385 return lhs.uid() >= rhs.uid();
390template <
class... Tags,
class... OTags>
392 DiscreteElement<Tags...>
const& lhs,
395 using detail::TypeSeq;
396 static_assert(((type_seq_contains_v<TypeSeq<OTags>, TypeSeq<Tags...>>) && ...));
397 DiscreteElement<Tags...> result(lhs);
405 class = std::enable_if_t<std::is_integral_v<IntegralType>>,
406 class = std::enable_if_t<!is_discrete_vector_v<IntegralType>>>
408 DiscreteElement<Tag>
const& lhs,
409 IntegralType
const& rhs)
411 DiscreteElement<Tag> result(lhs);
416template <
class... Tags,
class... OTags>
418 DiscreteElement<Tags...>
const& lhs,
421 using detail::TypeSeq;
422 static_assert(((type_seq_contains_v<TypeSeq<OTags>, TypeSeq<Tags...>>) && ...));
423 DiscreteElement<Tags...> result(lhs);
431 class = std::enable_if_t<std::is_integral_v<IntegralType>>,
432 class = std::enable_if_t<!is_discrete_vector_v<IntegralType>>>
434 DiscreteElement<Tag>
const& lhs,
435 IntegralType
const& rhs)
437 DiscreteElement<Tag> result(lhs);
444template <
class... Tags,
class... OTags>
446 DiscreteElement<Tags...>
const& lhs,
447 DiscreteElement<OTags...>
const& rhs)
449 static_assert(type_seq_same_v<detail::TypeSeq<Tags...>, detail::TypeSeq<OTags...>>);
450 return DiscreteVector<Tags...>((uid<Tags>(lhs) - uid<Tags>(rhs))...);
KOKKOS_FUNCTION constexpr DiscreteElement & operator+=(DiscreteVector< OTags... > const &rhs)
KOKKOS_FUNCTION constexpr value_type const & uid() const noexcept
KOKKOS_FUNCTION constexpr value_type & uid() noexcept
KOKKOS_DEFAULTED_FUNCTION ~DiscreteElement()=default
KOKKOS_FUNCTION constexpr DiscreteElement(std::array< IntegerType, sizeof...(Tags)> const &values) noexcept
KOKKOS_FUNCTION constexpr DiscreteElement & operator++()
KOKKOS_FUNCTION constexpr DiscreteElement & operator-=(IntegralType const &rhs)
KOKKOS_DEFAULTED_FUNCTION constexpr DiscreteElement(DiscreteElement const &)=default
KOKKOS_FUNCTION constexpr DiscreteElement(DElems const &... delems) noexcept
KOKKOS_FUNCTION constexpr DiscreteElement & operator-=(DiscreteVector< OTags... > const &rhs)
KOKKOS_FUNCTION constexpr DiscreteElement operator++(int)
KOKKOS_DEFAULTED_FUNCTION constexpr DiscreteElement()=default
KOKKOS_FUNCTION constexpr DiscreteElement & operator--()
KOKKOS_DEFAULTED_FUNCTION DiscreteElement & operator=(DiscreteElement const &other)=default
KOKKOS_FUNCTION constexpr DiscreteElement operator--(int)
KOKKOS_FUNCTION constexpr std::enable_if_t< N==1, value_type & > uid() noexcept
static KOKKOS_FUNCTION constexpr std::size_t size() noexcept
KOKKOS_FUNCTION constexpr std::enable_if_t< N==1, value_type const & > uid() const noexcept
KOKKOS_FUNCTION constexpr DiscreteElement & operator+=(IntegralType const &rhs)
KOKKOS_DEFAULTED_FUNCTION DiscreteElement & operator=(DiscreteElement &&other)=default
KOKKOS_FUNCTION constexpr DiscreteElement(Params const &... params) noexcept
KOKKOS_DEFAULTED_FUNCTION constexpr DiscreteElement(DiscreteElement &&)=default
KOKKOS_FUNCTION constexpr bool operator!=(DiscreteVector< OTags... > const &rhs) const noexcept
The top-level namespace of DDC.
KOKKOS_FUNCTION constexpr bool operator<(DiscreteElement< Tag > const &lhs, DiscreteElement< Tag > const &rhs)
KOKKOS_FUNCTION constexpr bool operator==(DiscreteElement< Tags... > const &lhs, DiscreteElement< OTags... > const &rhs) noexcept
KOKKOS_FUNCTION constexpr DiscreteElement< QueryTags... > select(DiscreteElement< Tags... > &&arr) noexcept
constexpr DiscreteElement< DDim > create_reference_discrete_element() noexcept
KOKKOS_FUNCTION constexpr DiscreteElement< QueryTags... > select(DiscreteElement< Tags... > const &arr) noexcept
KOKKOS_FUNCTION constexpr auto const & take(HeadDElem const &head, TailDElems const &... tail)
Returns a reference towards the DiscreteElement that contains the QueryTag.
KOKKOS_FUNCTION constexpr DiscreteElement< Tag > operator-(DiscreteElement< Tag > const &lhs, IntegralType const &rhs)
KOKKOS_FUNCTION constexpr DiscreteVector< Tags... > operator-(DiscreteElement< Tags... > const &lhs, DiscreteElement< OTags... > const &rhs)
binary operator: -
KOKKOS_FUNCTION constexpr DiscreteElement< QueryTag > select_or(DiscreteElement< Tags... > const &arr, DiscreteElement< QueryTag > const &default_value) noexcept
KOKKOS_FUNCTION constexpr DiscreteElementType const & uid(DiscreteElement< Tag > const &tuple) noexcept
KOKKOS_FUNCTION constexpr DiscreteElement< Tags... > operator+(DiscreteElement< Tags... > const &lhs, DiscreteVector< OTags... > const &rhs)
right external binary operators: +, -
constexpr bool is_discrete_element_v
KOKKOS_FUNCTION constexpr bool operator>=(DiscreteElement< Tag > const &lhs, DiscreteElement< Tag > const &rhs)
KOKKOS_FUNCTION constexpr bool operator<=(DiscreteElement< Tag > const &lhs, DiscreteElement< Tag > const &rhs)
KOKKOS_FUNCTION constexpr DiscreteElementType & uid(DiscreteElement< Tags... > &tuple) noexcept
KOKKOS_FUNCTION constexpr bool operator>(DiscreteElement< Tag > const &lhs, DiscreteElement< Tag > const &rhs)
KOKKOS_FUNCTION constexpr DiscreteElement< Tag > operator+(DiscreteElement< Tag > const &lhs, IntegralType const &rhs)
KOKKOS_FUNCTION constexpr DiscreteElementType & uid(DiscreteElement< Tag > &tuple) noexcept
KOKKOS_FUNCTION constexpr DiscreteElement< Tags... > operator-(DiscreteElement< Tags... > const &lhs, DiscreteVector< OTags... > const &rhs)
KOKKOS_FUNCTION constexpr DiscreteElementType const & uid(DiscreteElement< Tags... > const &tuple) noexcept