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



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



#include <xalanc/XSLT/ElemValueOf.hpp>



#include <xalanc/PlatformSupport/ArenaAllocator.hpp>



namespace XALAN_CPP_NAMESPACE {



class XALAN_XSLT_EXPORT XalanElemValueOfAllocator
{
public:

    typedef ElemValueOf                         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.
     */
    XalanElemValueOfAllocator(
            MemoryManager&  theManager,
            size_type           theBlockCount);

    ~XalanElemValueOfAllocator();
    
    /**
     * 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...
    XalanElemValueOfAllocator(const XalanElemValueOfAllocator&);

    XalanElemValueOfAllocator&
    operator=(const XalanElemValueOfAllocator&);

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



}



#endif  // XALANELEMVALUEOFALLOCATOR_INCLUDE_GUARD_12455133
