On Fri, Feb 6, 2009 at 5:59 PM, Gael Guennebaud
<
gael.guennebaud@xxxxxxxxx> wrote:
> Hi list,
>
> as some of you know, and as a user remind us on the forum, we have not
> finished yet the support for std::vector.
>
> Indeed, the problem still occurs for custom classes having fixed size
> Eigen objects:
>
> struct A {
> Vector4f x;
> Matrix4f m;
> EIGEN_MAKE_ALIGNED_OPERATOR_NEW
> };
>
> std::vector<A,aligned_allocator> will fail because of bugged
> vector<T>::resize(size_t,T). Our current solution is OK for Eigen's
> types for which we workaround via several tricks. However this
> solution is not extensible to user types (have to add special
> constructor to discard the assertion, the specializations of
> std::vector cannot be automatically generated by a macro, etc..).
>
> So here is what I propose: let's be ugly !
>
>
> #if define(_GLIBCXX_VECTOR) || define(_VECTOR_)
> #error you must include Eigen/StdVector before std::vector
> #endif
>
> #define vector std_vector
> #include <vector>
> #undef vector
>
> // now std::vector is actually reachable as std::std_vector !
>
> namespace std {
>
> // let's define our own std::vector inheriting the initial std::std_vector
> template<typename T, typename AllocT = Eigen::aligned_allocator<T> >
> class vector : public std::std_vector<T,AllocT>
> {
> typedef std::std_vector<T,AllocT> Base;
> public:
> vector() : Base() {}
> vector(size_t s) : Base(s) {}
> vector(size_t s, const T& v) : Base(s,v) {}
> vector(const vector& v) : Base(v) {}
> vector& operator=(const vector& v) { Base::operator=(v); return *this; }
>
> void resize(size_type __new_size)
> { resize(__new_size, T()); }
>
> #if defined(_GLIBCXX_VECTOR)
> void resize(size_type __new_size, const T& __x)
> {
> if (__new_size < size())
> Base::_M_erase_at_end(this->_M_impl._M_start + __new_size);
> else
> Base::insert(Base::end(), __new_size - Base::size(), __x);
> }
> #elif defined(_VECTOR_)
> // workaround MSVC's vector
> void resize(size_type _Newsize, const T& _Val)
> {
> if (Base::size() < _Newsize)
> Base::_Insert_n(Base::end(), _Newsize - Base::size(), _Val);
> else if (_Newsize < Base::size())
> Base::erase(Base::begin() + _Newsize, Base::end());
> }
> #endif
> };
>
> }
>
>
> yes I know this a bit ugly, but I don't know better solution to tackle
> this issue once for all. Of course this is just a starting point. If
> that really works, the next step is to have a specialization of
> std::vector for classes having EIGEN_MAKE_ALIGNED_OPERATOR_NEW (this
> is easy to detect), and do the workaround + "aligned_allocator as
> default" only in this specialization.
>
> I'll test it with MSVC tonight, and let you know.
>
> cheers,
> Gael.
>