Maxim Yegorushkin
11/27/2008 11:52:00 AM
On Nov 26, 6:06 pm, zr <zvir...@gmail.com> wrote:
> On Nov 26, 7:32 pm, Maxim Yegorushkin <maxim.yegorush...@gmail.com>
> wrote:
>
>
>
> > On Nov 26, 5:03 pm, Maxim Yegorushkin <maxim.yegorush...@gmail.com>
> > wrote:
>
> > > On Nov 26, 4:42 pm, zr <zvir...@gmail.com> wrote:
>
> > > > I need to use STL containers that allocate aligned memory.
>
> > > Why?
>
> > > > My compiler provides an aligned_malloc routine.
>
> > > It is probably provided by a library shipped with the compiler, not by
> > > compiler itself.
>
> > > > How can this be accomplished?
>
> > > Something like this:
>
> > > #include <memory>
> > > #include <stdexcept>
>
> > > template<class T, size_t alignment>
> > > struct aligned_allocator : std::allocator<T>
> > > {
> > > template<class U>
> > > struct rebind { typedef aligned_allocator<U, alignment> other; };
>
> > > typedef std::allocator<T> base;
>
> > > typedef typename base::pointer pointer;
> > > typedef typename base::size_type size_type;
>
> > > pointer allocate(size_type n)
> > > {
> > > if(pointer p = (pointer)aligned_malloc(n, alignment))
> > > return p;
> > > throw std::bad_alloc("aligned_allocator");
> > > }
>
> > > pointer allocate(size_type n, void const*)
> > > {
> > > return this->allocate(n);
> > > }
>
> > > void deallocate(pointer p, size_type)
> > > {
> > > aligned_free(p);
> > > }
>
> > > };
>
> > Usage is:
>
> > typedef std::vector<X, aligned_allocator<X, required_alignment> >
> > VecX;
>
> > --
> > Max
>
> Max, thanks. I wrote a quick test on your proposal. Unfortunately, got
> a compilation error:
> C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\xutility
> (419) : error C2664: 'aligned_allocator<T,alignment>::aligned_allocator
> (const aligned_allocator<T,alignment> &) throw()' : cannot convert
> parameter 1 from 'aligned_allocator<T,alignment>' to 'const
> aligned_allocator<T,alignment> &'
> with
> [
> T=std::_Aux_cont,
> alignment=64
> ]
> and
> [
> T=int,
> alignment=64
> ]
> and
> [
> T=std::_Aux_cont,
> alignment=64
> ]
> Reason: cannot convert from 'aligned_allocator<T,alignment>'
> to 'const aligned_allocator<T,alignment>'
> with
> [
> T=int,
> alignment=64
> ]
> and
> [
> T=std::_Aux_cont,
> alignment=64
> ]
> No user-defined-conversion operator available that can perform
> this conversion, or the operator cannot be called
> C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include
> \xutility(417) : while compiling class template member function
> 'std::_Container_base_aux_alloc_real<_Alloc>::_Container_base_aux_alloc_real
> (_Alloc)'
> with
> [
> _Alloc=aligned_allocator<int,64>
> ]
> C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include
> \vector(421) : see reference to class template instantiation
> 'std::_Container_base_aux_alloc_real<_Alloc>' being compiled
> with
> [
> _Alloc=aligned_allocator<int,64>
> ]
> C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include
> \vector(439) : see reference to class template instantiation
> 'std::_Vector_val<_Ty,_Alloc>' being compiled
> with
> [
> _Ty=int,
> _Alloc=aligned_allocator<int,64>
> ]
> .\main.cpp(38) : see reference to class template instantiation
> 'std::vector<_Ty,_Ax>' being compiled
> with
> [
> _Ty=int,
> _Ax=aligned_allocator<int,64>
> ]
>
> Following is the source of the test:
>
> #include <malloc.h>
> #include <memory>
> #include <stdexcept>
> #include <vector>
>
> template<class T, size_t alignment>
> struct aligned_allocator : std::allocator<T>
> {
> template<class U>
> struct rebind { typedef aligned_allocator<U, alignment> other; };
>
> typedef std::allocator<T> base;
>
> typedef typename base::pointer pointer;
> typedef typename base::size_type size_type;
>
> pointer allocate(size_type n)
> {
> if(pointer p = (pointer)_aligned_malloc(n, alignment))
> return p;
> throw std::bad_alloc("aligned_allocator");
> }
>
> pointer allocate(size_type n, void const*)
> {
> return this->allocate(n);
> }
>
> void deallocate(pointer p, size_type)
> {
> _aligned_free(p);
> }
>
> };
>
> int main(int argc, char* argv[])
> {
> std::vector<int, aligned_allocator<int, 64> > v(1024);
> }
Strange, it compiles fine with M$VC 2005. It looks like
aligned_allocator needs a conversion constructor. Try adding these
constructors:
aligned_allocator()
{}
template<class U>
aligned_allocator(U const&)
{}
--
Max