blob: 5110753cfb7bce27ce5f17f467ccefe418757dc7 [file] [log] [blame]
/*=============================================================================
Boost.Wave: A Standard compliant C++ preprocessor library
http://www.boost.org/
Copyright (c) 2001 Daniel C. Nuffer.
Copyright (c) 2001-2010 Hartmut Kaiser.
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#define BOOST_WAVE_SOURCE 1
// disable stupid compiler warnings
#include <boost/config/warning_disable.hpp>
#include <cstdlib>
#include <cstring>
#include <boost/wave/wave_config.hpp> // configuration data
#include <boost/wave/cpplexer/re2clex/aq.hpp>
#include <boost/assert.hpp>
// this must occur after all of the includes and before any code appears
#ifdef BOOST_HAS_ABI_HEADERS
#include BOOST_ABI_PREFIX
#endif
///////////////////////////////////////////////////////////////////////////////
namespace boost {
namespace wave {
namespace cpplexer {
namespace re2clex {
int aq_grow(aq_queue q)
{
using namespace std; // some systems have memcpy/realloc in std
std::size_t new_size = q->max_size << 1;
aq_stdelement* new_queue = (aq_stdelement*)realloc(q->queue,
new_size * sizeof(aq_stdelement));
BOOST_ASSERT(NULL != q);
BOOST_ASSERT(q->max_size < 100000);
BOOST_ASSERT(q->size <= q->max_size);
#define ASSERT_SIZE BOOST_ASSERT( \
((q->tail + q->max_size + 1) - q->head) % q->max_size == \
q->size % q->max_size)
ASSERT_SIZE;
BOOST_ASSERT(q->head <= q->max_size);
BOOST_ASSERT(q->tail <= q->max_size);
if (!new_queue)
{
BOOST_ASSERT(0);
return 0;
}
q->queue = new_queue;
if (q->tail <= q->head) /* tail has wrapped around */
{
/* move the tail from the beginning to the end */
memcpy(q->queue + q->max_size, q->queue,
(q->tail + 1) * sizeof(aq_stdelement));
q->tail += q->max_size;
}
q->max_size = new_size;
BOOST_ASSERT(q->size <= q->max_size);
ASSERT_SIZE;
BOOST_ASSERT(q->head <= q->max_size);
BOOST_ASSERT(q->tail <= q->max_size);
return 1;
}
int aq_enqueue(aq_queue q, aq_stdelement e)
{
BOOST_ASSERT(NULL != q);
BOOST_ASSERT(q->size <= q->max_size);
ASSERT_SIZE;
BOOST_ASSERT(q->head <= q->max_size);
BOOST_ASSERT(q->tail <= q->max_size);
if (AQ_FULL(q))
if (!aq_grow(q))
return 0;
++q->tail;
if (q->tail == q->max_size)
q->tail = 0;
q->queue[q->tail] = e;
++q->size;
BOOST_ASSERT(q->size <= q->max_size);
ASSERT_SIZE;
BOOST_ASSERT(q->head <= q->max_size);
BOOST_ASSERT(q->tail <= q->max_size);
return 1;
}
int aq_enqueue_front(aq_queue q, aq_stdelement e)
{
BOOST_ASSERT(NULL != q);
BOOST_ASSERT(q->size <= q->max_size);
ASSERT_SIZE;
BOOST_ASSERT(q->head <= q->max_size);
BOOST_ASSERT(q->tail <= q->max_size);
if (AQ_FULL(q))
if (!aq_grow(q))
return 0;
if (q->head == 0)
q->head = q->max_size - 1;
else
--q->head;
q->queue[q->head] = e;
++q->size;
BOOST_ASSERT(q->size <= q->max_size);
ASSERT_SIZE;
BOOST_ASSERT(q->head <= q->max_size);
BOOST_ASSERT(q->tail <= q->max_size);
return 1;
}
int aq_serve(aq_queue q, aq_stdelement *e)
{
BOOST_ASSERT(NULL != q);
BOOST_ASSERT(q->size <= q->max_size);
ASSERT_SIZE;
BOOST_ASSERT(q->head <= q->max_size);
BOOST_ASSERT(q->tail <= q->max_size);
if (AQ_EMPTY(q))
return 0;
*e = q->queue[q->head];
return aq_pop(q);
}
int aq_pop(aq_queue q)
{
BOOST_ASSERT(NULL != q);
BOOST_ASSERT(q->size <= q->max_size);
ASSERT_SIZE;
BOOST_ASSERT(q->head <= q->max_size);
BOOST_ASSERT(q->tail <= q->max_size);
if (AQ_EMPTY(q))
return 0;
++q->head;
if (q->head == q->max_size)
q->head = 0;
--q->size;
BOOST_ASSERT(q->size <= q->max_size);
ASSERT_SIZE;
BOOST_ASSERT(q->head <= q->max_size);
BOOST_ASSERT(q->tail <= q->max_size);
return 1;
}
aq_queue aq_create(void)
{
aq_queue q;
using namespace std; // some systems have malloc in std
q = (aq_queue)malloc(sizeof(aq_queuetype));
if (!q)
{
return 0;
}
q->max_size = 8; /* initial size */
q->queue = (aq_stdelement*)malloc(
sizeof(aq_stdelement) * q->max_size);
if (!q->queue)
{
free(q);
return 0;
}
q->head = 0;
q->tail = q->max_size - 1;
q->size = 0;
BOOST_ASSERT(q->size <= q->max_size);
ASSERT_SIZE;
BOOST_ASSERT(q->head <= q->max_size);
BOOST_ASSERT(q->tail <= q->max_size);
return q;
}
void aq_terminate(aq_queue q)
{
using namespace std; // some systems have free in std
BOOST_ASSERT(NULL != q);
BOOST_ASSERT(q->size <= q->max_size);
ASSERT_SIZE;
BOOST_ASSERT(q->head <= q->max_size);
BOOST_ASSERT(q->tail <= q->max_size);
free(q->queue);
free(q);
}
///////////////////////////////////////////////////////////////////////////////
} // namespace re2clex
} // namespace cpplexer
} // namespace wave
} // namespace boost
// the suffix header occurs after all of the code
#ifdef BOOST_HAS_ABI_HEADERS
#include BOOST_ABI_SUFFIX
#endif