mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-04-21 00:59:36 +08:00
Added support for STL lists with aligned Eigen types.
This commit is contained in:
parent
031932b4ec
commit
214d5a892d
44
Eigen/StdList
Normal file
44
Eigen/StdList
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
// This file is part of Eigen, a lightweight C++ template library
|
||||||
|
// for linear algebra.
|
||||||
|
//
|
||||||
|
// 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_STDLIST_MODULE_H
|
||||||
|
#define EIGEN_STDLIST_MODULE_H
|
||||||
|
|
||||||
|
#include "Core"
|
||||||
|
#include <list>
|
||||||
|
|
||||||
|
#if (defined(_MSC_VER) && defined(_WIN64)) || /* MSVC auto aligns in 64 bit builds */ \
|
||||||
|
(defined(_MSC_VER) && _MSC_VER >= 1600) || /* MSVC 2010 ships alignment compatible STL libs */ \
|
||||||
|
(defined(_GLIBCXX_VECTOR) && (!EIGEN_GNUC_AT_LEAST(4,1))) /* Note that before gcc-4.1 we already have: std::vector::resize(size_type,const T&). */
|
||||||
|
|
||||||
|
//#define EIGEN_DEFINE_STL_LIST_SPECIALIZATION(...)
|
||||||
|
#include "src/StlSupport/StdList.h"
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#include "src/StlSupport/StdList.h"
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // EIGEN_STDLIST_MODULE_H
|
175
Eigen/StdVector
175
Eigen/StdVector
@ -29,181 +29,16 @@
|
|||||||
#include "Core"
|
#include "Core"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
// Define the explicit instantiation (e.g. necessary for the Intel compiler)
|
#if (defined(_MSC_VER) && defined(_WIN64)) || /* MSVC auto aligns in 64 bit builds */ \
|
||||||
#if defined(__INTEL_COMPILER) || defined(__GNUC__)
|
(defined(_MSC_VER) && _MSC_VER >= 1600) || /* MSVC 2010 ships alignment compatible STL libs */ \
|
||||||
#define EIGEN_EXPLICIT_STL_VECTOR_INSTANTIATION(...) template class std::vector<__VA_ARGS__, Eigen::aligned_allocator<__VA_ARGS__> >;
|
(defined(_GLIBCXX_VECTOR) && (!EIGEN_GNUC_AT_LEAST(4,1))) /* Note that before gcc-4.1 we already have: std::vector::resize(size_type,const T&). */
|
||||||
#else
|
|
||||||
#define EIGEN_EXPLICIT_STL_VECTOR_INSTANTIATION(...)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
#define EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION(...)
|
||||||
* This section contains a convenience MACRO which allows an easy specialization of
|
|
||||||
* std::vector such that for data types with alignment issues the correct allocator
|
|
||||||
* is used automatically.
|
|
||||||
*/
|
|
||||||
#define EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION(...) \
|
|
||||||
EIGEN_EXPLICIT_STL_VECTOR_INSTANTIATION(__VA_ARGS__) \
|
|
||||||
namespace std \
|
|
||||||
{ \
|
|
||||||
template<typename _Ay> \
|
|
||||||
class vector<__VA_ARGS__, _Ay> \
|
|
||||||
: public vector<__VA_ARGS__, Eigen::aligned_allocator<__VA_ARGS__> > \
|
|
||||||
{ \
|
|
||||||
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; \
|
|
||||||
typedef typename vector_base::size_type size_type; \
|
|
||||||
typedef typename vector_base::iterator iterator; \
|
|
||||||
explicit vector(const allocator_type& a = allocator_type()) : vector_base(a) {} \
|
|
||||||
template<typename InputIterator> \
|
|
||||||
vector(InputIterator first, InputIterator last, const allocator_type& a = allocator_type()) : vector_base(first, last, a) {} \
|
|
||||||
vector(const vector& c) : vector_base(c) {} \
|
|
||||||
explicit vector(size_type num, const value_type& val = value_type()) : vector_base(num, val) {} \
|
|
||||||
vector(iterator start, iterator end) : vector_base(start, end) {} \
|
|
||||||
vector& operator=(const vector& x) { \
|
|
||||||
vector_base::operator=(x); \
|
|
||||||
return *this; \
|
|
||||||
} \
|
|
||||||
}; \
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace Eigen {
|
|
||||||
|
|
||||||
// This one is needed to prevent reimplementing the whole std::vector.
|
|
||||||
template <class T>
|
|
||||||
class aligned_allocator_indirection : public aligned_allocator<T>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef size_t size_type;
|
|
||||||
typedef ptrdiff_t difference_type;
|
|
||||||
typedef T* pointer;
|
|
||||||
typedef const T* const_pointer;
|
|
||||||
typedef T& reference;
|
|
||||||
typedef const T& const_reference;
|
|
||||||
typedef T value_type;
|
|
||||||
|
|
||||||
template<class U>
|
|
||||||
struct rebind
|
|
||||||
{
|
|
||||||
typedef aligned_allocator_indirection<U> other;
|
|
||||||
};
|
|
||||||
|
|
||||||
aligned_allocator_indirection() throw() {}
|
|
||||||
aligned_allocator_indirection(const aligned_allocator_indirection& ) throw() : aligned_allocator<T>() {}
|
|
||||||
aligned_allocator_indirection(const aligned_allocator<T>& ) throw() {}
|
|
||||||
template<class U>
|
|
||||||
aligned_allocator_indirection(const aligned_allocator_indirection<U>& ) throw() {}
|
|
||||||
template<class U>
|
|
||||||
aligned_allocator_indirection(const aligned_allocator<U>& ) throw() {}
|
|
||||||
~aligned_allocator_indirection() throw() {}
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
|
|
||||||
// sometimes, MSVC detects, at compile time, that the argument x
|
|
||||||
// in std::vector::resize(size_t s,T x) won't be aligned and generate an error
|
|
||||||
// even if this function is never called. Whence this little wrapper.
|
|
||||||
#define EIGEN_WORKAROUND_MSVC_STD_VECTOR(T) Eigen::ei_workaround_msvc_std_vector<T>
|
|
||||||
template<typename T> struct ei_workaround_msvc_std_vector : public T
|
|
||||||
{
|
|
||||||
inline ei_workaround_msvc_std_vector() : T() {}
|
|
||||||
inline ei_workaround_msvc_std_vector(const T& other) : T(other) {}
|
|
||||||
inline operator T& () { return *static_cast<T*>(this); }
|
|
||||||
inline operator const T& () const { return *static_cast<const T*>(this); }
|
|
||||||
template<typename OtherT>
|
|
||||||
inline T& operator=(const OtherT& other)
|
|
||||||
{ T::operator=(other); return *this; }
|
|
||||||
inline ei_workaround_msvc_std_vector& operator=(const ei_workaround_msvc_std_vector& other)
|
|
||||||
{ T::operator=(other); return *this; }
|
|
||||||
};
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#define EIGEN_WORKAROUND_MSVC_STD_VECTOR(T) T
|
#include "src/StlSupport/StdVector.h"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace std {
|
|
||||||
|
|
||||||
#define EIGEN_STD_VECTOR_SPECIALIZATION_BODY \
|
|
||||||
public: \
|
|
||||||
typedef T value_type; \
|
|
||||||
typedef typename vector_base::allocator_type allocator_type; \
|
|
||||||
typedef typename vector_base::size_type size_type; \
|
|
||||||
typedef typename vector_base::iterator iterator; \
|
|
||||||
typedef typename vector_base::const_iterator const_iterator; \
|
|
||||||
explicit vector(const allocator_type& a = allocator_type()) : vector_base(a) {} \
|
|
||||||
template<typename InputIterator> \
|
|
||||||
vector(InputIterator first, InputIterator last, const allocator_type& a = allocator_type()) \
|
|
||||||
: vector_base(first, last, a) {} \
|
|
||||||
vector(const vector& c) : vector_base(c) {} \
|
|
||||||
explicit vector(size_type num, const value_type& val = value_type()) : vector_base(num, val) {} \
|
|
||||||
vector(iterator start, iterator end) : vector_base(start, end) {} \
|
|
||||||
vector& operator=(const vector& x) { \
|
|
||||||
vector_base::operator=(x); \
|
|
||||||
return *this; \
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
class vector<T,Eigen::aligned_allocator<T> >
|
|
||||||
: public vector<EIGEN_WORKAROUND_MSVC_STD_VECTOR(T),
|
|
||||||
Eigen::aligned_allocator_indirection<EIGEN_WORKAROUND_MSVC_STD_VECTOR(T)> >
|
|
||||||
{
|
|
||||||
typedef vector<EIGEN_WORKAROUND_MSVC_STD_VECTOR(T),
|
|
||||||
Eigen::aligned_allocator_indirection<EIGEN_WORKAROUND_MSVC_STD_VECTOR(T)> > vector_base;
|
|
||||||
EIGEN_STD_VECTOR_SPECIALIZATION_BODY
|
|
||||||
|
|
||||||
void resize(size_type new_size)
|
|
||||||
{ resize(new_size, T()); }
|
|
||||||
|
|
||||||
#if defined(_VECTOR_)
|
|
||||||
// workaround MSVC std::vector implementation
|
|
||||||
void resize(size_type new_size, const value_type& x)
|
|
||||||
{
|
|
||||||
if (vector_base::size() < new_size)
|
|
||||||
vector_base::_Insert_n(vector_base::end(), new_size - vector_base::size(), x);
|
|
||||||
else if (new_size < vector_base::size())
|
|
||||||
vector_base::erase(vector_base::begin() + new_size, vector_base::end());
|
|
||||||
}
|
|
||||||
void push_back(const value_type& x)
|
|
||||||
{ vector_base::push_back(x); }
|
|
||||||
using vector_base::insert;
|
|
||||||
iterator insert(const_iterator position, const value_type& x)
|
|
||||||
{ return vector_base::insert(position,x); }
|
|
||||||
void insert(const_iterator position, size_type new_size, const value_type& x)
|
|
||||||
{ vector_base::insert(position, new_size, x); }
|
|
||||||
#elif defined(_GLIBCXX_VECTOR) && EIGEN_GNUC_AT_LEAST(4,2)
|
|
||||||
// workaround GCC std::vector implementation
|
|
||||||
void resize(size_type new_size, const value_type& x)
|
|
||||||
{
|
|
||||||
if (new_size < vector_base::size())
|
|
||||||
vector_base::_M_erase_at_end(this->_M_impl._M_start + new_size);
|
|
||||||
else
|
|
||||||
vector_base::insert(vector_base::end(), new_size - vector_base::size(), x);
|
|
||||||
}
|
|
||||||
#elif defined(_GLIBCXX_VECTOR) && (!EIGEN_GNUC_AT_LEAST(4,1))
|
|
||||||
// Note that before gcc-4.1 we already have: std::vector::resize(size_type,const T&),
|
|
||||||
// no no need to workaround !
|
|
||||||
using vector_base::resize;
|
|
||||||
#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 < vector_base::size())
|
|
||||||
vector_base::erase(vector_base::begin() + new_size, vector_base::end());
|
|
||||||
else if (new_size > vector_base::size())
|
|
||||||
vector_base::insert(vector_base::end(), new_size - vector_base::size(), x);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // EIGEN_STDVECTOR_MODULE_H
|
#endif // EIGEN_STDVECTOR_MODULE_H
|
||||||
/* vim: set filetype=cpp et sw=2 ts=2 ai: */
|
|
||||||
|
|
||||||
|
124
Eigen/src/StlSupport/StdList.h
Normal file
124
Eigen/src/StlSupport/StdList.h
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
// This file is part of Eigen, a lightweight C++ template library
|
||||||
|
// for linear algebra.
|
||||||
|
//
|
||||||
|
// 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_STDLIST_H
|
||||||
|
#define EIGEN_STDLIST_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_LIST_INSTANTIATION(...) template class std::list<__VA_ARGS__, Eigen::aligned_allocator<__VA_ARGS__> >;
|
||||||
|
#else
|
||||||
|
#define EIGEN_EXPLICIT_STL_LIST_INSTANTIATION(...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This section contains a convenience MACRO which allows an easy specialization of
|
||||||
|
* std::list such that for data types with alignment issues the correct allocator
|
||||||
|
* is used automatically.
|
||||||
|
*/
|
||||||
|
#define EIGEN_DEFINE_STL_LIST_SPECIALIZATION(...) \
|
||||||
|
EIGEN_EXPLICIT_STL_LIST_INSTANTIATION(__VA_ARGS__) \
|
||||||
|
namespace std \
|
||||||
|
{ \
|
||||||
|
template<typename _Ay> \
|
||||||
|
class list<__VA_ARGS__, _Ay> \
|
||||||
|
: public list<__VA_ARGS__, Eigen::aligned_allocator<__VA_ARGS__> > \
|
||||||
|
{ \
|
||||||
|
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; \
|
||||||
|
typedef typename list_base::size_type size_type; \
|
||||||
|
typedef typename list_base::iterator iterator; \
|
||||||
|
explicit list(const allocator_type& a = allocator_type()) : list_base(a) {} \
|
||||||
|
template<typename InputIterator> \
|
||||||
|
list(InputIterator first, InputIterator last, const allocator_type& a = allocator_type()) : list_base(first, last, a) {} \
|
||||||
|
list(const list& c) : list_base(c) {} \
|
||||||
|
explicit list(size_type num, const value_type& val = value_type()) : list_base(num, val) {} \
|
||||||
|
list(iterator start, iterator end) : list_base(start, end) {} \
|
||||||
|
list& operator=(const list& x) { \
|
||||||
|
list_base::operator=(x); \
|
||||||
|
return *this; \
|
||||||
|
} \
|
||||||
|
}; \
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace std
|
||||||
|
{
|
||||||
|
|
||||||
|
#define EIGEN_STD_LIST_SPECIALIZATION_BODY \
|
||||||
|
public: \
|
||||||
|
typedef T value_type; \
|
||||||
|
typedef typename list_base::allocator_type allocator_type; \
|
||||||
|
typedef typename list_base::size_type size_type; \
|
||||||
|
typedef typename list_base::iterator iterator; \
|
||||||
|
typedef typename list_base::const_iterator const_iterator; \
|
||||||
|
explicit list(const allocator_type& a = allocator_type()) : list_base(a) {} \
|
||||||
|
template<typename InputIterator> \
|
||||||
|
list(InputIterator first, InputIterator last, const allocator_type& a = allocator_type()) \
|
||||||
|
: list_base(first, last, a) {} \
|
||||||
|
list(const list& c) : list_base(c) {} \
|
||||||
|
explicit list(size_type num, const value_type& val = value_type()) : list_base(num, val) {} \
|
||||||
|
list(iterator start, iterator end) : list_base(start, end) {} \
|
||||||
|
list& operator=(const list& x) { \
|
||||||
|
list_base::operator=(x); \
|
||||||
|
return *this; \
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename 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)> >
|
||||||
|
{
|
||||||
|
typedef list<EIGEN_WORKAROUND_MSVC_STL_SUPPORT(T),
|
||||||
|
Eigen::aligned_allocator_indirection<EIGEN_WORKAROUND_MSVC_STL_SUPPORT(T)> > list_base;
|
||||||
|
EIGEN_STD_LIST_SPECIALIZATION_BODY
|
||||||
|
|
||||||
|
void resize(size_type new_size)
|
||||||
|
{ resize(new_size, T()); }
|
||||||
|
|
||||||
|
void resize(size_type new_size, const value_type& x)
|
||||||
|
{
|
||||||
|
if (list_base::size() < new_size)
|
||||||
|
list_base::insert(list_base::end(), new_size - list_base::size(), x);
|
||||||
|
else
|
||||||
|
while (new_size < list_base::size()) list_base::pop_back();
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(_LIST_)
|
||||||
|
// workaround MSVC std::list implementation
|
||||||
|
void push_back(const value_type& x)
|
||||||
|
{ list_base::push_back(x); }
|
||||||
|
using list_base::insert;
|
||||||
|
iterator insert(const_iterator position, const value_type& x)
|
||||||
|
{ return list_base::insert(position,x); }
|
||||||
|
void insert(const_iterator position, size_type new_size, const value_type& x)
|
||||||
|
{ list_base::insert(position, new_size, x); }
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // EIGEN_STDLIST_H
|
144
Eigen/src/StlSupport/StdVector.h
Normal file
144
Eigen/src/StlSupport/StdVector.h
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
// This file is part of Eigen, a lightweight C++ template library
|
||||||
|
// for linear algebra.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2009 Gael Guennebaud <g.gael@free.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_STDVECTOR_H
|
||||||
|
#define EIGEN_STDVECTOR_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_VECTOR_INSTANTIATION(...) template class std::vector<__VA_ARGS__, Eigen::aligned_allocator<__VA_ARGS__> >;
|
||||||
|
#else
|
||||||
|
#define EIGEN_EXPLICIT_STL_VECTOR_INSTANTIATION(...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This section contains a convenience MACRO which allows an easy specialization of
|
||||||
|
* std::vector such that for data types with alignment issues the correct allocator
|
||||||
|
* is used automatically.
|
||||||
|
*/
|
||||||
|
#define EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION(...) \
|
||||||
|
EIGEN_EXPLICIT_STL_VECTOR_INSTANTIATION(__VA_ARGS__) \
|
||||||
|
namespace std \
|
||||||
|
{ \
|
||||||
|
template<typename _Ay> \
|
||||||
|
class vector<__VA_ARGS__, _Ay> \
|
||||||
|
: public vector<__VA_ARGS__, Eigen::aligned_allocator<__VA_ARGS__> > \
|
||||||
|
{ \
|
||||||
|
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; \
|
||||||
|
typedef typename vector_base::size_type size_type; \
|
||||||
|
typedef typename vector_base::iterator iterator; \
|
||||||
|
explicit vector(const allocator_type& a = allocator_type()) : vector_base(a) {} \
|
||||||
|
template<typename InputIterator> \
|
||||||
|
vector(InputIterator first, InputIterator last, const allocator_type& a = allocator_type()) : vector_base(first, last, a) {} \
|
||||||
|
vector(const vector& c) : vector_base(c) {} \
|
||||||
|
explicit vector(size_type num, const value_type& val = value_type()) : vector_base(num, val) {} \
|
||||||
|
vector(iterator start, iterator end) : vector_base(start, end) {} \
|
||||||
|
vector& operator=(const vector& x) { \
|
||||||
|
vector_base::operator=(x); \
|
||||||
|
return *this; \
|
||||||
|
} \
|
||||||
|
}; \
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace std {
|
||||||
|
|
||||||
|
#define EIGEN_STD_VECTOR_SPECIALIZATION_BODY \
|
||||||
|
public: \
|
||||||
|
typedef T value_type; \
|
||||||
|
typedef typename vector_base::allocator_type allocator_type; \
|
||||||
|
typedef typename vector_base::size_type size_type; \
|
||||||
|
typedef typename vector_base::iterator iterator; \
|
||||||
|
typedef typename vector_base::const_iterator const_iterator; \
|
||||||
|
explicit vector(const allocator_type& a = allocator_type()) : vector_base(a) {} \
|
||||||
|
template<typename InputIterator> \
|
||||||
|
vector(InputIterator first, InputIterator last, const allocator_type& a = allocator_type()) \
|
||||||
|
: vector_base(first, last, a) {} \
|
||||||
|
vector(const vector& c) : vector_base(c) {} \
|
||||||
|
explicit vector(size_type num, const value_type& val = value_type()) : vector_base(num, val) {} \
|
||||||
|
vector(iterator start, iterator end) : vector_base(start, end) {} \
|
||||||
|
vector& operator=(const vector& x) { \
|
||||||
|
vector_base::operator=(x); \
|
||||||
|
return *this; \
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename 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)> >
|
||||||
|
{
|
||||||
|
typedef vector<EIGEN_WORKAROUND_MSVC_STL_SUPPORT(T),
|
||||||
|
Eigen::aligned_allocator_indirection<EIGEN_WORKAROUND_MSVC_STL_SUPPORT(T)> > vector_base;
|
||||||
|
EIGEN_STD_VECTOR_SPECIALIZATION_BODY
|
||||||
|
|
||||||
|
void resize(size_type new_size)
|
||||||
|
{ resize(new_size, T()); }
|
||||||
|
|
||||||
|
#if defined(_VECTOR_)
|
||||||
|
// workaround MSVC std::vector implementation
|
||||||
|
void resize(size_type new_size, const value_type& x)
|
||||||
|
{
|
||||||
|
if (vector_base::size() < new_size)
|
||||||
|
vector_base::_Insert_n(vector_base::end(), new_size - vector_base::size(), x);
|
||||||
|
else if (new_size < vector_base::size())
|
||||||
|
vector_base::erase(vector_base::begin() + new_size, vector_base::end());
|
||||||
|
}
|
||||||
|
void push_back(const value_type& x)
|
||||||
|
{ vector_base::push_back(x); }
|
||||||
|
using vector_base::insert;
|
||||||
|
iterator insert(const_iterator position, const value_type& x)
|
||||||
|
{ return vector_base::insert(position,x); }
|
||||||
|
void insert(const_iterator position, size_type new_size, const value_type& x)
|
||||||
|
{ vector_base::insert(position, new_size, x); }
|
||||||
|
#elif defined(_GLIBCXX_VECTOR) && EIGEN_GNUC_AT_LEAST(4,2)
|
||||||
|
// workaround GCC std::vector implementation
|
||||||
|
void resize(size_type new_size, const value_type& x)
|
||||||
|
{
|
||||||
|
if (new_size < vector_base::size())
|
||||||
|
vector_base::_M_erase_at_end(this->_M_impl._M_start + new_size);
|
||||||
|
else
|
||||||
|
vector_base::insert(vector_base::end(), new_size - vector_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 < vector_base::size())
|
||||||
|
vector_base::erase(vector_base::begin() + new_size, vector_base::end());
|
||||||
|
else if (new_size > vector_base::size())
|
||||||
|
vector_base::insert(vector_base::end(), new_size - vector_base::size(), x);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // EIGEN_STDVECTOR_H
|
87
Eigen/src/StlSupport/details.h
Normal file
87
Eigen/src/StlSupport/details.h
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
// This file is part of Eigen, a lightweight C++ template library
|
||||||
|
// for linear algebra.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2009 Gael Guennebaud <g.gael@free.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_STL_DETAILS_H
|
||||||
|
#define EIGEN_STL_DETAILS_H
|
||||||
|
|
||||||
|
namespace Eigen {
|
||||||
|
|
||||||
|
// This one is needed to prevent reimplementing the whole std::vector.
|
||||||
|
template <class T>
|
||||||
|
class aligned_allocator_indirection : public aligned_allocator<T>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef size_t size_type;
|
||||||
|
typedef ptrdiff_t difference_type;
|
||||||
|
typedef T* pointer;
|
||||||
|
typedef const T* const_pointer;
|
||||||
|
typedef T& reference;
|
||||||
|
typedef const T& const_reference;
|
||||||
|
typedef T value_type;
|
||||||
|
|
||||||
|
template<class U>
|
||||||
|
struct rebind
|
||||||
|
{
|
||||||
|
typedef aligned_allocator_indirection<U> other;
|
||||||
|
};
|
||||||
|
|
||||||
|
aligned_allocator_indirection() {}
|
||||||
|
aligned_allocator_indirection(const aligned_allocator_indirection& ) : aligned_allocator<T>() {}
|
||||||
|
aligned_allocator_indirection(const 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() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
|
||||||
|
// sometimes, MSVC detects, at compile time, that the argument x
|
||||||
|
// in std::vector::resize(size_t s,T x) won't be aligned and generate an error
|
||||||
|
// even if this function is never called. Whence this little wrapper.
|
||||||
|
#define EIGEN_WORKAROUND_MSVC_STL_SUPPORT(T) Eigen::ei_workaround_msvc_stl_support<T>
|
||||||
|
template<typename T> struct ei_workaround_msvc_stl_support : public T
|
||||||
|
{
|
||||||
|
inline ei_workaround_msvc_stl_support() : T() {}
|
||||||
|
inline ei_workaround_msvc_stl_support(const T& other) : T(other) {}
|
||||||
|
inline operator T& () { return *static_cast<T*>(this); }
|
||||||
|
inline operator const T& () const { return *static_cast<const T*>(this); }
|
||||||
|
template<typename OtherT>
|
||||||
|
inline T& operator=(const OtherT& other)
|
||||||
|
{ T::operator=(other); return *this; }
|
||||||
|
inline ei_workaround_msvc_stl_support& operator=(const ei_workaround_msvc_stl_support& other)
|
||||||
|
{ T::operator=(other); return *this; }
|
||||||
|
};
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define EIGEN_WORKAROUND_MSVC_STL_SUPPORT(T) T
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // EIGEN_STL_DETAILS_H
|
@ -157,6 +157,7 @@ ei_add_test(geo_alignedbox)
|
|||||||
ei_add_test(regression)
|
ei_add_test(regression)
|
||||||
ei_add_test(stdvector)
|
ei_add_test(stdvector)
|
||||||
ei_add_test(stdvector_overload)
|
ei_add_test(stdvector_overload)
|
||||||
|
ei_add_test(stdlist)
|
||||||
ei_add_test(resize)
|
ei_add_test(resize)
|
||||||
if(QT4_FOUND)
|
if(QT4_FOUND)
|
||||||
ei_add_test(qtvector " " "${QT_QTCORE_LIBRARY}")
|
ei_add_test(qtvector " " "${QT_QTCORE_LIBRARY}")
|
||||||
|
146
test/stdlist.cpp
Normal file
146
test/stdlist.cpp
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
// This file is part of Eigen, a lightweight C++ template library
|
||||||
|
// for linear algebra.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>
|
||||||
|
// Copyright (C) 2010 Hauke Heibel <hauke.heibel@gmail.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/>.
|
||||||
|
|
||||||
|
#include "main.h"
|
||||||
|
#include <Eigen/StdList>
|
||||||
|
#include <Eigen/Geometry>
|
||||||
|
|
||||||
|
template<typename MatrixType>
|
||||||
|
void check_stdlist_matrix(const MatrixType& m)
|
||||||
|
{
|
||||||
|
int rows = m.rows();
|
||||||
|
int cols = m.cols();
|
||||||
|
MatrixType x = MatrixType::Random(rows,cols), y = MatrixType::Random(rows,cols);
|
||||||
|
std::list<MatrixType,Eigen::aligned_allocator<MatrixType> > v(10, MatrixType(rows,cols)), w(20, y);
|
||||||
|
v.front() = x;
|
||||||
|
w.front() = w.back();
|
||||||
|
VERIFY_IS_APPROX(w.front(), w.back());
|
||||||
|
v = w;
|
||||||
|
|
||||||
|
typename std::list<MatrixType,Eigen::aligned_allocator<MatrixType> >::iterator vi = v.begin();
|
||||||
|
typename std::list<MatrixType,Eigen::aligned_allocator<MatrixType> >::iterator wi = w.begin();
|
||||||
|
for(int i = 0; i < 20; i++)
|
||||||
|
{
|
||||||
|
VERIFY_IS_APPROX(*vi, *wi);
|
||||||
|
++vi;
|
||||||
|
++wi;
|
||||||
|
}
|
||||||
|
|
||||||
|
v.resize(21);
|
||||||
|
v.back() = x;
|
||||||
|
VERIFY_IS_APPROX(v.back(), x);
|
||||||
|
v.resize(22,y);
|
||||||
|
VERIFY_IS_APPROX(v.back(), y);
|
||||||
|
v.push_back(x);
|
||||||
|
VERIFY_IS_APPROX(v.back(), x);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename TransformType>
|
||||||
|
void check_stdlist_transform(const TransformType&)
|
||||||
|
{
|
||||||
|
typedef typename TransformType::MatrixType MatrixType;
|
||||||
|
TransformType x(MatrixType::Random()), y(MatrixType::Random());
|
||||||
|
std::list<TransformType,Eigen::aligned_allocator<TransformType> > v(10), w(20, y);
|
||||||
|
v.front() = x;
|
||||||
|
w.front() = w.back();
|
||||||
|
VERIFY_IS_APPROX(w.front(), w.back());
|
||||||
|
v = w;
|
||||||
|
|
||||||
|
typename std::list<TransformType,Eigen::aligned_allocator<TransformType> >::iterator vi = v.begin();
|
||||||
|
typename std::list<TransformType,Eigen::aligned_allocator<TransformType> >::iterator wi = w.begin();
|
||||||
|
for(int i = 0; i < 20; i++)
|
||||||
|
{
|
||||||
|
VERIFY_IS_APPROX(*vi, *wi);
|
||||||
|
++vi;
|
||||||
|
++wi;
|
||||||
|
}
|
||||||
|
|
||||||
|
v.resize(21);
|
||||||
|
v.back() = x;
|
||||||
|
VERIFY_IS_APPROX(v.back(), x);
|
||||||
|
v.resize(22,y);
|
||||||
|
VERIFY_IS_APPROX(v.back(), y);
|
||||||
|
v.push_back(x);
|
||||||
|
VERIFY_IS_APPROX(v.back(), x);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename QuaternionType>
|
||||||
|
void check_stdlist_quaternion(const QuaternionType&)
|
||||||
|
{
|
||||||
|
typedef typename QuaternionType::Coefficients Coefficients;
|
||||||
|
QuaternionType x(Coefficients::Random()), y(Coefficients::Random());
|
||||||
|
std::list<QuaternionType,Eigen::aligned_allocator<QuaternionType> > v(10), w(20, y);
|
||||||
|
v.front() = x;
|
||||||
|
w.front() = w.back();
|
||||||
|
VERIFY_IS_APPROX(w.front(), w.back());
|
||||||
|
v = w;
|
||||||
|
|
||||||
|
typename std::list<QuaternionType,Eigen::aligned_allocator<QuaternionType> >::iterator vi = v.begin();
|
||||||
|
typename std::list<QuaternionType,Eigen::aligned_allocator<QuaternionType> >::iterator wi = w.begin();
|
||||||
|
for(int i = 0; i < 20; i++)
|
||||||
|
{
|
||||||
|
VERIFY_IS_APPROX(*vi, *wi);
|
||||||
|
++vi;
|
||||||
|
++wi;
|
||||||
|
}
|
||||||
|
|
||||||
|
v.resize(21);
|
||||||
|
v.back() = x;
|
||||||
|
VERIFY_IS_APPROX(v.back(), x);
|
||||||
|
v.resize(22,y);
|
||||||
|
VERIFY_IS_APPROX(v.back(), y);
|
||||||
|
v.push_back(x);
|
||||||
|
VERIFY_IS_APPROX(v.back(), x);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_stdlist()
|
||||||
|
{
|
||||||
|
// some non vectorizable fixed sizes
|
||||||
|
CALL_SUBTEST_1(check_stdlist_matrix(Vector2f()));
|
||||||
|
CALL_SUBTEST_1(check_stdlist_matrix(Matrix3f()));
|
||||||
|
CALL_SUBTEST_2(check_stdlist_matrix(Matrix3d()));
|
||||||
|
|
||||||
|
// some vectorizable fixed sizes
|
||||||
|
CALL_SUBTEST_1(check_stdlist_matrix(Matrix2f()));
|
||||||
|
CALL_SUBTEST_1(check_stdlist_matrix(Vector4f()));
|
||||||
|
CALL_SUBTEST_1(check_stdlist_matrix(Matrix4f()));
|
||||||
|
CALL_SUBTEST_2(check_stdlist_matrix(Matrix4d()));
|
||||||
|
|
||||||
|
// some dynamic sizes
|
||||||
|
CALL_SUBTEST_3(check_stdlist_matrix(MatrixXd(1,1)));
|
||||||
|
CALL_SUBTEST_3(check_stdlist_matrix(VectorXd(20)));
|
||||||
|
CALL_SUBTEST_3(check_stdlist_matrix(RowVectorXf(20)));
|
||||||
|
CALL_SUBTEST_3(check_stdlist_matrix(MatrixXcf(10,10)));
|
||||||
|
|
||||||
|
// some Transform
|
||||||
|
CALL_SUBTEST_4(check_stdlist_transform(Transform2f()));
|
||||||
|
CALL_SUBTEST_4(check_stdlist_transform(Transform3f()));
|
||||||
|
CALL_SUBTEST_4(check_stdlist_transform(Transform3d()));
|
||||||
|
//CALL_SUBTEST(heck_stdvector_transform(Transform4d()));
|
||||||
|
|
||||||
|
// some Quaternion
|
||||||
|
CALL_SUBTEST_5(check_stdlist_quaternion(Quaternionf()));
|
||||||
|
CALL_SUBTEST_5(check_stdlist_quaternion(Quaterniond()));
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user