Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
ring.h
- Committer:
- greletj
- Date:
- 2012-11-28
- Revision:
- 0:b3a2e39a13ad
- Child:
- 1:a4c87bc5b008
File content as of revision 0:b3a2e39a13ad:
/*****************************************************************************
 *                                                                           *
 * ring.cpp : Module template de gestion de buffers circulaires tous types   *
 *                                                                           *
 *          Jacques Grelet      Mars 1992                                    *
 *          Bruno Buisson       Aout 92                                      *
 *          - Modif lecture buffer : si plein, on perd la plus   *
 *                                   ancienne valeur, pas toutes *
 *          - Nouvelles fonctions : vide_ring_x() vide le buffer *
 *                                  term_ring_x() libere la mem  *
 *                                  pr_ring_list() (debug)       *
 *                                  swap_ring_x() construit list *
 *                                  libre_ring_x() taille dispo  *
 *                                                                           *
 *          Bruno Buisson       Novembre 95                                  *
 *                      - Ajout de la fonction top_ring_x() qui retourne sans*
 *                        supprimer du ring le premier de la liste           *
 *                                                                           *
 *                              Avril 96                                     *
 *                      - Version template                                   *
 *                        Modification des fonctions fct_x(r,) en r.fct()    *
 *                        Suppression des fonctions init et term             *
 *                        (constructeur / destructeur)                       *
 *                        Les fonctions ont ete renommees                    *
 *                        Nouvelle fonction shift( n ) : supprime n elements *
 *                                                                           *
 *****************************************************************************/
#ifdef DEBUG
#include "mbed.h"
#include "debug.h"
extern Serial pc;
#endif
#ifndef ring_H
#define ring_H
#include "util.h"
// Definition du template Ring
template <class T_elem>
class Ring
{
    // Type generique
#define P_ELEM T_elem  *
    // Membres;
private:
    unsigned taille,
             libre;
    P_ELEM   lecture;
    P_ELEM   ecriture;
    P_ELEM   tampon;
public:
    P_ELEM   list;
    // Methodes inline
private:
    inline void        incr(     P_ELEM &ptr              );
public:
    inline unsigned     nb_libre( void                     );
    // Methodes
public:
    bool                put(      T_elem elem              );
    bool                get(      T_elem &valeur           );
    bool                top(      T_elem &valeur           );
    unsigned            shift(    unsigned nb = 1          );
    void                vide(     void                     );
    unsigned            store(    void                     );
    // Constructeurs
public:
    Ring(     unsigned size = 0        );
    ~Ring();
};
/*****************************************************************************
 * Si le pointeur ptr depasse la taille maxi du tampon,                      *
 * il revient pointer au debut.                                              *
 * inline                                                                    *
 *****************************************************************************/
template <class T_elem>
void  Ring<T_elem>::incr( P_ELEM &ptr )
{
    if( ++ptr - tampon >= taille ) ptr = tampon;
}
/*****************************************************************************
 * Met un element dans un Ring                                               *
 * Lorsque Ring est plein, deplace egalement de pointeur de lecture et la    *
 * valeur la plus ancienne est perdue.                                       *
 *****************************************************************************/
template <class T_elem>
bool Ring<T_elem>::put( T_elem elem )
{
    if( taille == 0 ) return( false );
    *ecriture = elem;
    incr( ecriture );
    if( libre > 0 ) libre--;
    else            incr( lecture );
    return( true );
}
/*****************************************************************************
 * Lit une valeur dans le Ring et la stocke dans le parametre recu           *
 * Le pointeur de lecture est incremente par cette fonction                  *
 * Retourne FALSE si le Ring est vide                                        *
 *****************************************************************************/
template <class T_elem>
bool Ring<T_elem>::get( T_elem &valeur )
{
    if( libre == taille ) return( FALSE );
    valeur = *lecture;
    incr( lecture );
    libre++;
    return( TRUE );
}
/*****************************************************************************
 * Lit une valeur dans le Ring et la stocke dans le parametre recu           *
 * Le pointeur de lecture n'est pas modifié par cette fonction, cf. get()    *
 * Retourne FALSE si le Ring est vide                                        *
 *****************************************************************************/
template <class T_elem>
bool Ring<T_elem>::top( T_elem &valeur )
{
    if( libre == taille ) return( FALSE );
    valeur = *lecture;
    return( TRUE );
}
/*****************************************************************************
 * Supprime n elements du sommet du ring                                     *
 * Retourne le nb d'elements reellement supprimes                            *
 *****************************************************************************/
template <class T_elem>
unsigned Ring<T_elem>::shift( unsigned nb /*=1*/ )
{
    unsigned i;
    T_elem   val;
    for( i = 0; i < nb && get( val ); i++ );
    return( i );
}
/*****************************************************************************
 * Reinitialise les pointeurs de Ring. Le Ring est vide                      *
 *****************************************************************************/
template <class T_elem>
void  Ring<T_elem>::vide( void )
{
    libre    = taille;
    lecture  =
        ecriture = tampon;
}
/*****************************************************************************
 * Construction du tableau list.                                             *
 * Déplace les données contenues dans le buffer circulaire de Ring vers le   *
 * tableau list[]. Les donnéees de list[] ne seront écrasées que par un autre*
 * appel a cette fonction                                                    *
 * Retourne le nombre de valeurs transférées (0 si Ring est vide)            *
 * Version 02/02/94 : Ring est vide apres l'appel                            *
 *****************************************************************************/
template <class T_elem>
unsigned Ring<T_elem>::store( void )
{
    unsigned nb_elem = taille - libre,
             i;
    //DPRINTF( ("\r\nList: ") );
    for( i = 0; i < nb_elem; i++ ) {
        list[ i ] = *lecture;
        //DPRINTF( ("%4.3g ", list[ i ] ));
        incr( lecture );
    }
    //DPRINTF( ("\r\n") );
    libre    = taille;
    lecture  =
        ecriture = tampon;
    return( nb_elem );
}
/*****************************************************************************
 * inline                                                                    *
 *****************************************************************************/
template <class T_elem>
unsigned Ring<T_elem>::nb_libre( void )
{
    return( libre );
}
/*****************************************************************************
 *****************************************************************************/
template <class T_elem>
Ring<T_elem>::Ring( unsigned size /*=0*/ )
{
    lecture  =
        ecriture =
            tampon   = ( size == 0 ? (P_ELEM) NULL : FARALLOUE( size,T_elem ) );
    list     = ( size == 0 ? (P_ELEM) NULL : FARALLOUE( size,T_elem ) );
    libre    =
        taille   = ( tampon ? size : 0 );
}
/*****************************************************************************
 *****************************************************************************/
template <class T_elem>
Ring<T_elem>::~Ring()
{
    FARLIBERE( tampon );
    FARLIBERE( list   );
    libre    =
        taille   = 0;
    lecture  =
        ecriture =
            tampon   =
                list     = (P_ELEM) NULL;
}
#endif