stack_impl.h 10.5 KB
/**
 * \file scot/stack_impl.h
 * \author  Georg Steffers <georg@steffers.org>
 * \brief   Templates of functions for handling stacks based on typesafe lists.
 *
 * The Macros here generate the implementation for the interface to stacks
 * based on typesafe linked lists.
 * \anchor onlyfunc_stack
 * \attention
 * All documentation here does document the functions that are created by
 * the macros, as the macros themself are pretty easy and all used the same.
 * They are called with a type, that MUST be one word (use typedef if needed)
 * and generates the function defined with their value.
 *
 * Copyright (C)2006    Georg Steffers <georg@steffers.org>
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */
#ifndef  STACK_IMPL_H
#define  STACK_IMPL_H

#include <scot/list.h>


/**
 * \internal
 * \param   type     the datatype that this queue code should handle.
 * \param   a        a variable holding a pointer to list_[type]_node_t.
 *
 * \pre              Type must be a single word typename. If one wants
 *                   to use e.g. lists of structs one has to use typedef
 *                   to create a single word type name like this:
 *                   typedef struct mystruct_t mystruct_t;
 *                   a must be a valid pointer to a list_[type]_node_t.
 * \returns          \a a cast to a pointer of stack_[type]_node_t.
 * \post             None
 *
 * \brief   Cast a pointer to stack_[type]_node_t.
 *
 * FIXME: I should check better the validity of \a a.
 */
#define  STACK(type, a) (stack_ ## type ## _node_t *) (a)

extern const char *stack_err_msg[];


#ifdef   GEN_LOCAL
#  define   STATIC   static
#else
#  define   STATIC
#endif

/**
 * \attention
 * Only the generated function is explained here, for the reason look
 * \ref onlyfunc_stack "here".
 *
 * \param   anchor   a pointer that should contain the list anchor.
 * \pre              GEN_LIST_NEW(type) has to be called previously.
 * \return           NULL on error, but only if no exceptions are used.
 *                   If exceptions are used an exception is thrown on error.
 *                   On success a pointer to the newly created list_anchor
 *                   will be returned.
 * \retval  NULL     if an error occurs and no exceptions are used.
 * \retval  !=NULL   the pointer to the newly created list anchor.
 * \post             enough memory on the heap.
 *
 * \brief template for stack constructor.
 *
 * this simply calls list_[type]_new(), that must be generated previously
 * by a call of GEN_LIST_NEW(type).
 */
#define  GEN_STACK_NEW(type)                                         \
   STATIC                                                            \
   stack_ ## type ## _node_t *                                       \
   stack_ ## type ## _new (stack_ ## type ## _node_t *anchor)        \
   {                                                                 \
      return anchor = STACK (type,                                   \
            list_ ## type ## _new (LIST (type, anchor)));            \
   }
   
/**
 * \attention
 * Only the generated function is explained here, for the reason look
 * \ref onlyfunc_stack "here".
 *
 * \param   anchor   a pointer that should contain the list anchor.
 * \pre              GEN_LIST_FREE(type) has to be called previously.
 * \return           Nothing
 * \post             The list is completely removed from the heap.
 *
 * \brief template for stack destructor.
 *
 * this simply calls list_[type]_free(), that must be generated previously
 * by a call of GEN_LIST_FREE(type).
 */
#define  GEN_STACK_FREE(type)                                        \
   STATIC                                                            \
   void                                                              \
   stack_ ## type ## _free (stack_ ## type ## _node_t *anchor)       \
   {                                                                 \
      list_ ## type ## _free (LIST (type, anchor));                  \
   }
   
/**
 * \attention
 * Only the generated function is explained here, for the reason look
 * \ref onlyfunc_stack "here".
 *
 * \param   anchor   a pointer that should contain the list anchor.
 * \param   e        A pointer to a variable of the \a type, the
 *                   list was created for.
 * \pre              GEN_LIST_INSERT(type) has to be called previously.
 * \return           The pushed element \a e.
 * \post             Element \a e is pushed in the stack pointed by
 *                   \a anchor.
 *
 * \brief template for a function that pushes a value into a stack.
 *
 * To add a value into a stack meens to put it at the beginning of the stack.
 * That is simply a call to list_[type]_insert().
 */
#define  GEN_STACK_PUSH(type)                                        \
   STATIC                                                            \
   stack_ ## type ## _node_t *                                       \
   stack_ ## type ## _push (                                         \
         stack_ ## type ## _node_t  *anchor,                         \
         const type                 *e)                              \
   {                                                                 \
      return STACK (type, list_ ## type ## _insert (                 \
            LIST (type, anchor), e));                                \
   }

