Ensure that numeric array storage is aligned to 256-byte boundary.

OpenCL devices require this else we would get a performance hit.

Change-Id: I6b1db6320fa84f933b6446022a0fd02ba267bf21
diff --git a/sc/inc/formulagroup.hxx b/sc/inc/formulagroup.hxx
index 3834e49..028a04d 100644
--- a/sc/inc/formulagroup.hxx
+++ b/sc/inc/formulagroup.hxx
@@ -13,6 +13,7 @@
#include "address.hxx"
#include "types.hxx"
#include "platforminfo.hxx"
#include <stlalgorithm.hxx>

#include "svl/sharedstringpool.hxx"

@@ -28,7 +29,7 @@ namespace sc {

struct FormulaGroupContext : boost::noncopyable
{
    typedef std::vector<double> NumArrayType;
    typedef std::vector<double, AlignedAllocator<double,256> > NumArrayType;
    typedef std::vector<rtl_uString*> StrArrayType;
    typedef boost::ptr_vector<NumArrayType> NumArrayStoreType;
    typedef boost::ptr_vector<StrArrayType> StrArrayStoreType;
diff --git a/sc/inc/stlalgorithm.hxx b/sc/inc/stlalgorithm.hxx
index fb5509f..be45e15 100644
--- a/sc/inc/stlalgorithm.hxx
+++ b/sc/inc/stlalgorithm.hxx
@@ -25,6 +25,97 @@ struct ScDeleteObjectByPtr : public ::std::unary_function<T*, void>
    }
};

namespace sc {

/**
 * Custom allocator for STL container to ensure that the base address of
 * allocated storage is aligned to a specified boundary.
 */
template<typename T, std::size_t N>
class AlignedAllocator
{
public:
    typedef T value_type;
    typedef std::size_t size_type;
    typedef std::ptrdiff_t difference_type;

    typedef T* pointer;
    typedef const T* const_pointer;
    typedef T* void_pointer;

    typedef T& reference;
    typedef const T& const_reference;

public:
    AlignedAllocator() throw() {}

    template<typename T2>
    AlignedAllocator(const AlignedAllocator<T2, N>&) throw() {}

    ~AlignedAllocator() throw() {}

    pointer adress(reference r)
    {
        return &r;
    }

    const_pointer adress(const_reference r) const
    {
        return &r;
    }

    pointer allocate(size_type n)
    {
#ifdef WNT
        return (pointer)_aligned_malloc(n * sizeof(value_type), N);
#else
        return (pointer)aligned_alloc(N, n * sizeof(value_type));
#endif
    }

    void deallocate(pointer p, size_type)
    {
#ifdef WNT
        _aligned_free(p);
#else
        free(p);
#endif
    }

    void construct(pointer p, const value_type& wert)
    {
        new(p) value_type(wert);
    }

    void destroy(pointer p)
    {
        p->~value_type();
    }

    size_type max_size() const throw()
    {
        return size_type(-1) / sizeof(value_type);
    }

    template<typename T2>
    struct rebind
    {
        typedef AlignedAllocator<T2, N> other;
    };

    bool operator==(const AlignedAllocator<T, N>& other) const
    {
        return true;
    }

    bool operator!=(const AlignedAllocator<T, N>& other) const
    {
        return !(*this == other);
    }
};

}

#endif

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */