* added EIGEN_ALIGNED_ALLOCATOR macro to allow specifying a different aligned allocator

* attempted to add support for std::deque by copying and modifying the std::vector implementation...MSVC still fails to compile with the std::deque::resize() "will not be aligned" error...probably missing something simple but I'm not sure how to make it work
This commit is contained in:
Kenneth Riddile 2010-07-26 19:06:47 -04:00
parent 1420f8b3a1
commit b038a4bb71
5 changed files with 208 additions and 12 deletions

42
Eigen/StdDeque Normal file
View File

@ -0,0 +1,42 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
// Copyright (C) 2009 Hauke Heibel <hauke.heibel@googlemail.com>
//
// 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 <http://www.gnu.org/licenses/>.
#ifndef EIGEN_STDDEQUE_MODULE_H
#define EIGEN_STDDEQUE_MODULE_H
#include "Core"
#include <deque>
#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

View File

@ -0,0 +1,150 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
// Copyright (C) 2009 Hauke Heibel <hauke.heibel@googlemail.com>
//
// 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 <http://www.gnu.org/licenses/>.
#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<typename _Ay> \
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<typename InputIterator> \
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<typename InputIterator> \
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<typename T>
class deque<T,EIGEN_ALIGNED_ALLOCATOR<T> >
: public deque<EIGEN_WORKAROUND_MSVC_STL_SUPPORT(T),
Eigen::aligned_allocator_indirection<EIGEN_WORKAROUND_MSVC_STL_SUPPORT(T)> >
{
typedef deque<EIGEN_WORKAROUND_MSVC_STL_SUPPORT(T),
Eigen::aligned_allocator_indirection<EIGEN_WORKAROUND_MSVC_STL_SUPPORT(T)> > 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

View File

@ -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<typename _Ay> \
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<typename T>
class list<T,Eigen::aligned_allocator<T> >
class list<T,EIGEN_ALIGNED_ALLOCATOR<T> >
: public list<EIGEN_WORKAROUND_MSVC_STL_SUPPORT(T),
Eigen::aligned_allocator_indirection<EIGEN_WORKAROUND_MSVC_STL_SUPPORT(T)> >
{

View File

@ -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<typename _Ay> \
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<typename T>
class vector<T,Eigen::aligned_allocator<T> >
class vector<T,EIGEN_ALIGNED_ALLOCATOR<T> >
: public vector<EIGEN_WORKAROUND_MSVC_STL_SUPPORT(T),
Eigen::aligned_allocator_indirection<EIGEN_WORKAROUND_MSVC_STL_SUPPORT(T)> >
{

View File

@ -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 T>
class aligned_allocator_indirection : public aligned_allocator<T>
class aligned_allocator_indirection : public EIGEN_ALIGNED_ALLOCATOR<T>
{
public:
typedef size_t size_type;
@ -48,12 +52,12 @@ namespace Eigen {
};
aligned_allocator_indirection() {}
aligned_allocator_indirection(const aligned_allocator_indirection& ) : aligned_allocator<T>() {}
aligned_allocator_indirection(const aligned_allocator<T>& ) {}
aligned_allocator_indirection(const aligned_allocator_indirection& ) : EIGEN_ALIGNED_ALLOCATOR<T>() {}
aligned_allocator_indirection(const EIGEN_ALIGNED_ALLOCATOR<T>& ) {}
template<class U>
aligned_allocator_indirection(const aligned_allocator_indirection<U>& ) {}
template<class U>
aligned_allocator_indirection(const aligned_allocator<U>& ) {}
aligned_allocator_indirection(const EIGEN_ALIGNED_ALLOCATOR<U>& ) {}
~aligned_allocator_indirection() {}
};