view anagram/support/agstack.h @ 21:1c9dac05d040

Add lint-style FALLTHROUGH annotations to fallthrough cases. (in the parse engine and thus the output code) Document this, because the old output causes warnings with gcc10.
author David A. Holland
date Mon, 13 Jun 2022 00:04:38 -0400
parents 13d2b8934445
children
line wrap: on
line source

/**********************************************************

The AnaGram Class Library

The AgStackStorage Class
Copyright 1997 Parsifal Software. All Rights Reserved.
See the file COPYING for license and usage terms.

***********************************************************/

#ifndef AGSTACK_H
#define AGSTACK_H

#include <stdlib.h>
#include "port.h"

#include "agcontainer.h"


template <class T>
class AgStack;

class AgStackStorage {
private:
  void *buffer;                      // active buffer
  AgStack<void *> *bufferStack;      // buffer stack
  unsigned         count;            // number of items stacked
  unsigned         usage;            // usage count
  unsigned short   quantum;          // size of item
  unsigned short   bufferSize;       // buffer size
  unsigned short   mask;             // bufferSize - 1
  unsigned short   index;            // number of items in current buffer
  unsigned char    logSize;          // log2 of bufferSize
  unsigned char    bsLogSize;        // log2 bufferStack->bufferSize

public:

// Constructor
  AgStackStorage(const unsigned quantum_,
		 const unsigned logSize_,
		 const unsigned bsLogSize_);
// Destructor
  ~AgStackStorage();

  inline void *operator new(size_t n) { return malloc(n); }
  inline void operator delete(void *p) { free(p); }

  AgStackStorage &discardData();
  AgStackStorage &discardData(unsigned n);

  unsigned size() const {
    return count;                            // number of items stacked
  }

// Push operator
  void *push();

// Pop operator
  void *pop();

  void *locate(const unsigned n) const;

  void lock() {
    usage++;
  }
  int unlock() {
    return --usage == 0;
  }
};

template <class T>
class AgClassWrapper {
private:
  T data;

public:
  AgClassWrapper(const T &t);
  void *operator new(size_t, void *where) {
    return where;
  }
  void operator delete(void *) {}
  operator T () const;
};

template <class T>
class AgStack : public AgIndexedContainer<T>
{
private:
  AgStackStorage *store;

public:
  AgStack(unsigned logSize = 8, unsigned bsLogSize = 8);
  AgStack(const AgStack<T> &s);

  void *operator new(size_t n) { return malloc(n); }
  void operator delete(void *p) { free(p); }
  AgStack<T> &operator =(const AgStack<T> &s);
  ~AgStack();
  unsigned size() const {
    return store->size();
  }

  AgStack<T> &push(const T &t);
//  AgStack<T> &operator << (const T &t);
  AgStack<T> &pop(T &t);
  T pop();

  T &operator[] (const unsigned n) {
    return *(T *)store->locate(n);
  }
  const T &operator[] (const unsigned n) const {
    return *(T *)store->locate(n);
  }
  T &top() {
    return (*this)[size() - 1];
  }

  AgStack<T> &discardData(unsigned n);
  AgStack<T> &discardData() {
    discardData(size());
    return *this;
  }
  AgStack<T> &reset() {
    discardData();
    return *this;
  }
  int operator < (const AgStack<T> &s) const;
};


#endif /* AGSTACK_H */