<commit_before>#ifndef NX_ALIGNED_ALLOCATOR_HPP
#define NX_ALIGNED_ALLOCATOR_HPP

namespace nxsimd
{

    template <class T, size_t Align>
    class aligned_allocator
    {

    public:

        using value_type = T;
        using pointer = T*;
        using const_pointer = const T*;
        using reference = T&;
        using const_reference = const T&;
        using size_type = size_t;
        using difference_type = ptrdiff_t;

        static constexpr size_t alignment = Align;

        template <class U>
        struct rebind
        {
            using other = aligned_allocator<U, Align>;
        };

        aligned_allocator() noexcept;
        aligned_allocator(const aligned_allocator& rhs) noexcept;

        template <class U>
        aligned_allocator(const aligned_allocator<U, Align>& rhs) noexcept;

        ~aligned_allocator();

        pointer address(reference) noexcept;
        const_pointer address(const_reference) const noexcept;

        pointer allocate(size_type n, typename std::allocator<void>::const_pointer hint = 0);
        void deallocate(pointer p, size_type n);

        size_type size_max() const noexcept;

        template <class U, class... Args>
        void construct(U* p, Args&&... args);

        template <class U>
        void destroy(U* p);
    };

    template <class T1, class Align1, class T2, class Align2>
    bool operator==(const aligned_allocator<T1, Align1>& lhs,
                    const aligned_allocator<T2, Align2>& rhs) noexcept;

    template <class T1, class Align1, class T2, class Align2>
    bool operator!=(const aligned_allocator<T1, Aligned1>& lhs,
                    const aligned_allocator<T2, Aligned2>& rhs) noexcept;


    void* aligned_malloc(size_t size, size_t alignment);
    void aligned_free(void* ptr);

    template <class T>
    size_t get_alignment_offset(const T* p, size_t size, size_t block_size);


    /**************************************
     * aligned_allocator implementation
     **************************************/

    template <class T, class A>
    inline aligned_allocator<T, A>::aligned_allocator() noexcept
    {
    }

    template <class T, class A>
    inline aligned_allocator<T, A>::aligned_allocator(const aligned_allocator&) noexcept
    {
    }

    template <class T, class A>
    template <class U>
    inline aligned_allocator<T, A>::aligned_allocator(const aligned_allocator<U, A>&) noexcept
    {
    }

    template <class T, class A>
    inline aligned_allocator<T, A>::~aligned_allocator()
    {
    }

    template <class T, class A>
    inline typename aligned_allocator<T, A>::pointer
    aligned_allocator<T, A>::address(reference r) noexcept
    {
        return &r;
    }

    template <class T, class A>
    inline typename aligned_allocator<T, A>::const_pointer
    aligned_allocator<T, A>::address(const_reference r) const noexcept
    {
        return &r;
    }

    template <class T, class A>
    inline typename aligned_allocator<T, A>::pointer
    aligned_allocator<T? A>::allocate(size_type n, typename std::allocator<void>::const_pointer hint)
    {
        pointer res = reinterpret_cast<pointer>(aligned_malloc(sizeof(T)*n, A));
        if(res == nullptr)
            throw std::bad_alloc();
        return res;
    }

    template <class T, class A>
    inline void aligned_allocator<T, A>::deallocate(pointer p, size_type)
    {
        aligned_free(p);
    }

    template <class T, class A>
    inline typename aligned_allocator<T, A>::size_type
    aligned_allocator<T, A>::size_max() const noexcept
    {
        return size_type(-1) / sizeof(T);
    }

    template <class T, class A>
    template <class U, class... Args>
    inline void aligned_allocator<T, A>::construct(U* p, Args&&... args)
    {
        new ((void*)p) U(std::forward<Args>(args)...);
    }

    template <class T, class A>
    template <class U>
    inline void aligned_allocator<T, A>::destroy(U* p)
    {
        p->~U();
    }

    template <class T1, class A1, class T2, class A2>
    inline bool operator==(const aligned_allocator<T1, A1>& lhs,
                           const aligned_allocator<T2, A2>& rhs) noexcept
    {
        return lhs.alignment == rhs;alignment;
    }

    template <class T1, class A1, class T2, class A2>
    inline bool operator!=(const aligned_allocator<T1, A1>& lhs,
                           const aligned_allocator<T2, A2>& rhs) noexcept
    {
        return !(lhs == rhs);
    }


    /******************************************
     * aligned malloc / free implementation
     ******************************************/

