/*
 * 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(XALANELEMATTRIBUTEALLOCATOR_INCLUDE_GUARD_12455133)
#define XALANELEMATTRIBUTEALLOCATOR_INCLUDE_GUARD_12455133



// Base include file.  Must be first.
#include <xalanc/XSLT/XSLTDefinitions.hpp>



#include <xalanc/XSLT/ElemAttribute.hpp>



#include <xalanc/PlatformSupport/ArenaAllocator.hpp>



namespace XALAN_CPP_NAMESPACE {



class XALAN_XSLT_EXPORT XalanElemAttributeAllocator
{
public:

    typedef ElemAttribute                   data_type;

#if defined(XALAN_NO_DEFAULT_TEMPLATE_ARGUMENTS)
    typedef ArenaBlock<data_type>               ArenaBlockType;
    typedef ArenaAllocator<data_type,
                           ArenaBlockType>      ArenaAllocatorType;
#else
    typedef ArenaAllocator<data_type>           ArenaAllocatorType;
#endif

    typedef ArenaAllocatorType::size_type       size_type;

    /**
     * Construct an instance that will allocate blocks of the specified size.
     *
     * @param theBlockSize The block size.
     */
    XalanElemAttributeAllocator(
                MemoryManager&  theManager,
                size_type           theBlockCount);

    ~XalanElemAttributeAllocator();
    
    /**
     * Construct an instance
     * 
     * @param constructionContext context for construction of object
     * @param stylesheetTree      stylesheet containing element
     * @param atts                list of attributes for element
     * @param lineNumber                line number in document
     * @param columnNumber          column number in document
     *
     * @return A pointer to the new instance.
     */
    data_type*
    create(
            StylesheetConstructionContext&  constructionContext,
            Stylesheet&                     stylesheetTree,
            const AttributeListType&        atts,
            XalanFileLoc                    lineNumber,
            XalanFileLoc                    columnNumber);

    /**
     * Determine if an object is owned by the allocator...
     */
    bool
    ownsObject(const data_type*     theObject)
    {
        return m_allocator.ownsObject(theObject);
    }

    /**
     * Delete all objects from the allocator.    
     */ 
    void
    reset()
    {
        m_allocator.reset();
    }

    /**
     * Get the number of ArenaBlocks currently allocated.
     *
     * @return The number of blocks.
     */
    size_type
    getBlockCount() const
    {
        return m_allocator.getBlockCount();
    }

    /**
     * Get size of an ArenaBlock, that is, the number
     * of objects in each block.
     *
     * @return The size of the block
     */
    size_type
    getBlockSize() const
    {
        return m_allocator.getBlockSize();
    }

private:

    // Not implemented...
    XalanElemAttributeAllocator(const XalanElemAttributeAllocator&);

    XalanElemAttributeAllocator&
    operator=(const XalanElemAttributeAllocator&);

    // Data members...
    ArenaAllocatorType  m_allocator;
};



}



#endif  // XALANELEMATTRIBUTEALLOCATOR_INCLUDE_GUARD_12455133
