/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the  "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#if !defined(XALANALLOCATOR_INCLUDE_GUARD_1357924680)
#define XALANALLOCATOR_INCLUDE_GUARD_1357924680



#include <cstddef>



namespace XALAN_CPP_NAMESPACE {



template <class Type>
class XalanAllocator
{
public:
    typedef size_t          size_type;
    typedef ptrdiff_t       difference_type;
    typedef Type*           pointer;
    typedef const Type*     const_pointer;
    typedef Type&           reference;
    typedef const Type&     const_reference;
    typedef Type            value_type;

    
    XalanAllocator(MemoryManager&      theManager) :
        m_memoryManager(theManager)
    {
    }


    ~XalanAllocator()
    {
    }
    
    MemoryManager&
    getMemoryManager()
    {
        return m_memoryManager;
    }
    
    pointer
    address(reference   x) const
    {
        return &x;
    }

    const_pointer
    address(const_reference     x) const
    {
        return &x;
    }

    pointer
    allocate(
            size_type       size,
            const void*     /* hint */ = 0)
    {
        return (pointer)m_memoryManager.allocate(size * sizeof(Type));
    }

    void
    deallocate(
                pointer     p,
                size_type   /* n */)
    {
        if( p == 0 )
        {
            return;
        }

        m_memoryManager.deallocate(p);
    }

    size_type
    max_size() const
    {
        return ~0;
    }

    void
    construct(
            pointer         p,
            const Type&     val)
    {
        new (p) Type(val);
    }

    void
    destroy(pointer     p)
    {
        p->Type::~Type();
    }
    
private:
    XalanAllocator(const XalanAllocator<Type>&);
    
    XalanAllocator<Type>&
    operator=(const XalanAllocator<Type>&);
    
    MemoryManager&      m_memoryManager;
};



}



#endif  // XALANALLOCATOR_INCLUDE_GUARD_1357924680
