3#ifndef DUNE_DEBUGALIGN_HH
4#define DUNE_DEBUGALIGN_HH
19#include <dune/common/simd.hh>
25 std::function<void(
const char*, std::size_t,
const void*)>;
50 inline bool isAligned(
const void *p, std::size_t align)
54 return std::uintptr_t(p) % align == 0;
58 template<std::
size_t align,
class Impl>
61 void checkAlignment()
const
63 auto pimpl =
static_cast<const Impl*
>(
this);
80 namespace AlignedNumberImpl {
82 template<
class T, std::
size_t align = debugAlignment>
87 using AlignedNumberImpl::AlignedNumber;
90 template<std::
size_t align = debugAlignment,
class T>
99 namespace AlignedNumberImpl {
102 template<
class T, std::
size_t align>
104 :
public AlignedBase<align, AlignedNumber<T, align> >
111 template<
class U, std::size_t uAlign,
112 class = std::enable_if_t<(align >= uAlign) &&
113 std::is_convertible<U, T>::value> >
117 class = std::enable_if_t<std::is_convertible<T, U>::value> >
118 explicit operator U()
const {
return value_; }
121 template<
class charT,
class Traits>
122 friend std::basic_istream<charT, Traits>&
125 return str >> u.value_;
128 template<
class charT,
class Traits>
129 friend std::basic_ostream<charT, Traits>&
130 operator<<(std::basic_ostream<charT, Traits>& str,
133 return str << u.value_;
145 template<class U = T, class = void_t<decltype(++std::declval<U&>())> >
148 template<
class U = T,
class =
void_t<
decltype(--std::declval<U&>())> >
151 template<class U = T, class = void_t<decltype(std::declval<U&>()++)> >
152 decltype(
auto) operator++(
int) {
return aligned<align>(value_++); }
154 template<class U = T, class = void_t<decltype(std::declval<U&>()--)> >
155 decltype(
auto) operator--(
int) {
return aligned<align>(value_--); }
158 template<
class U = T,
160 decltype(
auto) operator+()
const {
return aligned<align>(+value_); }
162 template<
class U = T,
163 class =
void_t<
decltype(-std::declval<const U&>())> >
164 decltype(
auto) operator-()
const {
return aligned<align>(-value_); }
166 template<
class U = T,
168 decltype(
auto) operator~()
const {
return aligned<align>(~value_); }
170 template<
class U = T,
172 decltype(
auto) operator!()
const {
return aligned<align>(!value_); }
175#define DUNE_ASSIGN_OP(OP) \
176 template<class U, std::size_t uAlign, \
177 class = std::enable_if_t< \
178 ( uAlign <= align && \
179 sizeof(std::declval<T&>() OP std::declval<U>()) ) \
181 AlignedNumber &operator OP(const AlignedNumber<U, uAlign> &u) \
188 class = void_t<decltype(std::declval<T&>() OP \
189 std::declval<U>())> > \
190 AlignedNumber &operator OP(const U &u) \
196 static_assert(true, "Require semicolon to unconfuse editors")
216#define DUNE_BINARY_OP(OP) \
217 template<class T, std::size_t tAlign, class U, std::size_t uAlign, \
218 class = void_t<decltype(std::declval<T>() \
219 OP std::declval<U>())> > \
221 operator OP(const AlignedNumber<T, tAlign> &t, \
222 const AlignedNumber<U, uAlign> &u) \
225 return aligned<(tAlign > uAlign ? tAlign : uAlign)>(T(t) OP U(u)); \
228 template<class T, class U, std::size_t uAlign, \
229 class = void_t<decltype(std::declval<T>() \
230 OP std::declval<U>())> > \
232 operator OP(const T &t, const AlignedNumber<U, uAlign> &u) \
234 return aligned<uAlign>(t OP U(u)); \
237 template<class T, std::size_t tAlign, class U, \
238 class = void_t<decltype(std::declval<T>() \
239 OP std::declval<U>())> > \
241 operator OP(const AlignedNumber<T, tAlign> &t, const U &u) \
243 return aligned<tAlign>(T(t) OP u); \
246 static_assert(true, "Require semicolon to unconfuse editors")
278#define DUNE_UNARY_FUNC(name) \
279 template<class T, std::size_t align> \
280 decltype(auto) name(const AlignedNumber<T, align> &u) \
283 return aligned<align>(name(T(u))); \
298 DUNE_UNARY_FUNC(abs);
299 DUNE_UNARY_FUNC(acos);
300 DUNE_UNARY_FUNC(acosh);
301 DUNE_UNARY_FUNC(asin);
302 DUNE_UNARY_FUNC(asinh);
303 DUNE_UNARY_FUNC(atan);
305 DUNE_UNARY_FUNC(atanh);
306 DUNE_UNARY_FUNC(cbrt);
307 DUNE_UNARY_FUNC(ceil);
309 DUNE_UNARY_FUNC(cos);
310 DUNE_UNARY_FUNC(cosh);
311 DUNE_UNARY_FUNC(erf);
312 DUNE_UNARY_FUNC(erfc);
313 DUNE_UNARY_FUNC(exp);
314 DUNE_UNARY_FUNC(exp2);
315 DUNE_UNARY_FUNC(expm1);
316 DUNE_UNARY_FUNC(fabs);
318 DUNE_UNARY_FUNC(floor);
325 DUNE_UNARY_FUNC(ilogb);
327 DUNE_UNARY_FUNC(lgamma);
328 DUNE_UNARY_FUNC(llrint);
329 DUNE_UNARY_FUNC(llround);
330 DUNE_UNARY_FUNC(log);
331 DUNE_UNARY_FUNC(log10);
332 DUNE_UNARY_FUNC(log1p);
333 DUNE_UNARY_FUNC(log2);
334 DUNE_UNARY_FUNC(logb);
335 DUNE_UNARY_FUNC(lrint);
336 DUNE_UNARY_FUNC(lround);
338 DUNE_UNARY_FUNC(nearbyint);
344 DUNE_UNARY_FUNC(rint);
345 DUNE_UNARY_FUNC(
round);
348 DUNE_UNARY_FUNC(sin);
349 DUNE_UNARY_FUNC(sinh);
350 DUNE_UNARY_FUNC(sqrt);
351 DUNE_UNARY_FUNC(tan);
352 DUNE_UNARY_FUNC(tanh);
353 DUNE_UNARY_FUNC(tgamma);
354 DUNE_UNARY_FUNC(
trunc);
356 DUNE_UNARY_FUNC(isfinite);
357 DUNE_UNARY_FUNC(isinf);
358 DUNE_UNARY_FUNC(isnan);
359 DUNE_UNARY_FUNC(isnormal);
360 DUNE_UNARY_FUNC(signbit);
375 DUNE_UNARY_FUNC(real);
377#undef DUNE_UNARY_FUNC
382 template<
class T, std::
size_t align>
390 template<
class T, std::
size_t align>
391 T max_value(
const AlignedNumber<T, align>& val)
396 template<
class T, std::
size_t align>
397 T min_value(
const AlignedNumber<T, align>& val)
402 template<std::
size_t align>
403 bool any_true(
const AlignedNumber<bool, align>& val)
408 template<std::
size_t align>
409 bool all_true(
const AlignedNumber<bool, align>& val)
415 template<
typename T, std::
size_t align>
416 struct SimdScalarTypeTraits< AlignedNumber<T,align> >
CRTP base mixin class to check alignment.
Definition: debugalign.hh:60
aligned wrappers for arithmetic types
Definition: debugalign.hh:105
A free function to provide the demangled class name of a given object or type as a string.
Stream & operator>>(Stream &stream, std::tuple< Ts... > &t)
Read a std::tuple.
Definition: streamoperators.hh:41
typename Impl::voider< Types... >::type void_t
Is void for all valid input types (see N3911). The workhorse for C++11 SFINAE-techniques.
Definition: typetraits.hh:39
I round(const T &val, typename EpsilonType< T >::Type epsilon)
round using epsilon
Definition: float_cmp.cc:300
I trunc(const T &val, typename EpsilonType< T >::Type epsilon)
truncate using epsilon
Definition: float_cmp.cc:396
Dune namespace.
Definition: alignedallocator.hh:10
void violatedAlignment(const char *className, std::size_t expectedAlignment, const void *address)
called when an alignment violation is detected
Definition: debugalign.cc:37
std::string className()
Provide the demangled class name of a type T as a string.
Definition: classname.hh:26
static constexpr auto debugAlignment
an alignment large enough to trigger alignment errors
Definition: debugalign.hh:78
const T1 cond(bool b, const T1 &v1, const T2 &v2)
conditional evaluate
Definition: conditional.hh:26
AlignedNumber< T, align > aligned(T value)
align a value to a certain alignment
Definition: debugalign.hh:91
ViolatedAlignmentHandler & violatedAlignmentHandler()
access the handler called by violatedAlignment()
Definition: debugalign.cc:31
bool isAligned(const void *p, std::size_t align)
check whether an address conforms to the given alignment
Definition: debugalign.hh:50
std::function< void(const char *, std::size_t, const void *)> ViolatedAlignmentHandler
type of the handler called by violatedAlignment()
Definition: debugalign.hh:25
Traits for type conversions and type information.