00001 // This file is part of Eigen, a lightweight C++ template library 00002 // for linear algebra. 00003 // 00004 // Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr> 00005 // Copyright (C) 2009 Hauke Heibel <hauke.heibel@googlemail.com> 00006 // 00007 // Eigen is free software; you can redistribute it and/or 00008 // modify it under the terms of the GNU Lesser General Public 00009 // License as published by the Free Software Foundation; either 00010 // version 3 of the License, or (at your option) any later version. 00011 // 00012 // Alternatively, you can redistribute it and/or 00013 // modify it under the terms of the GNU General Public License as 00014 // published by the Free Software Foundation; either version 2 of 00015 // the License, or (at your option) any later version. 00016 // 00017 // Eigen is distributed in the hope that it will be useful, but WITHOUT ANY 00018 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 00019 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the 00020 // GNU General Public License for more details. 00021 // 00022 // You should have received a copy of the GNU Lesser General Public 00023 // License and a copy of the GNU General Public License along with 00024 // Eigen. If not, see <http://www.gnu.org/licenses/>. 00025 00026 #ifndef EIGEN_STL_DETAILS_H 00027 #define EIGEN_STL_DETAILS_H 00028 00029 #ifndef EIGEN_ALIGNED_ALLOCATOR 00030 #define EIGEN_ALIGNED_ALLOCATOR Eigen::aligned_allocator 00031 #endif 00032 00033 namespace Eigen { 00034 00035 // This one is needed to prevent reimplementing the whole std::vector. 00036 template <class T> 00037 class aligned_allocator_indirection : public EIGEN_ALIGNED_ALLOCATOR<T> 00038 { 00039 public: 00040 typedef size_t size_type; 00041 typedef ptrdiff_t difference_type; 00042 typedef T* pointer; 00043 typedef const T* const_pointer; 00044 typedef T& reference; 00045 typedef const T& const_reference; 00046 typedef T value_type; 00047 00048 template<class U> 00049 struct rebind 00050 { 00051 typedef aligned_allocator_indirection<U> other; 00052 }; 00053 00054 aligned_allocator_indirection() {} 00055 aligned_allocator_indirection(const aligned_allocator_indirection& ) : EIGEN_ALIGNED_ALLOCATOR<T>() {} 00056 aligned_allocator_indirection(const EIGEN_ALIGNED_ALLOCATOR<T>& ) {} 00057 template<class U> 00058 aligned_allocator_indirection(const aligned_allocator_indirection<U>& ) {} 00059 template<class U> 00060 aligned_allocator_indirection(const EIGEN_ALIGNED_ALLOCATOR<U>& ) {} 00061 ~aligned_allocator_indirection() {} 00062 }; 00063 00064 #ifdef _MSC_VER 00065 00066 // sometimes, MSVC detects, at compile time, that the argument x 00067 // in std::vector::resize(size_t s,T x) won't be aligned and generate an error 00068 // even if this function is never called. Whence this little wrapper. 00069 #define EIGEN_WORKAROUND_MSVC_STL_SUPPORT(T) \ 00070 typename Eigen::internal::conditional< \ 00071 Eigen::internal::is_arithmetic<T>::value, \ 00072 T, \ 00073 Eigen::internal::workaround_msvc_stl_support<T> \ 00074 >::type 00075 00076 namespace internal { 00077 template<typename T> struct workaround_msvc_stl_support : public T 00078 { 00079 inline workaround_msvc_stl_support() : T() {} 00080 inline workaround_msvc_stl_support(const T& other) : T(other) {} 00081 inline operator T& () { return *static_cast<T*>(this); } 00082 inline operator const T& () const { return *static_cast<const T*>(this); } 00083 template<typename OtherT> 00084 inline T& operator=(const OtherT& other) 00085 { T::operator=(other); return *this; } 00086 inline workaround_msvc_stl_support& operator=(const workaround_msvc_stl_support& other) 00087 { T::operator=(other); return *this; } 00088 }; 00089 } 00090 00091 #else 00092 00093 #define EIGEN_WORKAROUND_MSVC_STL_SUPPORT(T) T 00094 00095 #endif 00096 00097 } 00098 00099 #endif // EIGEN_STL_DETAILS_H