wow. that was easy: git mv core nucleus
[feisty_meow.git] / core / library / structures / amorph.h
diff --git a/core/library/structures/amorph.h b/core/library/structures/amorph.h
deleted file mode 100644 (file)
index d2104c7..0000000
+++ /dev/null
@@ -1,520 +0,0 @@
-#ifndef AMORPH_CLASS
-#define AMORPH_CLASS
-
-/*****************************************************************************\
-*                                                                             *
-*  Name   : amorph                                                            *
-*  Author : Chris Koeritz                                                     *
-*                                                                             *
-*******************************************************************************
-* Copyright (c) 1989-$now By Author.  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 is online at:      *
-*     http://www.fsf.org/copyleft/gpl.html                                    *
-* Please send any updates to: fred@gruntose.com                               *
-\*****************************************************************************/
-
-#include "object_packers.h"
-
-#include <basis/astring.h>
-#include <basis/functions.h>
-#include <basis/contracts.h>
-#include <basis/guards.h>
-
-//! A dynamic container class that holds any kind of object via pointers.
-/*!
-  The object is considered owned by the amorph unless re-acquired from it,
-  and will be deleted when the amorph is destroyed.
-
-  An amorph has a specified number of fields at any one time, but the number
-  can be changed with "zap", "insert" and "adjust".  Fields in the amorph
-  are either full or empty, where an empty field in the amorph has NIL as
-  its content.  "put" adds a new field to the amorph.  "get" retrieves the
-  contents of a field as a constant.  "acquire" is used to check a field
-  out of the amorph, meaning that the amorph no longer possesses that field.
-  The legal range of indices in an amorph is from 0 through
-  "elements() - 1".  In general, a range violation for an index is
-  treated as an invalid request and is ignored (although BAD_INDEX is
-  returned by functions with compatible return values).
-
-  Model:
-
-  The policy followed in amorph is that once an object is checked in with
-  "put" or "append", then the amorph owns that object.  The object must not
-  be destroyed externally, because the amorph will automatically destroy
-  the object when either: 1) the amorph itself is destroyed, or 2) another
-  object is entered into the same field.  If the stored object must be
-  destroyed externally, then it should be checked out of the amorph with
-  "acquire"; after that, the pointer may be deleted.  "get" and "borrow"
-  return a pointer to the stored item while leaving it checked in to the
-  amorph.  it is safe to modify what was "borrow"ed or to look at what one
-  "get"s, but do not destroy the pointers returned from either method.
-*/
-
-namespace structures {
-
-template <class contents>
-class amorph : private basis::array<contents *>
-{
-public:
-  amorph(int elements = 0);
-    //!< constructs an amorph capable of holding "elements" pointers.
-
-  ~amorph();
-
-  int elements() const { return this->length(); }
-    //!< the maximum number of elements currently allowed in this amorph.
-
-  int valid_fields() const { return _fields_used; }
-    //!< Returns the number of fields that have non-NIL contents.
-    /*!< This might be different from the number of total elements. */
-
-  void adjust(int new_max);
-    //!< Changes the maximum number of elements for this amorph.
-    /*!< If the new number is smaller than the original, then the fields at
-    index "new_maximum" and upwards are thrown away.  existing fields are
-    kept. */
-
-  void reset(int new_maximum = 0);
-    //!< like adjust but doesn't keep existing contents.
-
-  basis::outcome put(int field, const contents *data);
-    //!< Enters an object into the field at index "field" in the amorph.
-    /*!< If "data" is NIL, then the field is cleared.  The amorph considers the
-    pointer "data" to be its own property after put is invoked; "data"
-    should not be destructed since the amorph will automatically do so.
-    This restriction does not hold if the object is checked back out of
-    the amorph with acquire(). */
-
-  basis::outcome append(const contents *data);
-    //!< puts "data" on the end of this amorph.
-    /*!< adds an element to the end of the amorph by increasing the amorph size
-    (with "adjust") and putting the element into the new spot (with "put"). */
-
-  basis::outcome operator += (const contents *data) { return append(data); }
-    //!< a synonym for append.
-
-  //! Returns a constant pointer to the information at the index "field".
-  /*! If no information is stored or the field is out range, then NIL is
-  returned. */
-  const contents *get(int field) const;
-  //! Returns a pointer to the information at the index "field".
-  /*! Also returns NIL for invalid indexes.  DO NOT destroy the returned
-  pointer; it is still owned by the amorph. */
-  contents *borrow(int field);
-
-  //! synonym for get.
-  const contents *operator [] (int field) const { return get(field); }
-  //! synonym for borrow.
-  contents *operator [] (int field) { return borrow(field); }
-
-  contents *acquire(int field);
-    //!< Retrieves a "field" from the amorph, taking responsibility for it back.
-    /*!< This function is similar to get, except that the contents are pulled
-    out of the amorph.  The contents will no longer be destroyed when the
-    amorph is destroyed.  To store the modified contents again, use put,
-    and then the amorph will take over management of the contents again.
-    Note that the index is not zapped with this function; the acquired
-    "field" will simply hold a null pointer. */
-
-  basis::outcome clear(int field);
-    //!< Clears the contents of the field specified.
-    /*!< Clearing an empty field has no effect.  Clearing an invalid field has
-    no effect.  NOTE: clearing the contents means that the contents are
-    destroyed, not just disconnected. */
-
-  void clear_all();
-    //!< Clears every field in the amorph.
-
-  basis::outcome zap(int start, int end);
-    //!< Removes a range of indices from the amorph.
-    /*!< This does not just clear the field associated with the specified index
-    as "clear" does, it actually changes the number of total elements by
-    removing the indices from the amorph.  The new amorph contains the old
-    elements up to just before the "start" and from the "end" + 1 through the
-    end of the amorph.  AMORPH_BAD_INDEX is returned if either index is out of
-    range.  If the zap succeeds, then AMORPH_OKAY is returned, even if the
-    "end" is less than the "start". */
-
-  basis::outcome insert(int position, int lines_to_add);
-    //!< Adds "lines_to_add" indices to the amorph at the index "position".
-    /*!< If "lines_to_add" is non-positive, the request is ignored.  Inserting
-    at a position beyond the bounds of the array is ignored, but a position AT
-    elements() is allowed (it is an append...). */
-
-  int find_empty(basis::outcome &o) const;
-    //!< Returns the index of a free field if there are any.
-    /*!< The returned index is invalid if the "o" is IS_FULL. */
-
-  const contents *next_valid(int &field) const;
-    //!< Returns the contents of the next valid element at or after "field".
-    /*!< "field" is set to the location where an entry was found, if one was
-    actually found.  If none exists at "field" or after it, then NIL is
-    returned. */
-
-  int find(const contents *to_locate, basis::outcome &o);
-    //!< Searches the amorph for the contents specified.
-    /*!< Since only pointers to the contents are maintained, the search is
-    based on finding a pointer in the amorph that is identical to "to_locate".
-    if "o" is OKAY, then the index of the entry is returned.  If
-    "o" is NOT_FOUND, then the contents are not present. */
-
-  void swap_contents(amorph<contents> &other);
-    //!< Exchanges the contents of "this" and "other".
-    /*!< No validation is performed but this should always succeed given
-    amorphs that are constructed properly. */
-
-private:
-  int _fields_used;  //!< The number of fields currently full of info.
-
-  void check_fields(const char *where) const;
-    //!< Crashes out if the field count is wrong.
-    /*!< This is only used for the debugging version. */
-
-  void set_nil(int start, int end);
-    // Puts NIL in the indices between start and end.
-    /*!< Does not delete whatever used to reside there; it just sets the
-    pointers to NIL. */
-
-  // not to be used: amorphs should not be copied because it is intended that
-  // they support storing heavyweight objects that either have no copy
-  // constructors or have high-cost copy constructors.
-  amorph(const amorph &to_copy) {}  //!< not to be used.
-  amorph &operator = (const amorph &to_copy) { return *this; }
-    //!< not to be used.
-};
-
-//////////////
-
-// these extensions are phrased as macros to avoid including the headers
-// necessary for compiling them.  to use them, just put the macro name in
-// the file where the template is needed.
-
-//////////////
-
-//! This can be used when the templated object has a copy constructor.
-/*! this makes the "to_assign" into a copy of the "to_copy" amorph. */
-template <class contents>
-void amorph_assign(amorph<contents> &to_assign,
-    const amorph<contents> &to_copy);
-
-//////////////
-
-//! support for packing an amorph into an array of bytes.
-/*!
-  this can be used when the underlying object is based on packable or
-  supports the same pack/unpack methods.  note that if there are empty spots in
-  the amorph, they are not packed.  when the packed form is unpacked again, it will
-  have only the first N elements set, where N is the number of non-empty items.
-*/
-template <class contents>
-void amorph_pack(basis::byte_array &packed_form, const amorph<contents> &to_pack);
-
-//! unpacks the amorph from an array of bytes.
-template <class contents>
-bool amorph_unpack(basis::byte_array &packed_form, amorph<contents> &to_unpack);
-
-//! reports how large the packed form will be.
-template <class contents>
-int amorph_packed_size(const amorph<contents> &to_pack);
-
-// implementation for longer methods...
-
-//#define DEBUG_AMORPH
-  // uncomment to enable more testing, as well as complaints on errors.
-
-#undef static_class_name
-#define static_class_name() "amorph"
-  // used in bounds_halt macro.
-
-#undef AMO_ALERT
-#ifdef DEBUG_AMORPH
-  #include <basis/astring.h>
-  #define AMO_ALERT(a, b, c) basis::throw_error(basis::astring(a), basis::astring(func), basis::astring(b) + " -- " + c)
-  #define CHECK_FIELDS check_fields(func)
-#else
-  #define AMO_ALERT(a1, a2, a3) {}
-  #define CHECK_FIELDS { if (!func) {} }
-#endif
-
-//////////////
-
-template <class contents>
-amorph<contents>::amorph(int elements)
-: basis::array<contents *>(elements, NIL, basis::array<contents *>::SIMPLE_COPY
-      | basis::array<contents *>::EXPONE | basis::array<contents *>::FLUSH_INVISIBLE),
-  _fields_used(0)
-{
-  FUNCDEF("constructor");
-  set_nil(0, elements - 1);
-  CHECK_FIELDS;
-}
-
-template <class contents>
-amorph<contents>::~amorph()
-{
-  FUNCDEF("destructor");
-  CHECK_FIELDS;
-  clear_all();
-}
-
-template <class contents>
-void amorph<contents>::set_nil(int start, int end)
-{
-  for (int i = start; i <= end; i++)
-    basis::array<contents *>::put(i, (contents *)NIL);
-}
-
-template <class contents>
-void amorph<contents>::check_fields(const char *where) const
-{
-  FUNCDEF("check_fields");
-  int counter = 0;
-  for (int i = 0; i < elements(); i++)
-    if (basis::array<contents *>::get(i)) counter++;
-  if (_fields_used != counter) {
-    AMO_ALERT("amorph", basis::a_sprintf("check_fields for %s", where),
-        "error in _fields_used count");
-  }
-}
-
-template <class contents>
-void amorph<contents>::reset(int new_maximum)
-{
-  FUNCDEF("reset");
-  CHECK_FIELDS;
-  adjust(new_maximum);
-  clear_all();
-}
-
-template <class contents>
-void amorph<contents>::clear_all()
-{
-  FUNCDEF("clear_all");
-  CHECK_FIELDS;
-  for (int i = 0; i < elements(); i++) clear(i);
-}
-
-template <class contents>
-basis::outcome amorph<contents>::append(const contents *data)
-{
-  FUNCDEF("append");
-  CHECK_FIELDS;
-  adjust(elements() + 1);
-  return put(elements() - 1, (contents *)data);
-}
-
-template <class contents>
-const contents *amorph<contents>::get(int field) const
-{
-  FUNCDEF("get");
-  CHECK_FIELDS;
-  bounds_return(field, 0, elements() - 1, NIL);
-  return basis::array<contents *>::observe()[field];
-}
-
-template <class contents>
-void amorph<contents>::adjust(int new_maximum)
-{
-  FUNCDEF("adjust");
-  CHECK_FIELDS;
-  if (new_maximum < 0) return;  // bad input here.
-  int old_max = elements();
-  if (new_maximum == old_max) return;  // nothing to do.
-  if (new_maximum < old_max) {
-    // removes the elements beyond the new size of the amorph.
-    zap(new_maximum, old_max - 1);
-    // we're done tuning it.
-    return;
-  }
-
-  // we get to here if we need more space than we used to.
-  int new_fields = new_maximum - old_max;
-
-  basis::array<contents *>::insert(old_max, new_fields);
-  for (int i = old_max; i < new_maximum; i++) {
-    basis::array<contents *>::put(i, NIL);
-  }
-}
-
-template <class contents>
-basis::outcome amorph<contents>::insert(int position, int lines_to_add)
-{
-  FUNCDEF("insert");
-  CHECK_FIELDS;
-  bounds_return(position, 0, elements(), basis::common::OUT_OF_RANGE);
-  basis::outcome o = basis::array<contents *>::insert(position, lines_to_add);
-  if (o != basis::common::OKAY) return basis::common::OUT_OF_RANGE;
-  set_nil(position, position + lines_to_add - 1);
-  return basis::common::OKAY;
-}
-
-template <class contents>
-basis::outcome amorph<contents>::zap(int start_index, int end_index)
-{
-  FUNCDEF("zap");
-  CHECK_FIELDS;
-  bounds_return(start_index, 0, elements() - 1, basis::common::OUT_OF_RANGE);
-  bounds_return(end_index, 0, elements() - 1, basis::common::OUT_OF_RANGE);
-  if (end_index < start_index) return basis::common::OKAY;
-  for (int i = start_index; i <= end_index;  i++) clear(i);
-  basis::outcome o = basis::array<contents *>::zap(start_index, end_index);
-  return (o == basis::common::OKAY? basis::common::OKAY : basis::common::OUT_OF_RANGE);
-}
-
-template <class contents>
-basis::outcome amorph<contents>::put(int field, const contents *data)
-{
-  FUNCDEF("put");
-  CHECK_FIELDS;
-  bounds_return(field, 0, elements() - 1, basis::common::OUT_OF_RANGE);
-  contents *to_whack = acquire(field);
-  WHACK(to_whack);
-  if (data) {
-    basis::array<contents *>::access()[field] = (contents *)data;
-    _fields_used++; 
-  }
-  return basis::common::OKAY;
-}
-
-template <class contents>
-int amorph<contents>::find_empty(basis::outcome &o) const
-{
-  FUNCDEF("find_empty");
-  CHECK_FIELDS;
-  if (_fields_used == elements()) { o = basis::common::IS_FULL; return 0; }
-  for (int i = 0; i < elements(); i++)
-    if (!basis::array<contents *>::get(i)) { o = basis::common::OKAY; return i; }
-  AMO_ALERT("amorph", "empty", "_fields_used is incorrect");
-  return basis::common::IS_FULL;
-}
-
-template <class contents>
-const contents *amorph<contents>::next_valid(int &field) const
-{
-  FUNCDEF("next_valid");
-  CHECK_FIELDS;
-  bounds_return(field, 0, elements() - 1, NIL);
-  for (int i = field; i < elements(); i++)
-    if (basis::array<contents *>::get(i)) {
-      field = i;
-      return basis::array<contents *>::get(i);
-    }
-  return NIL;
-}
-
-template <class contents>
-basis::outcome amorph<contents>::clear(int field)
-{
-  FUNCDEF("clear");
-  CHECK_FIELDS;
-  return this->put(field, NIL);
-}
-
-template <class contents>
-contents *amorph<contents>::acquire(int field)
-{
-  FUNCDEF("acquire");
-  CHECK_FIELDS;
-  contents *to_return = borrow(field);
-  if (to_return) {
-    _fields_used--;
-    basis::array<contents *>::access()[field] = NIL;
-  }
-  return to_return;
-}
-
-template <class contents>
-int amorph<contents>::find(const contents *to_locate, basis::outcome &o)
-{
-  FUNCDEF("find");
-  CHECK_FIELDS;
-  if (!_fields_used) { o = basis::common::NOT_FOUND; return 0; }
-  for (int i = 0; i < elements(); i++) {
-    if (basis::array<contents *>::get(i) == to_locate) {
-      o = basis::common::OKAY;
-      return i; 
-    }
-  }
-  o = basis::common::NOT_FOUND;
-  return 0;
-}
-
-template <class contents>
-contents *amorph<contents>::borrow(int field)
-{
-  FUNCDEF("borrow");
-  CHECK_FIELDS;
-  bounds_return(field, 0, elements() - 1, NIL);
-  return basis::array<contents *>::access()[field];
-}
-
-template <class contents>
-void amorph<contents>::swap_contents(amorph<contents> &other)
-{
-  FUNCDEF("swap_contents");
-  CHECK_FIELDS;
-  int hold_fields = _fields_used;
-  _fields_used = other._fields_used;
-  other._fields_used = hold_fields;
-  this->basis::array<contents *>::swap_contents(other);
-}
-
-template <class contents>
-int amorph_packed_size(const amorph<contents> &to_pack)
-{
-  int parts_size = 0;
-  for (int i = 0; i < to_pack.elements(); i++) {
-    const contents *current = to_pack.get(i);
-    if (current) parts_size += current->packed_size();
-  }
-  return PACKED_SIZE_INT32 + parts_size;
-}
-
-template <class contents>
-void amorph_pack(basis::byte_array &packed_form, const amorph<contents> &to_pack)
-{
-  structures::attach(packed_form, to_pack.elements());
-  for (int i = 0; i < to_pack.elements(); i++) {
-    const contents *current = to_pack.get(i);
-    if (current) current->pack(packed_form);
-  }
-}
-
-template <class contents>
-bool amorph_unpack(basis::byte_array &packed_form, amorph<contents> &to_unpack)
-{
-  to_unpack.reset();
-  int elem = 0;
-  if (!structures::detach(packed_form, elem)) return false;
-  for (int i = 0; i < elem; i++) {
-    contents *to_add = new contents;
-    if (!to_add->unpack(packed_form)) { delete to_add; return false; }
-    to_unpack.append(to_add);
-  }
-  return true;
-}
-
-template <class contents>
-void amorph_assign(amorph<contents> &to_assign,
-    const amorph<contents> &to_copy)
-{
-  if (&to_assign == &to_copy) return;
-  to_assign.clear_all();
-  if (to_assign.elements() != to_copy.elements()) {
-    to_assign.zap(0, to_assign.elements() - 1);
-    to_assign.insert(0, to_copy.elements());
-  }
-  for (int i = 0; i < to_assign.elements(); i++) {
-    if (to_copy.get(i)) to_assign.put(i, new contents(*to_copy.get(i)));
-    else to_assign.put(i, (contents *)NIL);
-  }
-}
-
-#undef static_class_name
-
-} //namespace.
-
-#endif
-