17#ifndef __mrtrix_types_h__
18#define __mrtrix_types_h__
34# define PRI_SIZET PRIu64
36# define PRI_SIZET PRIu32
39# define PRI_SIZET "zu"
45#ifdef MRTRIX_MAX_ALIGN_T_NOT_DEFINED
46# ifdef MRTRIX_STD_MAX_ALIGN_T_NOT_DEFINED
49 long long __clang_max_align_nonce1
50 __attribute__((__aligned__(__alignof__(
long long))));
51 long double __clang_max_align_nonce2
52 __attribute__((__aligned__(__alignof__(
long double))));
56 constexpr size_t malloc_align =
alignof (std::max_align_t);
63 template <
class ImageType>
class ConstRow;
64 template <
class ImageType>
class Row;
68#ifdef EIGEN_HAS_OPENMP
69# undef EIGEN_HAS_OPENMP
72#define EIGEN_DENSEBASE_PLUGIN "eigen_plugins/dense_base.h"
73#define EIGEN_MATRIXBASE_PLUGIN "eigen_plugins/dense_base.h"
74#define EIGEN_ARRAYBASE_PLUGIN "eigen_plugins/dense_base.h"
75#define EIGEN_MATRIX_PLUGIN "eigen_plugins/matrix.h"
76#define EIGEN_ARRAY_PLUGIN "eigen_plugins/array.h"
78#include <Eigen/Geometry>
113# define VLA(name, type, num) \
114 vector<type> __vla__ ## name(num); \
115 type* name = &__vla__ ## name[0]
116# define VLA_MAX(name, type, num, max) type name[max]
118# define VLA(name, type, num) type name[num]
119# define VLA_MAX(name, type, num, max) type name[num]
141#ifdef MRTRIX_NO_NON_POD_VLA
142# define NON_POD_VLA(name, type, num) \
143 vector<type> __vla__ ## name(num); \
144 type* name = &__vla__ ## name[0]
145# define NON_POD_VLA_MAX(name, type, num, max) type name[max]
147# define NON_POD_VLA(name, type, num) type name[num]
148# define NON_POD_VLA_MAX(name, type, num, max) type name[num]
154# define FORCE_INLINE inline __attribute__((always_inline))
156# define FORCE_INLINE inline
160#ifndef EIGEN_DEFAULT_ALIGN_BYTES
162# define EIGEN_DEFAULT_ALIGN_BYTES 16
167 template <
typename C>
static inline char test (
decltype(C::operator
new (
sizeof(C)))) ;
168 template <
typename C>
static inline long test (...);
170 enum {
value =
sizeof(test<T>(
nullptr)) ==
sizeof(
char) };
176 if (!original)
throw std::bad_alloc();
178 *(
reinterpret_cast<void**
>(aligned) - 1) = original;
182inline void __aligned_free (
void* ptr) {
if (ptr) std::free (*(
reinterpret_cast<void**
>(ptr) - 1)); }
185#define MEMALIGN(...) public: \
186 FORCE_INLINE void* operator new (std::size_t size) { return (alignof(__VA_ARGS__)>::MR::malloc_align) ? __aligned_malloc (size) : ::operator new (size); } \
187 FORCE_INLINE void* operator new[] (std::size_t size) { return (alignof(__VA_ARGS__)>::MR::malloc_align) ? __aligned_malloc (size) : ::operator new[] (size); } \
188 FORCE_INLINE void operator delete (void* ptr) { if (alignof(__VA_ARGS__)>::MR::malloc_align) __aligned_free (ptr); else ::operator delete (ptr); } \
189 FORCE_INLINE void operator delete[] (void* ptr) { if (alignof(__VA_ARGS__)>::MR::malloc_align) __aligned_free (ptr); else ::operator delete[] (ptr); }
206#define CHECK_MEM_ALIGN(...) \
207 static_assert ( (alignof(__VA_ARGS__) <= ::MR::malloc_align) || __has_custom_new_operator<__VA_ARGS__>::value, \
208 "class requires over-alignment, but no operator new defined! Please insert MEMALIGN() into class definition.")
217 using cdouble = std::complex<double>;
218 using cfloat = std::complex<float>;
220 template <
typename T>
221 struct container_cast :
public T {
MEMALIGN(container_cast<T>)
222 template <
typename U>
224 T (x.begin(), x.end()) { }
230 constexpr default_type NaN = std::numeric_limits<default_type>::quiet_NaN();
231 constexpr default_type Inf = std::numeric_limits<default_type>::infinity();
234 using transform_type = Eigen::Transform<default_type, 3, Eigen::AffineCompact>;
238 using KeyValues = std::map<std::string, std::string>;
242 template <
class ValueType>
struct is_complex : std::false_type {
NOMEMALIGN };
243 template <
class ValueType>
struct is_complex<
std::complex<ValueType>> : std::true_type {
NOMEMALIGN };
247 template <
class ValueType>
248 struct is_data_type :
249 std::integral_constant<bool, std::is_arithmetic<ValueType>::value || is_complex<ValueType>::value> {
NOMEMALIGN };
253 class vector : public ::std::vector<X, Eigen::aligned_allocator<X>> {
NOMEMALIGN
255 using ::std::vector<X,Eigen::aligned_allocator<X>>::vector;
259 template <
typename X>
260 class vector<X,0> :
public ::std::vector<X> {
NOMEMALIGN
262 using ::std::vector<X>::vector;
268 class deque : public ::std::deque<X, Eigen::aligned_allocator<X>> {
NOMEMALIGN
270 using ::std::deque<X,Eigen::aligned_allocator<X>>::deque;
274 template <
typename X>
275 class deque<X,0> :
public ::std::deque<X> {
NOMEMALIGN
277 using ::std::deque<X>::deque;
282 template <
typename X,
typename... Args>
283 inline std::shared_ptr<X>
make_shared (Args&&... args) {
284 return std::shared_ptr<X> (
new X (std::forward<Args> (args)...));
287 template <
typename X,
typename... Args>
288 inline std::unique_ptr<X>
make_unique (Args&&... args) {
289 return std::unique_ptr<X> (
new X (std::forward<Args> (args)...));
296 template <
typename X>
298 template <
typename X>
305 template <
class T>
inline ostream&
operator<< (ostream& stream,
const vector<T>& V)
308 for (
size_t n = 0; n < V.size(); n++)
309 stream << V[n] <<
" ";
314 template <
class T, std::
size_t N>
inline ostream&
operator<< (ostream& stream,
const array<T,N>& V)
317 for (
size_t n = 0; n < N; n++)
318 stream << V[n] <<
" ";
VectorType::Scalar value(const VectorType &coefs, typename VectorType::Scalar cos_elevation, typename VectorType::Scalar cos_azimuth, typename VectorType::Scalar sin_azimuth, int lmax)
std::map< std::string, std::string > KeyValues
used in various places for storing key-value pairs
std::complex< float > cfloat
std::complex< double > cdouble
double default_type
the default type used throughout MRtrix
constexpr size_t malloc_align
std::unique_ptr< X > make_unique(Args &&... args)
constexpr std::enable_if< std::is_arithmetic< X >::value &&std::is_unsigned< X >::value, X >::type abs(X x)
Eigen::Transform< default_type, 3, Eigen::AffineCompact > transform_type
the type for the affine transform of an image:
constexpr default_type Inf
std::shared_ptr< X > make_shared(Args &&... args)
constexpr default_type NaN
constexpr std::enable_if< std::is_arithmetic< X >::value &&!std::is_unsigned< X >::value, X >::type abs(X x)
ostream & operator<<(ostream &stream, const vector< T > &V)
void __aligned_free(void *ptr)
void * __aligned_malloc(std::size_t size)
#define EIGEN_DEFAULT_ALIGN_BYTES
container_cast(const U &x)