Re: [eigen] Re: about std::vector::resize (again)

[ Thread Index | Date Index | More lists.tuxfamily.org/eigen Archives ]


It seems reasonable to allow 0 sized arrays. In some cases having 0 sized arrays prevents writing special cases in code.

Keir

On Fri, Feb 6, 2009 at 9:17 AM, Gael Guennebaud <gael.guennebaud@xxxxxxxxx> wrote:
I forgot to mention that this would also requires to allow Matrix to
resize to 0. Eg:

std::vector<MatrixXf> data;
data.resize(10);

I don't see any reason why we could not allow that. In the worst case
we simply remove the assertion and everything is fine, unless a wasted
memory (on my 64bits linux, a malloc(0) cost 32 bytes). So we could
add a test in MatrixStorage::resize(size_t). A call to this is
extremely rare and anyway, the cost of a if compared to a call to
malloc....

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.
>





Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/