xref: /aosp_15_r20/external/eigen/Eigen/src/StlSupport/details.h (revision bf2c37156dfe67e5dfebd6d394bad8b2ab5804d4)
1*bf2c3715SXin Li // This file is part of Eigen, a lightweight C++ template library
2*bf2c3715SXin Li // for linear algebra.
3*bf2c3715SXin Li //
4*bf2c3715SXin Li // Copyright (C) 2009 Gael Guennebaud <[email protected]>
5*bf2c3715SXin Li // Copyright (C) 2009 Hauke Heibel <[email protected]>
6*bf2c3715SXin Li //
7*bf2c3715SXin Li // This Source Code Form is subject to the terms of the Mozilla
8*bf2c3715SXin Li // Public License v. 2.0. If a copy of the MPL was not distributed
9*bf2c3715SXin Li // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
10*bf2c3715SXin Li 
11*bf2c3715SXin Li #ifndef EIGEN_STL_DETAILS_H
12*bf2c3715SXin Li #define EIGEN_STL_DETAILS_H
13*bf2c3715SXin Li 
14*bf2c3715SXin Li #ifndef EIGEN_ALIGNED_ALLOCATOR
15*bf2c3715SXin Li   #define EIGEN_ALIGNED_ALLOCATOR Eigen::aligned_allocator
16*bf2c3715SXin Li #endif
17*bf2c3715SXin Li 
18*bf2c3715SXin Li namespace Eigen {
19*bf2c3715SXin Li 
20*bf2c3715SXin Li   // This one is needed to prevent reimplementing the whole std::vector.
21*bf2c3715SXin Li   template <class T>
22*bf2c3715SXin Li   class aligned_allocator_indirection : public EIGEN_ALIGNED_ALLOCATOR<T>
23*bf2c3715SXin Li   {
24*bf2c3715SXin Li   public:
25*bf2c3715SXin Li     typedef std::size_t     size_type;
26*bf2c3715SXin Li     typedef std::ptrdiff_t  difference_type;
27*bf2c3715SXin Li     typedef T*              pointer;
28*bf2c3715SXin Li     typedef const T*        const_pointer;
29*bf2c3715SXin Li     typedef T&              reference;
30*bf2c3715SXin Li     typedef const T&        const_reference;
31*bf2c3715SXin Li     typedef T               value_type;
32*bf2c3715SXin Li 
33*bf2c3715SXin Li     template<class U>
34*bf2c3715SXin Li     struct rebind
35*bf2c3715SXin Li     {
36*bf2c3715SXin Li       typedef aligned_allocator_indirection<U> other;
37*bf2c3715SXin Li     };
38*bf2c3715SXin Li 
aligned_allocator_indirection()39*bf2c3715SXin Li     aligned_allocator_indirection() {}
aligned_allocator_indirection(const aligned_allocator_indirection &)40*bf2c3715SXin Li     aligned_allocator_indirection(const aligned_allocator_indirection& ) : EIGEN_ALIGNED_ALLOCATOR<T>() {}
aligned_allocator_indirection(const EIGEN_ALIGNED_ALLOCATOR<T> &)41*bf2c3715SXin Li     aligned_allocator_indirection(const EIGEN_ALIGNED_ALLOCATOR<T>& ) {}
42*bf2c3715SXin Li     template<class U>
aligned_allocator_indirection(const aligned_allocator_indirection<U> &)43*bf2c3715SXin Li     aligned_allocator_indirection(const aligned_allocator_indirection<U>& ) {}
44*bf2c3715SXin Li     template<class U>
aligned_allocator_indirection(const EIGEN_ALIGNED_ALLOCATOR<U> &)45*bf2c3715SXin Li     aligned_allocator_indirection(const EIGEN_ALIGNED_ALLOCATOR<U>& ) {}
~aligned_allocator_indirection()46*bf2c3715SXin Li     ~aligned_allocator_indirection() {}
47*bf2c3715SXin Li   };
48*bf2c3715SXin Li 
49*bf2c3715SXin Li #if EIGEN_COMP_MSVC
50*bf2c3715SXin Li 
51*bf2c3715SXin Li   // sometimes, MSVC detects, at compile time, that the argument x
52*bf2c3715SXin Li   // in std::vector::resize(size_t s,T x) won't be aligned and generate an error
53*bf2c3715SXin Li   // even if this function is never called. Whence this little wrapper.
54*bf2c3715SXin Li #define EIGEN_WORKAROUND_MSVC_STL_SUPPORT(T) \
55*bf2c3715SXin Li   typename Eigen::internal::conditional< \
56*bf2c3715SXin Li     Eigen::internal::is_arithmetic<T>::value, \
57*bf2c3715SXin Li     T, \
58*bf2c3715SXin Li     Eigen::internal::workaround_msvc_stl_support<T> \
59*bf2c3715SXin Li   >::type
60*bf2c3715SXin Li 
61*bf2c3715SXin Li   namespace internal {
62*bf2c3715SXin Li   template<typename T> struct workaround_msvc_stl_support : public T
63*bf2c3715SXin Li   {
workaround_msvc_stl_supportworkaround_msvc_stl_support64*bf2c3715SXin Li     inline workaround_msvc_stl_support() : T() {}
workaround_msvc_stl_supportworkaround_msvc_stl_support65*bf2c3715SXin Li     inline workaround_msvc_stl_support(const T& other) : T(other) {}
66*bf2c3715SXin Li     inline operator T& () { return *static_cast<T*>(this); }
67*bf2c3715SXin Li     inline operator const T& () const { return *static_cast<const T*>(this); }
68*bf2c3715SXin Li     template<typename OtherT>
69*bf2c3715SXin Li     inline T& operator=(const OtherT& other)
70*bf2c3715SXin Li     { T::operator=(other); return *this; }
71*bf2c3715SXin Li     inline workaround_msvc_stl_support& operator=(const workaround_msvc_stl_support& other)
72*bf2c3715SXin Li     { T::operator=(other); return *this; }
73*bf2c3715SXin Li   };
74*bf2c3715SXin Li   }
75*bf2c3715SXin Li 
76*bf2c3715SXin Li #else
77*bf2c3715SXin Li 
78*bf2c3715SXin Li #define EIGEN_WORKAROUND_MSVC_STL_SUPPORT(T) T
79*bf2c3715SXin Li 
80*bf2c3715SXin Li #endif
81*bf2c3715SXin Li 
82*bf2c3715SXin Li }
83*bf2c3715SXin Li 
84*bf2c3715SXin Li #endif // EIGEN_STL_DETAILS_H
85