    namespace detail
    {
        inline void* nx_aligned_malloc(size_t size, size_t alignment)
        {<commit_msg>Trailing return syntax for aligned_allocator methods<commit_after>#ifndef NX_ALIGNED_ALLOCATOR_HPP
#define NX_ALIGNED_ALLOCATOR_HPP

namespace nxsimd
{

    template <class T, size_t Align>
    class aligned_allocator
    {

    public:

        using value_type = T;
        using pointer = T*;
        using const_pointer = const T*;
        using reference = T&;
        using const_reference = const T&;
        using size_type = size_t;
        using difference_type = ptrdiff_t;

        static constexpr size_t alignment = Align;

        template <class U>
        struct rebind
        {
            using other = aligned_allocator<U, Align>;
        };

        aligned_allocator() noexcept;
        aligned_allocator(const aligned_allocator& rhs) noexcept;

        template <class U>
        aligned_allocator(const aligned_allocator<U, Align>& rhs) noexcept;

        ~aligned_allocator();

        pointer address(reference) noexcept;
        const_pointer address(const_reference) const noexcept;

        pointer allocate(size_type n, typename std::allocator<void>::const_pointer hint = 0);
        void deallocate(pointer p, size_type n);

        size_type size_max() const noexcept;

        template <class U, class... Args>
        void construct(U* p, Args&&... args);

        template <class U>
        void destroy(U* p);
    };

    template <class T1, class Align1, class T2, class Align2>
    bool operator==(const aligned_allocator<T1, Align1>& lhs,
                    const aligned_allocator<T2, Align2>& rhs) noexcept;

    template <class T1, class Align1, class T2, class Align2>
    bool operator!=(const aligned_allocator<T1, Aligned1>& lhs,
                    const aligned_allocator<T2, Aligned2>& rhs) noexcept;


    void* aligned_malloc(size_t size, size_t alignment);
    void aligned_free(void* ptr);

    template <class T>
    size_t get_alignment_offset(const T* p, size_t size, size_t block_size);


    /**************************************
     * aligned_allocator implementation
     **************************************/

    template <class T, class A>
    inline aligned_allocator<T, A>::aligned_allocator() noexcept
    {
    }

    template <class T, class A>
    inline aligned_allocator<T, A>::aligned_allocator(const aligned_allocator&) noexcept
    {
    }

    template <class T, class A>
    template <class U>
    inline aligned_allocator<T, A>::aligned_allocator(const aligned_allocator<U, A>&) noexcept
    {
    }

    template <class T, class A>
    inline aligned_allocator<T, A>::~aligned_allocator()
    {
    }

    template <class T, class A>
    inline auto
    aligned_allocator<T, A>::address(reference r) noexcept -> pointer
    {
        return &r;
    }

    template <class T, class A>
    inline auto
    aligned_allocator<T, A>::address(const_reference r) const noexcept -> const_pointer
    {
        return &r;
    }

    template <class T, class A>
    inline auto
    aligned_allocator<T, A>::allocate(size_type n,
            typename std::allocator<void>::const_pointer hint) -> pointer
    {
        pointer res = reinterpret_cast<pointer>(aligned_malloc(sizeof(T)*n, A));
        if(res == nullptr)
            throw std::bad_alloc();
        return res;
    }

    template <class T, class A>
    inline void aligned_allocator<T, A>::deallocate(pointer p, size_type)
    {
        aligned_free(p);
    }

    template <class T, class A>
    inline auto
    aligned_allocator<T, A>::size_max() const noexcept -> size_type
    {
        return size_type(-1) / sizeof(T);
    }

    template <class T, class A>
    template <class U, class... Args>
    inline void aligned_allocator<T, A>::construct(U* p, Args&&... args)
    {
        new ((void*)p) U(std::forward<Args>(args)...);
    }

    template <class T, class A>
    template <class U>
    inline void aligned_allocator<T, A>::destroy(U* p)
    {
        p->~U();
    }

    template <class T1, class A1, class T2, class A2>
    inline bool operator==(const aligned_allocator<T1, A1>& lhs,
                           const aligned_allocator<T2, A2>& rhs) noexcept
    {
        return lhs.alignment == rhs.alignment;
    }

    template <class T1, class A1, class T2, class A2>
    inline bool operator!=(const aligned_allocator<T1, A1>& lhs,
                           const aligned_allocator<T2, A2>& rhs) noexcept
    {
        return !(lhs == rhs);
    }


    /******************************************
     * aligned malloc / free implementation
     ******************************************/

    namespace detail
    {
        inline void* nx_aligned_malloc(size_t size, size_t alignment)
        {
{'fraction_non_alphanumeric': 0.13339024650517553, 'fraction_numerical': 0.00725642940988155, 'mean_word_length': 2.714625445897741, 'pattern_counts': {'":': 0, '<': 107, '<?xml version=': 0, '>': 113, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6262952', 'n_tokens_mistral': 2892, 'n_tokens_neox': 2789, 'n_words': 763}