diff --git a/Eigen/StdDeque b/Eigen/StdDeque new file mode 100644 index 000000000..a4f96232d --- /dev/null +++ b/Eigen/StdDeque @@ -0,0 +1,42 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2009 Gael Guennebaud +// Copyright (C) 2009 Hauke Heibel +// +// Eigen is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 3 of the License, or (at your option) any later version. +// +// Alternatively, you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of +// the License, or (at your option) any later version. +// +// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License and a copy of the GNU General Public License along with +// Eigen. If not, see . + +#ifndef EIGEN_STDDEQUE_MODULE_H +#define EIGEN_STDDEQUE_MODULE_H + +#include "Core" +#include + +#if (defined(_MSC_VER) && defined(_WIN64)) /* MSVC auto aligns in 64 bit builds */ + +#define EIGEN_DEFINE_STL_DEQUE_SPECIALIZATION(...) + +#else + +#include "src/StlSupport/StdDeque.h" + +#endif + +#endif // EIGEN_STDDEQUE_MODULE_H diff --git a/Eigen/src/StlSupport/StdDeque.h b/Eigen/src/StlSupport/StdDeque.h new file mode 100644 index 000000000..324737b38 --- /dev/null +++ b/Eigen/src/StlSupport/StdDeque.h @@ -0,0 +1,150 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2009 Gael Guennebaud +// Copyright (C) 2009 Hauke Heibel +// +// Eigen is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 3 of the License, or (at your option) any later version. +// +// Alternatively, you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of +// the License, or (at your option) any later version. +// +// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License and a copy of the GNU General Public License along with +// Eigen. If not, see . + +#ifndef EIGEN_STDDEQUE_H +#define EIGEN_STDDEQUE_H + +#include "Eigen/src/StlSupport/details.h" + +// Define the explicit instantiation (e.g. necessary for the Intel compiler) +#if defined(__INTEL_COMPILER) || defined(__GNUC__) + #define EIGEN_EXPLICIT_STL_DEQUE_INSTANTIATION(...) template class std::deque<__VA_ARGS__, EIGEN_ALIGNED_ALLOCATOR<__VA_ARGS__> >; +#else + #define EIGEN_EXPLICIT_STL_DEQUE_INSTANTIATION(...) +#endif + +/** + * This section contains a convenience MACRO which allows an easy specialization of + * std::deque such that for data types with alignment issues the correct allocator + * is used automatically. + */ +#define EIGEN_DEFINE_STL_DEQUE_SPECIALIZATION(...) \ +EIGEN_EXPLICIT_STL_DEQUE_INSTANTIATION(__VA_ARGS__) \ +namespace std \ +{ \ + template \ + class deque<__VA_ARGS__, _Ay> \ + : public deque<__VA_ARGS__, EIGEN_ALIGNED_ALLOCATOR<__VA_ARGS__> > \ + { \ + typedef deque<__VA_ARGS__, EIGEN_ALIGNED_ALLOCATOR<__VA_ARGS__> > deque_base; \ + public: \ + typedef __VA_ARGS__ value_type; \ + typedef typename deque_base::allocator_type allocator_type; \ + typedef typename deque_base::size_type size_type; \ + typedef typename deque_base::iterator iterator; \ + explicit deque(const allocator_type& a = allocator_type()) : deque_base(a) {} \ + template \ + deque(InputIterator first, InputIterator last, const allocator_type& a = allocator_type()) : deque_base(first, last, a) {} \ + deque(const deque& c) : deque_base(c) {} \ + explicit deque(size_type num, const value_type& val = value_type()) : deque_base(num, val) {} \ + deque(iterator start, iterator end) : deque_base(start, end) {} \ + deque& operator=(const deque& x) { \ + deque_base::operator=(x); \ + return *this; \ + } \ + }; \ +} + +// check whether we really need the std::deque specialization +#if !(defined(_GLIBCXX_DEQUE) && (!EIGEN_GNUC_AT_LEAST(4,1))) /* Note that before gcc-4.1 we already have: std::deque::resize(size_type,const T&). */ + +namespace std { + +#define EIGEN_STD_DEQUE_SPECIALIZATION_BODY \ + public: \ + typedef T value_type; \ + typedef typename deque_base::allocator_type allocator_type; \ + typedef typename deque_base::size_type size_type; \ + typedef typename deque_base::iterator iterator; \ + typedef typename deque_base::const_iterator const_iterator; \ + explicit deque(const allocator_type& a = allocator_type()) : deque_base(a) {} \ + template \ + deque(InputIterator first, InputIterator last, const allocator_type& a = allocator_type()) \ + : deque_base(first, last, a) {} \ + deque(const deque& c) : deque_base(c) {} \ + explicit deque(size_type num, const value_type& val = value_type()) : deque_base(num, val) {} \ + deque(iterator start, iterator end) : deque_base(start, end) {} \ + deque& operator=(const deque& x) { \ + deque_base::operator=(x); \ + return *this; \ + } + + template + class deque > + : public deque > +{ + typedef deque > deque_base; + EIGEN_STD_DEQUE_SPECIALIZATION_BODY + + void resize(size_type new_size) + { resize(new_size, T()); } + +#if defined(_DEQUE_) + #pragma message("old method") + // workaround MSVC std::deque implementation + void resize(size_type new_size, const value_type& x) + { + if (deque_base::size() < new_size) + deque_base::_Insert_n(deque_base::end(), new_size - deque_base::size(), x); + else if (new_size < deque_base::size()) + deque_base::erase(deque_base::begin() + new_size, deque_base::end()); + } + void push_back(const value_type& x) + { deque_base::push_back(x); } + void push_front(const value_type& x) + { deque_base::push_front(x); } + using deque_base::insert; + iterator insert(const_iterator position, const value_type& x) + { return deque_base::insert(position,x); } + void insert(const_iterator position, size_type new_size, const value_type& x) + { deque_base::insert(position, new_size, x); } +#elif defined(_GLIBCXX_DEQUE) && EIGEN_GNUC_AT_LEAST(4,2) + // workaround GCC std::deque implementation + void resize(size_type new_size, const value_type& x) + { + if (new_size < deque_base::size()) + deque_base::_M_erase_at_end(this->_M_impl._M_start + new_size); + else + deque_base::insert(deque_base::end(), new_size - deque_base::size(), x); + } +#else + // either GCC 4.1 or non-GCC + // default implementation which should always work. + void resize(size_type new_size, const value_type& x) + { + if (new_size < deque_base::size()) + deque_base::erase(deque_base::begin() + new_size, deque_base::end()); + else if (new_size > deque_base::size()) + deque_base::insert(deque_base::end(), new_size - deque_base::size(), x); + } +#endif + }; +} + +#endif // check whether specialization is actually required + +#endif // EIGEN_STDDEQUE_H diff --git a/Eigen/src/StlSupport/StdList.h b/Eigen/src/StlSupport/StdList.h index 55b90066e..d329a0b2d 100644 --- a/Eigen/src/StlSupport/StdList.h +++ b/Eigen/src/StlSupport/StdList.h @@ -29,7 +29,7 @@ // Define the explicit instantiation (e.g. necessary for the Intel compiler) #if defined(__INTEL_COMPILER) || defined(__GNUC__) - #define EIGEN_EXPLICIT_STL_LIST_INSTANTIATION(...) template class std::list<__VA_ARGS__, Eigen::aligned_allocator<__VA_ARGS__> >; + #define EIGEN_EXPLICIT_STL_LIST_INSTANTIATION(...) template class std::list<__VA_ARGS__, EIGEN_ALIGNED_ALLOCATOR<__VA_ARGS__> >; #else #define EIGEN_EXPLICIT_STL_LIST_INSTANTIATION(...) #endif @@ -45,9 +45,9 @@ namespace std \ { \ template \ class list<__VA_ARGS__, _Ay> \ - : public list<__VA_ARGS__, Eigen::aligned_allocator<__VA_ARGS__> > \ + : public list<__VA_ARGS__, EIGEN_ALIGNED_ALLOCATOR<__VA_ARGS__> > \ { \ - typedef list<__VA_ARGS__, Eigen::aligned_allocator<__VA_ARGS__> > list_base; \ + typedef list<__VA_ARGS__, EIGEN_ALIGNED_ALLOCATOR<__VA_ARGS__> > list_base; \ public: \ typedef __VA_ARGS__ value_type; \ typedef typename list_base::allocator_type allocator_type; \ @@ -92,7 +92,7 @@ namespace std } template - class list > + class list > : public list > { diff --git a/Eigen/src/StlSupport/StdVector.h b/Eigen/src/StlSupport/StdVector.h index 9b6bb6578..a1d1391a6 100644 --- a/Eigen/src/StlSupport/StdVector.h +++ b/Eigen/src/StlSupport/StdVector.h @@ -30,7 +30,7 @@ // Define the explicit instantiation (e.g. necessary for the Intel compiler) #if defined(__INTEL_COMPILER) || defined(__GNUC__) - #define EIGEN_EXPLICIT_STL_VECTOR_INSTANTIATION(...) template class std::vector<__VA_ARGS__, Eigen::aligned_allocator<__VA_ARGS__> >; + #define EIGEN_EXPLICIT_STL_VECTOR_INSTANTIATION(...) template class std::vector<__VA_ARGS__, EIGEN_ALIGNED_ALLOCATOR<__VA_ARGS__> >; #else #define EIGEN_EXPLICIT_STL_VECTOR_INSTANTIATION(...) #endif @@ -46,9 +46,9 @@ namespace std \ { \ template \ class vector<__VA_ARGS__, _Ay> \ - : public vector<__VA_ARGS__, Eigen::aligned_allocator<__VA_ARGS__> > \ + : public vector<__VA_ARGS__, EIGEN_ALIGNED_ALLOCATOR<__VA_ARGS__> > \ { \ - typedef vector<__VA_ARGS__, Eigen::aligned_allocator<__VA_ARGS__> > vector_base; \ + typedef vector<__VA_ARGS__, EIGEN_ALIGNED_ALLOCATOR<__VA_ARGS__> > vector_base; \ public: \ typedef __VA_ARGS__ value_type; \ typedef typename vector_base::allocator_type allocator_type; \ @@ -92,7 +92,7 @@ namespace std { } template - class vector > + class vector > : public vector > { diff --git a/Eigen/src/StlSupport/details.h b/Eigen/src/StlSupport/details.h index d19408012..5ee4dba94 100644 --- a/Eigen/src/StlSupport/details.h +++ b/Eigen/src/StlSupport/details.h @@ -26,11 +26,15 @@ #ifndef EIGEN_STL_DETAILS_H #define EIGEN_STL_DETAILS_H +#ifndef EIGEN_ALIGNED_ALLOCATOR + #define EIGEN_ALIGNED_ALLOCATOR Eigen::aligned_allocator +#endif + namespace Eigen { // This one is needed to prevent reimplementing the whole std::vector. template - class aligned_allocator_indirection : public aligned_allocator + class aligned_allocator_indirection : public EIGEN_ALIGNED_ALLOCATOR { public: typedef size_t size_type; @@ -48,12 +52,12 @@ namespace Eigen { }; aligned_allocator_indirection() {} - aligned_allocator_indirection(const aligned_allocator_indirection& ) : aligned_allocator() {} - aligned_allocator_indirection(const aligned_allocator& ) {} + aligned_allocator_indirection(const aligned_allocator_indirection& ) : EIGEN_ALIGNED_ALLOCATOR() {} + aligned_allocator_indirection(const EIGEN_ALIGNED_ALLOCATOR& ) {} template aligned_allocator_indirection(const aligned_allocator_indirection& ) {} template - aligned_allocator_indirection(const aligned_allocator& ) {} + aligned_allocator_indirection(const EIGEN_ALIGNED_ALLOCATOR& ) {} ~aligned_allocator_indirection() {} };