3 #ifndef DUNE_DEBUGALIGN_HH
4 #define DUNE_DEBUGALIGN_HH
16 #include <type_traits>
29 std::function<void(
const char*, std::size_t,
const void*)>;
54 inline bool isAligned(
const void *p, std::size_t align)
58 return std::uintptr_t(p) % align == 0;
62 template<std::
size_t align,
class Impl>
65 void checkAlignment()
const
67 auto pimpl =
static_cast<const Impl*
>(
this);
84 namespace AlignedNumberImpl {
86 template<
class T, std::
size_t align = debugAlignment>
94 template<std::
size_t align = debugAlignment,
class T>
103 namespace AlignedNumberImpl {
106 template<
class T, std::
size_t align>
108 :
public AlignedBase<align, AlignedNumber<T, align> >
115 template<
class U, std::size_t uAlign,
116 class = std::enable_if_t<(align >= uAlign) &&
117 std::is_convertible<U, T>::value> >
122 class = std::enable_if_t<std::is_convertible<T, U>::value> >
123 explicit operator U()
const {
return value_; }
125 const T &
value()
const {
return value_; }
129 template<
class charT,
class Traits>
130 friend std::basic_istream<charT, Traits>&
133 return str >> u.value_;
136 template<
class charT,
class Traits>
137 friend std::basic_ostream<charT, Traits>&
138 operator<<(std::basic_ostream<charT, Traits>& str,
141 return str << u.value_;
153 template<class U = T, class = std::void_t<decltype(++std::declval<U&>())> >
156 template<
class U = T,
class =
std::void_t<decltype(--std::declval<U&>())> >
159 template<class U = T, class = std::void_t<decltype(std::declval<U&>()++)> >
160 decltype(
auto)
operator++(
int) {
return aligned<align>(value_++); }
162 template<class U = T, class = std::void_t<decltype(std::declval<U&>()--)> >
163 decltype(
auto)
operator--(
int) {
return aligned<align>(value_--); }
166 template<
class U = T,
167 class = std::void_t<decltype(+std::declval<const U&>())> >
168 decltype(
auto)
operator+()
const {
return aligned<align>(+value_); }
170 template<
class U = T,
171 class =
std::void_t<decltype(-std::declval<const U&>())> >
172 decltype(
auto) operator-()
const {
return aligned<align>(-value_); }
179 # pragma GCC diagnostic push
180 # pragma GCC diagnostic ignored "-Wbool-operation"
182 template<
class U = T,
183 class = std::void_t<decltype(~std::declval<const U&>())> >
184 decltype(
auto)
operator~()
const {
return aligned<align>(~value_); }
186 # pragma GCC diagnostic pop
189 template<
class U = T,
190 class = std::void_t<decltype(!std::declval<const U&>())> >
191 decltype(
auto)
operator!()
const {
return aligned<align>(!value_); }
194 #define DUNE_ASSIGN_OP(OP) \
195 template<class U, std::size_t uAlign, \
196 class = std::enable_if_t< \
197 ( uAlign <= align && \
198 sizeof(std::declval<T&>() OP std::declval<U>()) ) \
200 AlignedNumber &operator OP(const AlignedNumber<U, uAlign> &u) \
207 class = std::void_t<decltype(std::declval<T&>() OP \
208 std::declval<U>())> > \
209 AlignedNumber &operator OP(const U &u) \
215 static_assert(true, "Require semicolon to unconfuse editors")
231 #undef DUNE_ASSIGN_OP
235 #define DUNE_BINARY_OP(OP) \
236 template<class T, std::size_t tAlign, class U, std::size_t uAlign, \
237 class = std::void_t<decltype(std::declval<T>() \
238 OP std::declval<U>())> > \
240 operator OP(const AlignedNumber<T, tAlign> &t, \
241 const AlignedNumber<U, uAlign> &u) \
244 return aligned<(tAlign > uAlign ? tAlign : uAlign)>(T(t) OP U(u)); \
247 template<class T, class U, std::size_t uAlign, \
248 class = std::void_t<decltype(std::declval<T>() \
249 OP std::declval<U>())> > \
251 operator OP(const T &t, const AlignedNumber<U, uAlign> &u) \
253 return aligned<uAlign>(t OP U(u)); \
256 template<class T, std::size_t tAlign, class U, \
257 class = std::void_t<decltype(std::declval<T>() \
258 OP std::declval<U>())> > \
260 operator OP(const AlignedNumber<T, tAlign> &t, const U &u) \
262 return aligned<tAlign>(T(t) OP u); \
265 static_assert(true, "Require semicolon to unconfuse editors")
291 #undef DUNE_BINARY_OP
297 #define DUNE_UNARY_FUNC(name) \
298 template<class T, std::size_t align> \
299 decltype(auto) name(const AlignedNumber<T, align> &u) \
302 return aligned<align>(name(T(u))); \
304 static_assert(true, "Require semicolon to unconfuse editors")
397 #undef DUNE_UNARY_FUNC
411 template<
class T, std::
size_t align>
416 return aligned<align>(
max(T(a), T(b)));
419 template<
class T, std::
size_t align>
423 return aligned<align>(
max(a, T(b)));
426 template<
class T, std::
size_t align>
430 return aligned<align>(
max(T(a), b));
433 template<
class T, std::
size_t align>
438 return aligned<align>(
min(T(a), T(b)));
441 template<
class T, std::
size_t align>
445 return aligned<align>(
min(a, T(b)));
448 template<
class T, std::
size_t align>
452 return aligned<align>(
min(T(a), b));
458 template<
class T, std::
size_t align>
459 AlignedNumber<T, align>
467 template<
class T, std::
size_t align>
473 template<
class T, std::
size_t align>
479 template<std::
size_t align>
485 template<std::
size_t align>
493 namespace Overloads {
495 template<
class T, std::
size_t align>
498 template<
class U,
class T, std::
size_t align>
503 template<
class T, std::
size_t align>
506 template<
class T, std::
size_t align>
513 template<
class T, std::
size_t align>
520 template<
class T, std::
size_t align>
526 return mask ? ifTrue : ifFalse;
529 template<std::
size_t align>
A free function to provide the demangled class name of a given object or type as a string.
#define DUNE_BINARY_OP(OP)
Definition: debugalign.hh:235
#define DUNE_UNARY_FUNC(name)
#define DUNE_ASSIGN_OP(OP)
Definition: debugalign.hh:194
Basic definitions for SIMD Implementations.
Default implementations for SIMD Implementations.
Traits for type conversions and type information.
std::integral_constant< std::size_t, i > index_constant
An index constant with value i.
Definition: indices.hh:28
typename Impl::voider< Types... >::type void_t
Is void for all valid input types. The workhorse for C++11 SFINAE-techniques.
Definition: typetraits.hh:38
std::ostream & operator<<(std::ostream &s, const bigunsignedint< k > &x)
Definition: bigunsignedint.hh:273
I round(const T &val, typename EpsilonType< T >::Type epsilon)
round using epsilon
Definition: float_cmp.cc:309
I trunc(const T &val, typename EpsilonType< T >::Type epsilon)
truncate using epsilon
Definition: float_cmp.cc:405
Mask< V > mask(ADLTag< 0, std::is_same< V, Mask< V > >::value >, const V &v)
implements Simd::mask()
Definition: defaults.hh:151
Dune namespace.
Definition: alignedallocator.hh:11
void violatedAlignment(const char *className, std::size_t expectedAlignment, const void *address)
called when an alignment violation is detected
Definition: debugalign.cc:37
AlignedNumber< T, align > aligned(T value)
align a value to a certain alignment
Definition: debugalign.hh:95
bool any_true(const AlignedNumber< bool, align > &val)
Definition: debugalign.hh:480
bool all_true(const AlignedNumber< bool, align > &val)
Definition: debugalign.hh:486
std::string className()
Provide the demangled class name of a type T as a string.
Definition: classname.hh:45
static constexpr auto debugAlignment
an alignment large enough to trigger alignment errors
Definition: debugalign.hh:82
T lane(std::size_t l, const T &v)
access a lane of a simd vector (scalar version)
Definition: simd.hh:364
const T1 cond(bool b, const T1 &v1, const T2 &v2)
conditional evaluate
Definition: conditional.hh:26
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:54
T max_value(const AlignedNumber< T, align > &val)
Definition: debugalign.hh:468
std::function< void(const char *, std::size_t, const void *)> ViolatedAlignmentHandler
type of the handler called by violatedAlignment()
Definition: debugalign.hh:29
T min_value(const AlignedNumber< T, align > &val)
Definition: debugalign.hh:474
auto max(const AlignedNumber< T, align > &a, const T &b)
Definition: debugalign.hh:427
auto min(const AlignedNumber< T, align > &a, const T &b)
Definition: debugalign.hh:449
bool anyTrue(ADLTag< 5 >, const AlignedNumber< bool, align > &mask)
Definition: debugalign.hh:530
CRTP base mixin class to check alignment.
Definition: debugalign.hh:64
~AlignedBase()
Definition: debugalign.hh:75
AlignedBase & operator=(AlignedBase &&)=default
AlignedBase & operator=(const AlignedBase &)=default
AlignedBase(AlignedBase &&)
Definition: debugalign.hh:74
AlignedBase(const AlignedBase &)
Definition: debugalign.hh:73
AlignedBase()
Definition: debugalign.hh:72
aligned wrappers for arithmetic types
Definition: debugalign.hh:109
DUNE_ASSIGN_OP * DUNE_ASSIGN_OP(/=);DUNE_ASSIGN_OP(%=
T & value()
Definition: debugalign.hh:126
decltype(auto) operator+() const
Definition: debugalign.hh:168
decltype(auto) operator--(int)
Definition: debugalign.hh:163
decltype(auto) operator++(int)
Definition: debugalign.hh:160
friend std::basic_istream< charT, Traits > & operator>>(std::basic_istream< charT, Traits > &str, AlignedNumber &u)
Definition: debugalign.hh:131
decltype(auto) operator!() const
Definition: debugalign.hh:191
DUNE_ASSIGN_OP^ DUNE_ASSIGN_OP(&=);DUNE_ASSIGN_OP(|=
AlignedNumber & operator--()
Definition: debugalign.hh:157
const T & value() const
Definition: debugalign.hh:125
decltype(auto) operator~() const
Definition: debugalign.hh:184
AlignedNumber(T value)
Definition: debugalign.hh:114
AlignedNumber(const AlignedNumber< U, uAlign > &o)
Definition: debugalign.hh:118
T type
Definition: debugalign.hh:496
Tag used to force late-binding lookup in Dune::Simd::Overloads.
Definition: base.hh:180
should have a member type type
Definition: standard.hh:58
should have a member type type
Definition: standard.hh:65
should be derived from a Dune::index_constant
Definition: standard.hh:72