11#if defined(__GNUC__) && !defined(__clang__)
12#pragma GCC diagnostic warning "-Wdeprecated-declarations"
16#include "detray/algebra/common/array_operators.hpp"
17#include "detray/algebra/concepts.hpp"
18#include "detray/definitions/detail/qualifiers.hpp"
23#include <initializer_list>
27namespace detray::algebra {
36consteval std::size_t nearest_power_of_two(std::size_t min_value,
37 std::size_t current_value) {
40 return min_value <= current_value
42 : nearest_power_of_two(min_value, current_value * 2u);
49template <std::size_t N, concepts::scalar scalar_t,
50 template <
typename, std::
size_t>
class array_t>
52 alignof(array_t<scalar_t, detail::nearest_power_of_two(N, 2u)>))
vector {
69 zero_fill(std::make_index_sequence<
simd_size()>{});
79 template <
typename... Scalars>
82 std::convertible_to<Scalars, scalar_t>) &&
87 DETRAY_HOST_DEVICE constexpr
vector(Scalars &&...scals)
88 :
m_data{std::forward<Scalars>(scals)...} {}
96 template <
typename... Values>
99 std::convertible_to<Values, scalar_t>) &&
102 DETRAY_HOST_DEVICE constexpr
vector(Values &&...vals) {
103 static_assert(
sizeof...(Values) <= N);
107 m_data = {std::forward<Values>(vals)..., 0.f};
108 }
else if constexpr ((
simd_size() - N) == 2) {
109 m_data = {std::forward<Values>(vals)..., 0.f, 0.f};
110 }
else if constexpr (
sizeof...(Values) <
simd_size()) {
112 zero_fill(std::make_index_sequence<
simd_size() -
sizeof...(Values)>{});
114 m_data = {std::forward<Values>(vals)...};
140 template <std::
size_t M>
143 DETRAY_HOST_DEVICE
constexpr const vector &
operator=(
172 constexpr decltype(
auto)
operator[](std::size_t i) {
return m_data[i]; }
176 constexpr decltype(
auto)
operator[](std::size_t i)
const {
return m_data[i]; }
184 constexpr decltype(
auto)
operator*=(
scalar_type factor)
noexcept {
191 template <concepts::scalar S = scalar_t>
193 DETRAY_HOST_DEVICE
constexpr friend bool operator==(
195 const auto comp = lhs.
compare(rhs);
199 for (
unsigned int i{0u}; i < N; ++i) {
200 is_full = is_full && comp[i];
207 template <concepts::scalar S = scalar_t>
209 DETRAY_HOST_DEVICE
constexpr friend bool operator==(
211 const auto comp = lhs.
compare(rhs);
215 for (
unsigned int i{0u}; i < N; ++i) {
217 is_full = is_full && comp[i].isFull();
227 template <
typename other_t>
229 const other_t &rhs)
const noexcept {
230 return ((*
this == rhs) ==
false);
236 template <
typename other_t>
237 DETRAY_HOST_DEVICE
constexpr auto compare(
const other_t &rhs)
const noexcept {
238 using result_t =
decltype(
m_data[0] == rhs[0]);
240 std::array<result_t, N> comp;
243 for (
unsigned int i{0u}; i < N; ++i) {
244 comp[i] = (
m_data[i] == rhs[i]);
255 template <std::size_t... Is>
256 DETRAY_HOST_DEVICE
constexpr void zero_fill(
257 std::index_sequence<Is...> )
noexcept {
258 ((
m_data[
simd_size() -
sizeof...(Is) + Is] =
static_cast<scalar_t
>(0)),
264#define DECLARE_VECTOR_OPERATORS(OP) \
265 template <std::size_t N, concepts::scalar scalar_t, concepts::value value_t, \
266 template <typename, std::size_t> class array_t> \
267 DETRAY_HOST_DEVICE constexpr decltype(auto) operator OP( \
268 const vector<N, scalar_t, array_t> &lhs, value_t rhs) noexcept { \
269 return lhs.m_data OP static_cast<scalar_t>(rhs); \
271 template <std::size_t N, concepts::scalar scalar_t, concepts::value value_t, \
272 template <typename, std::size_t> class array_t> \
273 DETRAY_HOST_DEVICE constexpr decltype(auto) operator OP( \
274 value_t lhs, const vector<N, scalar_t, array_t> &rhs) noexcept { \
275 return static_cast<scalar_t>(lhs) OP rhs.m_data; \
277 template <std::size_t N, concepts::scalar scalar_t, \
278 template <typename, std::size_t> class array_t> \
279 DETRAY_HOST_DEVICE constexpr decltype(auto) operator OP( \
280 const vector<N, scalar_t, array_t> &lhs, \
281 const vector<N, scalar_t, array_t> &rhs) noexcept { \
282 return lhs.m_data OP rhs.m_data; \
284 template <std::size_t N, concepts::scalar scalar_t, \
285 template <typename, std::size_t> class array_t, typename other_t> \
286 requires(concepts::vector<other_t> || concepts::simd_scalar<other_t>) \
287 DETRAY_HOST_DEVICE constexpr decltype(auto) operator OP( \
288 const vector<N, scalar_t, array_t> &lhs, const other_t &rhs) noexcept { \
289 return lhs.m_data OP rhs; \
291 template <std::size_t N, concepts::scalar scalar_t, \
292 template <typename, std::size_t> class array_t, typename other_t> \
293 requires(concepts::vector<other_t> || concepts::simd_scalar<other_t>) \
294 DETRAY_HOST_DEVICE constexpr decltype(auto) operator OP( \
295 const other_t &lhs, const vector<N, scalar_t, array_t> &rhs) noexcept { \
296 return lhs OP rhs.m_data; \
301DECLARE_VECTOR_OPERATORS(+)
302DECLARE_VECTOR_OPERATORS(-)
303DECLARE_VECTOR_OPERATORS(*)
304DECLARE_VECTOR_OPERATORS(/)
308#undef DECLARE_VECTOR_OPERATORS
318 template <
typename, std::
size_t>
class array_t>
320 :
public std::true_type {};
Vector wrapper for AoS vs interleaved SoA data.
Definition vector.hpp:52
constexpr const auto & get() const
Return the underlying storage array.
Definition vector.hpp:165
static consteval std::size_t simd_size()
Definition vector.hpp:56
constexpr vector()
Default constructor sets all entries to zero.
Definition vector.hpp:67
constexpr auto compare(const other_t &rhs) const noexcept
Elementwise comparison.
Definition vector.hpp:237
array_t< scalar_t, simd_size()> array_type
Definition vector.hpp:63
array_t< scalar_t, simd_size()> m_data
Definition vector.hpp:251
constexpr vector(const array_type &vals)
Definition vector.hpp:133
constexpr vector(array_type &&vals)
Construct from existing array storage vals.
Definition vector.hpp:128
constexpr bool operator!=(const other_t &rhs) const noexcept
Inequality operator.
Definition vector.hpp:228
scalar_t scalar_type
Definition vector.hpp:61
Scalar concept: Elements of vectors/matrices (can be simd vectors).
Definition concepts.hpp:40
Check if a scalar is simd.
Definition concepts.hpp:50
Definition concepts.hpp:32
Definition vector.hpp:315