struct results
{ double value;
  bool present;

results(double v, bool p)
{ value = v;
  present = p; } };

results lookup(string v, memlink * ptr)
{ while (ptr != NULL)
  { if (ptr->var == v)
      return results(ptr->val, true);
    ptr = ptr->next; }
  return results(0.0, false); }
      
typical use

results r = lookup("pi", d);
if (r.present)
  use r.value
else
  maybe error



template <typename T>
  class linked_list
  { protected:
      struct link
      { T data;
        link * next;

        link(const T & x, link * n = NULL)
        { data = x;
          next = n; } };

      link * first;

    public:
      linked_list()
      { first = NULL; }

      void add_to_front(T x)
      { first = new link(x, first); }

      template <typename Q>
      T find(bool match(T, Q), Q wanted, bool & found)
      { link * ptr = first;
        while (ptr != NULL)
        { if (match(ptr->data, wanted))
          { found = true;
            return ptr->data; } }
        T x; 
        return x; }

example

  struct person
  { string fname, lname;
    int ssn, zip; }

  linked_list<person> D;

  D.add_to_front(person("Jill", "Jones", 111111111, 33333));
  ...
  
  bool compare(person p, string s)
  { return p->lname == s; }

  D.find(compare, "Jones");

__________________________________________________________


    protected:
      int len;

    public:
      linked_list()
      { first = NULL;
        len = 0; }

      void add_to_front(T x)
      { first = new link(x, first);
        len += 1; }

      template <typename Q>
      T find(bool match(T, Q), Q wanted, bool & found)
      { link * ptr = first;
        while (ptr != NULL)
        { if (match(ptr->data, wanted))
          { found = true;
            return ptr->data; } }
        T x; 
        return x; }

      int length()         // this version when no int len
      { int count = 0;
        link * ptr = first;
        while (ptr != NULL)
        { ptr = ptr->next;
          count += 1; }
        return count; }

alternative

      int length()
      { return len; }


------------------------
  remove first and add last when last is not recorded

      T remove_first()
      { T value = first->data;
        link * nxt = first->next;
        delete first;
        first = nxt;
        return value; }

      void add_to_end(T newitem)
      { link * ptr = first, * prev = NULL;
        while (ptr != NULL)
        { prev = ptr;
          ptr = ptr->next; }
        if (prev == NULL)     // means list is empty
          first = new link(newitem, NULL);
        else
          prev->next = new link(newitem, NULL); }

------------------------------
much better to record the end is adding to the end is going to be needed


class LLint
{ protected:
    struct link ... as before

    link * first, * last;

  public:
    LLint()
    { first = NULL;
      last = NULL; }

    void add_to_front(int newval)
    { if (first == NULL)
      { first = new link(newval, NULL);
        last = first; }
      else
        first = new link(newval, first); }

    void add_to_end(int newval)
    { if (first == NULL)
      { first = new link(newval, NULL);
        last = first; }
      else
      { link * newlink = new link(newval, NULL);
        last->next = newlink;
        last = newlink; } };