/* -*- C++ -*- vim: set syntax=cpp: 
 * (C) 2004-2009 Frank-Rene Schaefer                               */
#ifndef __QUEX_INCLUDE_GUARD__TOKEN__TOKEN_QUEUE
#define __QUEX_INCLUDE_GUARD__TOKEN__TOKEN_QUEUE

#include <quex/code_base/definitions>
#include <quex/code_base/asserts>
#include <quex/code_base/MemoryManager>

#include <quex/code_base/temporary_macros_on>

#ifndef QUEX_TYPE_TOKEN
#    error "QUEX_TYPE_TOKEN must be defined before including this file."
#endif


QUEX_NAMESPACE_MAIN_OPEN

    typedef struct {

        QUEX_TYPE_TOKEN*   begin;
        QUEX_TYPE_TOKEN*   read_iterator;    /* pointer to next token to be read          */
        QUEX_TYPE_TOKEN*   write_iterator;   /* pointer to next token to be written       */
        QUEX_TYPE_TOKEN*   end_minus_safety_border;
        QUEX_TYPE_TOKEN*   end;
        /* A token might be 'N' times repeated. This is the only case where a token
         * queue overflow might occur. When the token queue is full and there are still
         * 'N' tokens to be repeated, then the remaining 'N' are stored in the following
         * variable.                                                                      */

    } QUEX_NAME(TokenQueue);

    QUEX_INLINE void             QUEX_NAME(TokenQueue_reset)(QUEX_NAME(TokenQueue)* me);
    QUEX_INLINE void             QUEX_NAME(TokenQueue_init)(QUEX_NAME(TokenQueue)* me, 
                                                            QUEX_TYPE_TOKEN*       Memory, 
                                                            QUEX_TYPE_TOKEN*       MemoryEnd); 
    QUEX_INLINE void             QUEX_NAME(TokenQueue_construct)(QUEX_NAME(TokenQueue)* me, 
                                                                 QUEX_TYPE_TOKEN*       Memory,
                                                                 const size_t           N);
    QUEX_INLINE void             QUEX_NAME(TokenQueue_destruct)(QUEX_NAME(TokenQueue)* me);
    QUEX_INLINE void             QUEX_NAME(TokenQueue_remainder_get)(QUEX_NAME(TokenQueue)* me,
                                                                     QUEX_TYPE_TOKEN**      begin,
                                                                     QUEX_TYPE_TOKEN**      end);
    QUEX_INLINE void             QUEX_NAME(TokenQueue_memory_get)(QUEX_NAME(TokenQueue)* me,
                                                                  QUEX_TYPE_TOKEN**      memory,
                                                                  size_t*                n);
    QUEX_INLINE bool             QUEX_NAME(TokenQueue_is_full)(QUEX_NAME(TokenQueue)* me);
    QUEX_INLINE bool             QUEX_NAME(TokenQueue_is_empty)(QUEX_NAME(TokenQueue)* me);
    QUEX_INLINE QUEX_TYPE_TOKEN* QUEX_NAME(TokenQueue_pop)(QUEX_NAME(TokenQueue)* me);
    QUEX_INLINE QUEX_TYPE_TOKEN* QUEX_NAME(TokenQueue_begin)(QUEX_NAME(TokenQueue)* me);
    QUEX_INLINE QUEX_TYPE_TOKEN* QUEX_NAME(TokenQueue_back)(QUEX_NAME(TokenQueue)* me);
    QUEX_INLINE size_t           QUEX_NAME(TokenQueue_available_n)(QUEX_NAME(TokenQueue)* me); 


#ifdef QUEX_OPTION_ASSERTS
    QUEX_INLINE void  
    QUEX_ASSERT_TOKEN_QUEUE_AFTER_WRITE(QUEX_NAME(TokenQueue)* me);

    QUEX_INLINE void  
    QUEX_TOKEN_QUEUE_ASSERT(QUEX_NAME(TokenQueue)* me);
#else
#   define QUEX_TOKEN_QUEUE_ASSERT(me)             /* empty */
#   define QUEX_ASSERT_TOKEN_QUEUE_AFTER_WRITE(me) /* empty */
#endif

typedef struct {
    QUEX_TYPE_TOKEN*   token_list;
    size_t             size;
} QUEX_NAME(TokenQueueRemainder);

#if 1
QUEX_INLINE void  QUEX_NAME(TokenQueueRemainder_save)(QUEX_NAME(TokenQueueRemainder)*  me, 
                                                      QUEX_NAME(TokenQueue)*           token_queue);

QUEX_INLINE void  QUEX_NAME(TokenQueueRemainder_restore)(QUEX_NAME(TokenQueueRemainder)*  me, 
                                                         QUEX_NAME(TokenQueue)*           token_queue);
#endif

QUEX_NAMESPACE_MAIN_CLOSE

#include <quex/code_base/temporary_macros_off>

#endif /* __QUEX_INCLUDE_GUARD__TOKEN__TOKENQUEUE */
