view anagram/support/agstack-imp.h @ 7:57b2cc9b87f7

Use memcpy instead of strncpy when we know the length anyway. Modern gcc seems to think it knows how to detect misuse of strncpy, but it's wrong (in fact: very, very wrong) and the path of least resistance is to not try to fight with it.
author David A. Holland
date Mon, 30 May 2022 23:47:52 -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_IMP_H
#define AGSTACK_IMP_H


template <class T>
AgClassWrapper<T>::AgClassWrapper(const T &t)
  : data(t)
{}

template <class T>
AgClassWrapper<T>::operator T () const {
  return data;
}

template <class T>
AgStack<T>::AgStack(unsigned logSize, unsigned bsLogSize)
  : AgIndexedContainer<T>()
  , store(new AgStackStorage(sizeof(AgClassWrapper<T>), logSize, bsLogSize))
{
  //LOGSECTION("AgStack constructor");
  //constructorCalls++;
  //LOGV(constructorCalls);
}

template <class T>
AgStack<T>::AgStack(const AgStack<T> &s)
  : AgIndexedContainer<T>()
  , store(s.store)
{
  //LOGSECTION("AgStack copy constructor");
  //copyConstructorCalls++;
  //LOGV(copyConstructorCalls);
  store->lock();
}

template <class T>
AgStack<T>::~AgStack() {
  //LOGSECTION("~AgStack");
  //destructorCalls++;
  //LOGV(destructorCalls);
  if (store->unlock()) {
    discardData();
    delete store;
  }
}

template <class T>
AgStack<T> &AgStack<T>::operator = (const AgStack<T> &s) {
  //LOGSECTION("AgStack::operator =");
  if (store->unlock()) {
    delete store;
  }
  store = s.store;
  store->lock();
  return *this;
}

template <class T>
int AgStack<T>::operator < (const AgStack<T> &s) const {
  int n = min(size(), s.size());
  int i = 0;
  while (i < n) {
    if ((*this)[i] < s[i]) {
      return 1;
    }
    if (s[i] < (*this)[i]) {
      return 0;
    }
    i++;
  }
  return size() < s.size();
}

template <class T>
AgStack<T> &AgStack<T>::push(const T &t) {
  new(store->push()) AgClassWrapper<T>(t);
  return *this;
}

//template <class T>
//AgStack<T> &AgStack<T>::operator << (const T &t) {
//  new(store->push()) AgClassWrapper<T>(t);
//  return *this;
//}

template <class T>
AgStack<T> &AgStack<T>::pop(T &t) {
  AgClassWrapper<T> *pointer = (AgClassWrapper<T> *) store->pop();
  t = (T) *pointer;
  delete pointer;
  return *this;
}

template <class T>
T AgStack<T>::pop() {
  AgClassWrapper<T> *pointer = (AgClassWrapper<T> *) store->pop();
  T value((T) *pointer);
  delete pointer;
  return value;
}

//template <class T>
//AgArray<T> AgStack<T>::popArray() {
//  unsigned n = size();
//  AgArray<T> array(n);
//  while (n--) pop(array[n]);
//  //for (int i = 0; i < n; i++) array[i] = (*this)[i];
//  //discardData(n);
//  return array;
//}

template <class T>
AgStack<T> &AgStack<T>::discardData(unsigned n) {
  while (n--) {
    AgClassWrapper<T> *pointer = (AgClassWrapper<T> *) store->pop();
    delete pointer;
  }
  //store->discardData(n);
  return *this;
}

//template <class T>
//AgStack<T> &operator << (AgStack<T> &stack, const T &t) {
//  return stack.push(t);
//}

//template <class T>
//AgStack<T> &operator >> (AgStack<T> &stack, T &t) {
//  return stack.pop(t);
//}

//template <class T>
//AgStack<T> &operator << (AgStack<T> &stack, const AgIndexedContainer<T> &a) {
//  for (int i = 0; i < a.size(); i++) stack.push(a[i]);
//  return stack;
//}


#endif /* AGSTACK_IMP_H */