/**
 * \attention
 * Only the generated function is explained here, for the reason look
 * \ref onlyfunc_stack "here".
 *
 * \param   anchor   a pointer that should contain the list anchor.
 * \pre              GEN_LIST_NEXT(type), GEN_LIST_RETRIVE(type)
 *                   GEN_LIST_ISEMPTY(type) and GEN_LIST_DELETE(type)
 *                   has to be called previously.
 * \return           The poped element.
 * \post             One Element is poped from the stack pointed to
 *                   by \a anchor.
 *
 * \brief template for a function that pops a value from a stack.
 *
 * Pop means get and remove the first element from the stack.
 * This is done here.
 */
#define  GEN_STACK_POP(type)                                         \
   STATIC                                                            \
   type *                                                            \
   stack_ ## type ## _pop (stack_ ## type ## _node_t  *anchor)       \
   {                                                                 \
      list_ ## type ## _node_t   *next;                              \
      const type                 *e;                                 \
                                                                     \
      next  = list_ ## type ## _next (LIST (type, anchor));          \
      e     = list_ ## type ## _retrive (next);                      \
                                                                     \
      if (! list_ ## type ## _isempty (next))                        \
         list_ ## type ## _delete (next);                            \
                                                                     \
      return (type *) e;                                             \
   }
   
/**
 * \attention
 * Only the generated function is explained here, for the reason look
 * \ref onlyfunc_stack "here".
 *
 * \param   anchor   a pointer that should contain the list anchor.
 * \pre              GEN_LIST_NEXT(type) and GEN_LIST_RETRIVE(type)
 *                   has to be called previously.
 * \return           The next element in the stack.
 * \post             None
 *
 * \brief get next element in the stack without poping it.
 */
#define  GEN_STACK_TOP(type)                                         \
   STATIC                                                            \
   type *                                                            \
   stack_ ## type ## _top (                                          \
         stack_ ## type ## _node_t *anchor)                          \
   {                                                                 \
      return list_ ## type ## _retrive (                             \
            list_ ## type ## _next (LIST (type, anchor)));           \
   }

/**
 * \param   type     the datatype that this list code should handle.
 * \pre              Type must be a single word typename. If one wants
 *                   to use e.g. lists of structs one has to use typedef
 *                   to create a single word type name like this:
 *                   typedef struct mystruct_t mystruct_t;
 *                   GEN_LIST_IMPL(type) should be called before this.
 * \return           Nothing
 * \post             The functions, struct and globals to handle stacks
 *                   based on typesave
 *                   lists for the given datatype are generated within the
 *                   calling build file.
 *
 * \brief this creates all functions, structs and globals needed for a
 *        stack based on typesafe list of a given \a type.
 *
 * In detail the following is created by this macro:\n
 * \li <b>struct stack_[type]_node_t</b>: This is the structure a stack
 * is constructed of. Practically this just contains an instance of a
 * list_[type]_node_t, as stacks are completely based on lists and does
 * not add further information.
 * \li all functions created by the macros defined within this file.
 */
#define  GEN_STACK_IMPL(type)                                        \
   struct stack_ ## type ## _node_t                                  \
   {                                                                 \
      struct list_node_t  list;                                      \
   };                                                                \
                                                                     \
   GEN_STACK_NEW (type)                                              \
   GEN_STACK_FREE (type)                                             \
   GEN_STACK_PUSH (type)                                             \
   GEN_STACK_POP (type)                                              \
   GEN_STACK_TOP (type)

#endif   /* STACK_IMPL_H */