/*
 * Copyright (c) 2012 Glen Joseph Fernandes 
 * glenfe at live dot com
 *
 * Distributed under the Boost Software License, 
 * Version 1.0. (See accompanying file LICENSE_1_0.txt 
 * or copy at http://boost.org/LICENSE_1_0.txt)
 */
#ifndef BOOST_SMART_PTR_DETAIL_ALLOCATE_ARRAY_HELPER_HPP
#define BOOST_SMART_PTR_DETAIL_ALLOCATE_ARRAY_HELPER_HPP

#include <ndnboost/type_traits/alignment_of.hpp>

namespace ndnboost {
    namespace detail {
        template<typename A, typename T, typename Y = char>
        class allocate_array_helper;
        template<typename A, typename T, typename Y>
        class allocate_array_helper<A, T[], Y> {
            template<typename A9, typename T9, typename Y9>
            friend class allocate_array_helper;
            typedef typename A::template rebind<Y>   ::other A2;
            typedef typename A::template rebind<char>::other A3;
        public:
            typedef typename A2::value_type      value_type;
            typedef typename A2::pointer         pointer;
            typedef typename A2::const_pointer   const_pointer;
            typedef typename A2::reference       reference;
            typedef typename A2::const_reference const_reference;
            typedef typename A2::size_type       size_type;
            typedef typename A2::difference_type difference_type;
            template<typename U>
            struct rebind {
                typedef allocate_array_helper<A, T[], U> other;
            };
            allocate_array_helper(const A& allocator, std::size_t size, T** data)
                : allocator(allocator),
                  size(sizeof(T) * size),
                  data(data) {
            }
            template<class U>
            allocate_array_helper(const allocate_array_helper<A, T[], U>& other) 
                : allocator(other.allocator),
                  size(other.size),
                  data(other.data) {
            }
            pointer address(reference value) const {
                return allocator.address(value);
            }
            const_pointer address(const_reference value) const {
                return allocator.address(value);
            }
            size_type max_size() const {
                return allocator.max_size();
            }
            pointer allocate(size_type count, const void* value = 0) {
                std::size_t a1 = ndnboost::alignment_of<T>::value;
                std::size_t n1 = count * sizeof(Y) + a1 - 1;
                char*  p1 = A3(allocator).allocate(n1 + size, value);
                char*  p2 = p1 + n1;
                while (std::size_t(p2) % a1 != 0) {
                    p2--;
                }
                *data = reinterpret_cast<T*>(p2);
                return  reinterpret_cast<Y*>(p1);
            }
            void deallocate(pointer memory, size_type count) {
                std::size_t a1 = ndnboost::alignment_of<T>::value;
                std::size_t n1 = count * sizeof(Y) + a1 - 1;
                char*  p1 = reinterpret_cast<char*>(memory);
                A3(allocator).deallocate(p1, n1 + size);
            }
            void construct(pointer memory, const Y& value) {
                allocator.construct(memory, value);
            }
            void destroy(pointer memory) {
                allocator.destroy(memory);
            }
            template<typename U>
            bool operator==(const allocate_array_helper<A, T[], U>& other) const {
                return allocator == other.allocator;
            }
            template<typename U>
            bool operator!=(const allocate_array_helper<A, T[], U>& other) const {
                return !(*this == other); 
            }
        private:
            A2 allocator;
            std::size_t size;
            T** data;
        };
        template<typename A, typename T, std::size_t N, typename Y>
        class allocate_array_helper<A, T[N], Y> {
            template<typename A9, typename T9, typename Y9>
            friend class allocate_array_helper;
            typedef typename A::template rebind<Y>   ::other A2;
            typedef typename A::template rebind<char>::other A3;
        public:
            typedef typename A2::value_type      value_type;
            typedef typename A2::pointer         pointer;
            typedef typename A2::const_pointer   const_pointer;
            typedef typename A2::reference       reference;
            typedef typename A2::const_reference const_reference;
            typedef typename A2::size_type       size_type;
            typedef typename A2::difference_type difference_type;
            template<typename U>
            struct rebind {
                typedef allocate_array_helper<A, T[N], U> other;
            };
            allocate_array_helper(const A& allocator, T** data)
                : allocator(allocator),
                  data(data) {
            }
            template<class U>
            allocate_array_helper(const allocate_array_helper<A, T[N], U>& other) 
                : allocator(other.allocator),
                  data(other.data) {
            }
            pointer address(reference value) const {
                return allocator.address(value);
            }
            const_pointer address(const_reference value) const {
                return allocator.address(value);
            }
            size_type max_size() const {
                return allocator.max_size();
            }
            pointer allocate(size_type count, const void* value = 0) {
                std::size_t a1 = ndnboost::alignment_of<T>::value;
                std::size_t n1 = count * sizeof(Y) + a1 - 1;
                char*  p1 = A3(allocator).allocate(n1 + N1, value);
                char*  p2 = p1 + n1;
                while (std::size_t(p2) % a1 != 0) {
                    p2--;
                }
                *data = reinterpret_cast<T*>(p2);
                return  reinterpret_cast<Y*>(p1);
            }
            void deallocate(pointer memory, size_type count) {
                std::size_t a1 = ndnboost::alignment_of<T>::value;
                std::size_t n1 = count * sizeof(Y) + a1 - 1;
                char*  p1 = reinterpret_cast<char*>(memory);
                A3(allocator).deallocate(p1, n1 + N1);
            }
            void construct(pointer memory, const Y& value) {
                allocator.construct(memory, value);
            }
            void destroy(pointer memory) {
                allocator.destroy(memory);
            }
            template<typename U>
            bool operator==(const allocate_array_helper<A, T[N], U>& other) const {
                return allocator == other.allocator;
            }
            template<typename U>
            bool operator!=(const allocate_array_helper<A, T[N], U>& other) const {
                return !(*this == other); 
            }
        private:
            enum {
                N1 = N * sizeof(T)
            };
            A2 allocator;
            T** data;
        };
    }
}

#endif
