ATLAS Offline Software
Loading...
Searching...
No Matches
vec_fb.h
Go to the documentation of this file.
1// This file's extension implies that it's C, but it's really -*- C++ -*-.
2/*
3 * Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration.
4 */
15
16#ifndef CXXUTILS_VEC_FB_H
17#define CXXUTILS_VEC_FB_H
18
19#include <initializer_list>
20#include <type_traits>
21#include <algorithm>
22#include <cstdint>
23
24#include "boost/integer.hpp"
25
26namespace CxxUtils {
29template<typename T, size_t N>
30struct alignas(N*sizeof(T)) vec_fb
31{
32 static_assert(std::is_arithmetic_v<T>, "Element type is not arithmetic");
33 static_assert(N > 0 && (N & (N - 1)) == 0, "Size not a power or 2");
34 // cppcheck-suppress uninitMemberVar; deliberate
35 vec_fb() = default;
36 vec_fb(const vec_fb&) = default;
37 vec_fb& operator=(const vec_fb&) = default;
38 vec_fb(std::initializer_list<T> init)
39 {
40 std::copy(init.begin(), init.end(), m_arr);
41 std::fill(m_arr + init.size(), m_arr + N, T());
42 }
43
44 T operator[](size_t n) const { return m_arr[n]; }
45 T& operator[](size_t n) { return m_arr[n]; }
46
47 T m_arr[N];
48};
49
50// Helper: Given a vectorized class, find another vectorized class
51// that uses integers of the same size as the original class.
52template <typename T, size_t N>
53using ivec = vec_fb<typename boost::int_t<sizeof(T) * 8>::exact, N>;
54
55// Define binary operations.
56// For each operation, define
57// V1 OP V2
58// V OP S
59// S OP V
60// V1 OP= V2
61// V OP= S
62
63#define BINOP(op) \
64 template<typename T, size_t N> \
65 inline vec_fb<T, N> operator op(const vec_fb<T, N>& a, \
66 const vec_fb<T, N>& b) \
67 { \
68 vec_fb<T, N> c; \
69 for (size_t i = 0; i < N; ++i) \
70 c.m_arr[i] = a.m_arr[i] op b.m_arr[i]; \
71 return c; \
72 } \
73 template<typename T, size_t N, typename U> \
74 inline vec_fb<T, N> operator op(const vec_fb<T, N>& a, U b) \
75 { \
76 vec_fb<T, N> c; \
77 for (size_t i = 0; i < N; ++i) \
78 c.m_arr[i] = a.m_arr[i] op b; \
79 return c; \
80 } \
81 template<typename T, size_t N, typename U> \
82 inline vec_fb<T, N> operator op(U a, const vec_fb<T, N>& b) \
83 { \
84 vec_fb<T, N> c; \
85 for (size_t i = 0; i < N; ++i) \
86 c.m_arr[i] = a op b.m_arr[i]; \
87 return c; \
88 } \
89 template<typename T, size_t N> \
90 inline vec_fb<T, N>& operator op##=(vec_fb<T, N>& a, const vec_fb<T, N>& b) \
91 { \
92 for (size_t i = 0; i < N; ++i) \
93 a.m_arr[i] op## = b.m_arr[i]; \
94 return a; \
95 } \
96 template<typename T, size_t N, typename U> \
97 inline vec_fb<T, N>& operator op##=(vec_fb<T, N>& a, U b) \
98 { \
99 for (size_t i = 0; i < N; ++i) \
100 a.m_arr[i] op## = b; \
101 return a; \
102 }
103
104BINOP(+)
105BINOP(-)
106BINOP(*)
107BINOP(/)
108BINOP(^)
109BINOP(|)
110BINOP(&)
111BINOP(%)
112BINOP(>>)
113BINOP(<<)
114
115#undef BINOP
116
117// Define unary operations.
118
119#define UNOP(op) \
120 template<typename T, size_t N> \
121 inline vec_fb<T, N> operator op(const vec_fb<T, N>& a) \
122 { \
123 vec_fb<T, N> c; \
124 for (size_t i = 0; i < N; ++i) \
125 c.m_arr[i] = op a.m_arr[i]; \
126 return c; \
127 }
128
129UNOP(-)
130UNOP(~)
131
132#undef UNOP
133
134// Define relational operations.
135
136#define RELOP(op) \
137 template<typename T, size_t N> \
138 inline ivec<T, N> operator op(const vec_fb<T, N>& a, const vec_fb<T, N>& b) \
139 { \
140 ivec<T, N> c; \
141 for (size_t i = 0; i < N; ++i) \
142 c.m_arr[i] = a.m_arr[i] op b.m_arr[i]; \
143 return c; \
144 }
145
146RELOP(==)
147RELOP(!=)
148RELOP(<)
149RELOP(<=)
150RELOP(>)
151RELOP(>=)
152
153#undef RELOP
154
156template<typename T, size_t N>
157inline ivec<T, N>
159{
160 ivec<T, N> c;
161 for (size_t i = 0; i < N; ++i)
162 c.m_arr[i] = a.m_arr[i] == 0;
163 return c;
164}
165
167template<typename T, size_t N>
168inline ivec<T, N>
170{
171 ivec<T, N> c;
172 for (size_t i = 0; i < N; ++i)
173 c.m_arr[i] = (a.m_arr[i] != 0) & (b.m_arr[i] != 0);
174 return c;
175}
176
178template<typename T, size_t N, class U>
179inline ivec<T, N>
181{
182 ivec<T, N> c;
183 for (size_t i = 0; i < N; ++i)
184 c.m_arr[i] = a ? b.m_arr[i] != 0 : 0;
185 return c;
186}
187
189template<typename T, size_t N, class U>
190inline ivec<T, N>
192{
193 ivec<T, N> c;
194 for (size_t i = 0; i < N; ++i)
195 c.m_arr[i] = (a.m_arr[i] != 0) & (b ? -1 : 0);
196 return c;
197}
198
200template<typename T, size_t N>
201inline ivec<T, N>
203{
204 ivec<T, N> c;
205 for (size_t i = 0; i < N; ++i)
206 c.m_arr[i] = (a.m_arr[i] != 0) | (b.m_arr[i] != 0);
207 return c;
208}
209
210} // namespace CxxUtils
211
212#endif // CXXUTILS_VEC_FB_H
static Double_t a
ivec< T, N > operator||(const vec_fb< T, N > &a, const vec_fb< T, N > &b)
V1 || V2.
Definition vec_fb.h:202
vec_fb< typename boost::int_t< sizeof(T) *8 >::exact, N > ivec
Definition vec_fb.h:53
ivec< T, N > operator!(const vec_fb< T, N > &a)
Negation.
Definition vec_fb.h:158
ivec< T, N > operator&&(const vec_fb< T, N > &a, const vec_fb< T, N > &b)
V1 && V2.
Definition vec_fb.h:169
vec_fb & operator=(const vec_fb &)=default
T operator[](size_t n) const
Definition vec_fb.h:44
vec_fb(std::initializer_list< T > init)
Definition vec_fb.h:38
vec_fb()=default
T & operator[](size_t n)
Definition vec_fb.h:45
vec_fb(const vec_fb &)=default
#define RELOP(op)
Definition vec_fb.h:136
#define UNOP(op)
Definition vec_fb.h:119
#define BINOP(op)
Definition vec_fb.h:63