Wrapper for Clustal Omega.
[jabaws.git] / binaries / src / clustalo / src / hhalign / list-C.h
diff --git a/binaries/src/clustalo/src/hhalign/list-C.h b/binaries/src/clustalo/src/hhalign/list-C.h
new file mode 100644 (file)
index 0000000..5cda100
--- /dev/null
@@ -0,0 +1,600 @@
+/* -*- mode: c; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+
+/*********************************************************************
+ * Clustal Omega - Multiple sequence alignment
+ *
+ * Copyright (C) 2010 University College Dublin
+ *
+ * Clustal-Omega 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 file is part of Clustal-Omega.
+ *
+ ********************************************************************/
+
+/*
+ * RCS $Id: list-C.h 143 2010-10-14 13:11:14Z andreas $
+ */
+
+// list.C
+// Class for double-linked list 
+
+
+
+#ifndef JLIST
+#define JLIST
+
+#ifndef MAIN
+#include <iostream>   // cin, cout
+#include <stdlib.h>   // 
+#include <stdio.h>    // 
+using std::cout;
+using std::cerr;
+#endif
+
+#include "list.h"
+
+////////////////////////////////////////////////////////////////////////////
+// Double-linked list implementation with head and tail dummy elements
+// We set head->prev=head and tail->next=tail.
+// This makes sure that repeated current=current->next; ends up in tail
+// and repeated current=current->prev; ends up in head.
+// head and tail optionally contain a NULL element of Typ defined by method Null(Typ)
+////////////////////////////////////////////////////////////////////////////
+
+
+
+////////////////////////////////////////////////////////////////////////////
+// Constructors and destructor
+
+////////////////////////////////////////////////////////////////////////////
+// Creates empty List with two dummy elements
+////////////////////////////////////////////////////////////////////////////
+template <class Typ> 
+List<Typ>::List()
+{
+  head=new ListEl<Typ>();
+  if (!head) { cerr<<"Could not create new element\n"; return; }
+  tail=new ListEl<Typ>(head,NULL);
+  if (!tail) { cerr<<"Could not create new element\n"; return; }
+  tail->next = tail;
+  head->prev = head;
+  head->next = tail;
+  current = head;
+  size=0;
+}
+
+////////////////////////////////////////////////////////////////////////////
+// Creates List with one element 
+////////////////////////////////////////////////////////////////////////////
+template <class Typ> 
+List<Typ>::List(Typ d)
+{
+  head=new ListEl<Typ>();
+  if (!head) { cerr<<"Could not create new element\n"; return; }
+  tail=new ListEl<Typ>();
+  if (!tail) { cerr<<"Could not create new element\n"; return; }
+  ListEl<Typ>* el = new ListEl<Typ>(d,head,tail);
+  if (!el)   { cerr<<"Could not create new element\n"; return; }
+  head->prev = head;
+  head->next = el;
+  tail->prev = el;
+  tail->next = tail;
+  current = head;
+  size=1;
+}
+
+////////////////////////////////////////////////////////////////////////////
+// Destructor deletes List object
+////////////////////////////////////////////////////////////////////////////
+template <class Typ> 
+List<Typ>::~List()
+{
+  ListEl<Typ>* n=head->next;
+  while(head!=n)
+    {
+      delete(head); head = NULL;
+      head=n;
+      n=head->next;
+  }
+  delete(head); head = NULL;
+}
+
+////////////////////////////////////////////////////////////////////////////
+// Flat copy
+////////////////////////////////////////////////////////////////////////////
+template <class Typ> 
+List<Typ>& List<Typ>::operator=(List<Typ>& l)
+{
+  head = l.head;
+  tail = l.tail;
+  current = l.current;
+  size = l.size;
+}
+
+
+////////////////////////////////////////////////////////////////////////////
+// Reverse order of list
+////////////////////////////////////////////////////////////////////////////
+template <class Typ> 
+void List<Typ>::Reverse()
+{
+  ListEl<Typ> *n; // next list element; also for swapping
+  ListEl<Typ> *c; // current element to be sorted in. Everything to the left is already sorted
+  if (Size()<=1) return;
+  for (c=head; c!=tail; c=n)
+    {
+      // Swap prev and next pointers of all list elements
+      n = c->next;
+      c->next = c->prev;
+      c->prev = n;
+    }
+  
+  // Swap prev and next pointers of tail
+  tail->next = tail->prev;
+  tail->prev = tail;
+
+  // Swap head an tail
+  n = head;
+  head = tail;
+  tail = n;
+}
+
+
+
+
+////////////////////////////////////////////////////////////////////////////
+// Methods that act at the end of the list 
+
+////////////////////////////////////////////////////////////////////////////
+// Insert Element after LAST of list  (and return address of data element)
+////////////////////////////////////////////////////////////////////////////
+template <class Typ> 
+Typ* List<Typ>::Push(Typ d)
+{ 
+  ListEl<Typ>* t=new ListEl<Typ>(d,tail->prev,tail); 
+  if (!t) { cerr<<"Could not create new element\n"; return 0; }
+  tail->prev->next=t;
+  tail->prev = t;
+  size++;
+  return &(t->data);
+} 
+
+////////////////////////////////////////////////////////////////////////////
+// Remove and return LAST element of list. Returns head->data if empty
+////////////////////////////////////////////////////////////////////////////
+template <class Typ> 
+Typ List<Typ>::Pop()
+{
+  if (!size) return head->data;
+  ListEl<Typ>* t=tail->prev;
+  if (current==t) current=tail;
+  Typ d=t->data;
+  t->prev->next=tail;
+  tail->prev=t->prev;
+  delete t; t = NULL;
+  size--;
+  return d;
+}
+
+
+
+////////////////////////////////////////////////////////////////////////////
+// Methods that act at the beginning of the list
+
+////////////////////////////////////////////////////////////////////////////
+// Insert element as FIRST element of list (and return address of data element)
+////////////////////////////////////////////////////////////////////////////
+template <class Typ> 
+Typ* List<Typ>::Enqueue(Typ d)
+{
+  ListEl<Typ>* h = new ListEl<Typ>(d,head,head->next); 
+  if (!h) { cerr<<"Could not create new element\n"; return 0; }
+  h->next->prev = h;
+  head->next=h;
+  size++;
+  return &(h->data);
+} 
+
+////////////////////////////////////////////////////////////////////////////
+// Remove element at BEGINNING of list
+////////////////////////////////////////////////////////////////////////////
+template <class Typ> 
+Typ List<Typ>::Dequeue()
+{
+  if (!size) return head->data;
+  ListEl<Typ>* h=head->next;
+  if (current==h) current=head;
+  Typ d=h->data;
+  h->next->prev=head;
+  head->next=h->next;
+  delete h; h = NULL;
+  size--;
+  return d;
+} 
+
+////////////////////////////////////////////////////////////////////////////
+// Methods that work with 'current' position in the list
+
+////////////////////////////////////////////////////////////////////////////
+// Reads next element; advances current position by 1
+////////////////////////////////////////////////////////////////////////////
+template <class Typ> 
+inline Typ List<Typ>::ReadNext()
+{
+  current = current->next;
+  return current->data;
+}
+
+////////////////////////////////////////////////////////////////////////////
+// Reads current element again (NULL if nothing read yet)
+////////////////////////////////////////////////////////////////////////////
+template <class Typ> 
+inline Typ List<Typ>::ReadCurrent()
+{
+  return current->data;
+}
+
+////////////////////////////////////////////////////////////////////////////
+// Reads previous element; moves current position back by 1
+////////////////////////////////////////////////////////////////////////////
+template <class Typ> 
+inline Typ List<Typ>::ReadPrevious()
+{
+  current = current->prev;
+  return current->data;
+}
+
+////////////////////////////////////////////////////////////////////////////
+// Reads next element; advances current position by 1
+////////////////////////////////////////////////////////////////////////////
+template <class Typ> 
+inline Typ* List<Typ>::ReadNextAddress()
+{
+  current = current->next;
+  if (current==tail) return NULL;
+  return &(current->data);
+}
+
+////////////////////////////////////////////////////////////////////////////
+// Reads address of current element again, returns NULL if at end of list
+////////////////////////////////////////////////////////////////////////////
+template <class Typ> 
+inline Typ* List<Typ>::ReadCurrentAddress()
+{
+  if (current==tail) return NULL;
+  return &(current->data);
+}
+
+////////////////////////////////////////////////////////////////////////////
+// Sets current position to k and reads k'th element (first=1)
+////////////////////////////////////////////////////////////////////////////
+template <class Typ>
+Typ List<Typ>::Read(int pos)
+{
+  if (pos>size) {current = tail; return tail->data;}
+  if (pos<=0)   {current = head; return head->data;}
+  current = head->next;
+  for (; pos>1; pos--) current = current->next; //If pos==2 do 1 iteration
+  return current->data;
+}
+
+////////////////////////////////////////////////////////////////////////////
+// Inserts element d AFTER current element and sets current element to inserted
+////////////////////////////////////////////////////////////////////////////
+template <class Typ> 
+void List<Typ>::Insert(Typ d)
+{
+  ListEl<Typ>* el = new ListEl<Typ>(d,current,current->next); 
+  if (!el) { cerr<<"Could not create new element\n"; return; }
+  (current->next)->prev = el;
+  current->next = el;
+  current=el;
+  size++;
+}
+
+////////////////////////////////////////////////////////////////////////////
+// Deletes current element and returns content of deleted element. Current element 
+// will be previous one after Delete(). After Reset() delete first element (not 0'th)
+////////////////////////////////////////////////////////////////////////////
+template <class Typ> 
+Typ List<Typ>::Delete()
+{
+  Typ d;
+  ListEl<Typ>* p;
+  if (!size || current==tail) return tail->data;
+  if (current==head) current = head->next; // After Reset() delete first element (not 0'th)     
+  (current->prev)->next = current->next;
+  (current->next)->prev = current->prev;
+  d = current->data;
+  p = current->prev;
+  delete current; current = NULL;
+  current = p;
+  size--;
+  return d;
+}
+
+////////////////////////////////////////////////////////////////////////////
+// Methods that return useful information about the list
+
+////////////////////////////////////////////////////////////////////////////
+// Get current position within list (0 <= pos <= Size+1) 
+////////////////////////////////////////////////////////////////////////////
+template <class Typ>
+int List<Typ>::GetPos()
+{
+  int pos=0;
+  ListEl<Typ>* el;
+  for (el = head; el!=current; el=el->next) pos++; 
+  return pos;
+}
+
+////////////////////////////////////////////////////////////////////////////
+//print out list
+////////////////////////////////////////////////////////////////////////////
+template <class Typ>
+void List<Typ>::PrintList()
+{
+  int j=0;
+  ListEl<Typ>* c=current;
+  Reset();
+  printf("List: ");
+  while (!End()) 
+    {
+      j++;
+      cout<<j<<" "<<ReadNext()<<"  ";
+      if (!(j%10)) cout<<"\n      ";
+    }
+  cout<<"\n";
+  current=c;
+}
+
+////////////////////////////////////////////////////////////////////////////
+// Get largest data element
+////////////////////////////////////////////////////////////////////////////
+template <class Typ>
+Typ List<Typ>::Largest()
+{
+  Typ* result= &((tail->prev)->data);
+  Reset();
+  while (!End()) 
+    {
+      if (*result<ReadNext()) result=ReadCurrentAddress();
+    }
+  return *result;
+}
+
+////////////////////////////////////////////////////////////////////////////
+// Get smallest data element
+////////////////////////////////////////////////////////////////////////////
+template <class Typ>
+Typ List<Typ>::Smallest()
+{
+  Typ* result= &((tail->prev)->data);
+  Reset();
+  while (!End()) 
+    {
+      if (ReadNext()<*result) result=ReadCurrentAddress();
+    }
+  return *result;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Methods that manipulate the list as a whole
+
+////////////////////////////////////////////////////////////////////////////
+// Copies list 0 into list object
+////////////////////////////////////////////////////////////////////////////
+template <class Typ> 
+void List<Typ>::Copy(List<Typ>* list)
+{
+  if (list==this) return;
+  while (!End()) Pop(); //empty list
+  list->Reset();
+  while (!list->End()) Push(list->ReadNext());
+}
+
+////////////////////////////////////////////////////////////////////////////
+// Appends a copy of list2 to class object
+////////////////////////////////////////////////////////////////////////////
+template <class Typ> 
+void List<Typ>::AppendCopy(List<Typ>* list2)
+{
+  List<Typ>* cpy=new List<Typ>;
+  cpy->Copy(list2);
+  Append(cpy);
+  delete cpy; cpy = NULL;
+}
+
+////////////////////////////////////////////////////////////////////////////
+// Appends list2 to class object
+////////////////////////////////////////////////////////////////////////////
+template <class Typ> 
+void List<Typ>::Append(List<Typ>* list)
+{
+  if (this==list) { AppendCopy(list); return;}
+  (tail->prev)->next = list->head->next;
+  (list->head->next)->prev = tail->prev;
+  if (current==tail) current=tail->prev; 
+  ListEl<Typ>* t=tail;
+  tail = list->tail;
+  size += list->size;
+
+// Reuse old tail as new tail t for list2 and initialize pointers for empty list 
+  list->tail=t;
+  list->head->next=t;
+  t->prev=list->head;
+  t->next=t;
+  list->head->prev=list->head;
+  t->data=list->head->data;
+  list->current=list->head;
+  list->size = 0;
+}
+
+////////////////////////////////////////////////////////////////////////////
+// Use QUICKSORT to sort list in ascending order between two list elements
+////////////////////////////////////////////////////////////////////////////
+template <class Typ> 
+void List<Typ>::SortList(ListEl<Typ>* left, ListEl<Typ>* right, int sz) 
+{
+  if (sz<=1) return; // when SortList() is called, left=head->next, right=tail->prev
+  ListEl<Typ> *l=left->prev, *r=right->next;
+
+  // Choose *random* pivot element!! 
+  // (Otherwise, complexity for an already sorted list is N^2 => recursive calls may lead to stack overflow)
+  ListEl<Typ> *c=left;
+  for (int i=1; i<(int)(float(rand())*sz/(RAND_MAX+0.999)); i++) c = c->next; 
+  SwapContent(left,c);
+
+  Typ pivot = left->data;
+//   Typ* pivot= &(left->data);
+  int sz0=sz+1;
+  //  cout<<"Sorting between "<<left->data<<" and "<<right->data<<". Pivot="<<pivot<<endl;
+  while(1)
+    {
+//        PrintList();
+      do {r=r->prev; sz0--;} while (pivot < r->data); 
+      do l=l->next; while (l->data < pivot);
+      if (l==r || l->prev==r) break;
+      SwapContent(l,r);
+    }
+  SortList(left,r,sz0);
+  SortList(r->next,right,sz-sz0);
+  pivot = tail->data; // to avoid calling the destructor of Typ on some real data element
+ }
+
+////////////////////////////////////////////////////////////////////////////
+// Use QUICKSORT to sort list of POINTERS by comparing the objects the pointers point to
+////////////////////////////////////////////////////////////////////////////
+template <class Typ> 
+void List<Typ>::SortPointerList(ListEl<Typ>* left, ListEl<Typ>* right) 
+{
+  if (right==left || right->next==left) return;
+  ListEl<Typ> *l=left->prev, *r=right->next;
+  Typ pivot=left->data;
+//    cout<<"Sorting between "<<left->data<<" and "<<right->data<<". Pivot="<<pivot<<endl;
+  while(1)
+    {
+//        PrintList();
+      do
+       {
+         r=r->prev;
+//       cout<<"r=r->prev. r->data="<<r->data<<endl;
+       } while(*pivot < *(r->data)); 
+      do
+       {
+         l=l->next;
+//       cout<<"l=l->next l->data="<<l->data<<endl;
+       } while (*(l->data) < *pivot);
+      if (l==r || l->prev==r) break;
+      SwapContent(l,r);
+    }
+  SortPointerList(left,r);
+  SortPointerList(r->next,right);
+}
+
+// Use INSERTSORT to sort list in asscending order between two list elements. Use only for presorted lists, otherwise time O(N^2)!
+template <class Typ> 
+void List<Typ>::ResortList() 
+{
+  ListEl<Typ> *c; // current element to be sorted in. Everything to the left is already sorted
+  ListEl<Typ> *n; // next element to be sorted in
+  ListEl<Typ> *p; // pointer for looping through sorted part of list
+  ListEl<Typ> *pnext; // for swapping
+  if (Size()<=1) return;
+  c=head->next->next;
+  while (c!=tail) 
+    {
+      p=c->prev;
+      n=c->next;
+      if (c->data < p->data)
+       {
+         do {p=p->prev;} while (p!=head && c->data < p->data);
+         // Connect c->prev to c->next ...
+         c->next->prev=c->prev;
+         c->prev->next=c->next;
+         // ... and insert c between p and p->next ...
+         pnext=p->next;
+         p->next=c;
+         c->next=pnext;
+         pnext->prev=c;
+         c->prev=p;
+       }
+      c=n;
+    }
+}
+
+
+#endif /* JLIST */
+
+
+// //Main program: test class List
+
+//  int main()
+//  {
+//    int p;
+//    List<int>* plist=new List<int>(11);
+//    List<int> list(22);
+
+//    plist->Push(24);
+//    plist->Push(18);
+//    plist->Push(3);
+//    plist->Enqueue(17);
+//    plist->Enqueue(29);
+//    printf("List 1 with pushed and enqueued elements:\n");
+//    plist->PrintList();
+
+//    list.Push(222);
+//    printf("List 1 with list 2 appended:\n");
+//    plist->Append(&list);
+//    plist->PrintList();
+
+//    printf("Pushing one element three times into list 2:\n");
+//    list.Push(333);
+//    list.Push(444);
+//    list.Push(555);
+//    printf("Printing plist and list with three elements:\n");
+//    list.PrintList();
+//    plist->PrintList();
+  
+//    printf("list.Copy(plist). Printing list 1 and 2:\n");
+//    list.Copy(plist);
+//    plist->PrintList(); 
+//    list.PrintList();
+
+//    printf("Appending list 1 to itself:\n");
+//    plist->Append(plist);
+//    plist->PrintList();
+
+//    cout<<"Popping "<<plist->Pop()<<"\n";
+//    cout<<"Popping "<<plist->Pop()<<"\n";
+//    plist->PrintList();
+
+//    cout<<"Dequeing "<<plist->Dequeue()<<"\n";
+//    cout<<"Dequeing "<<plist->Dequeue()<<"\n";
+//    plist->PrintList();
+
+//    cout<<"Reversing list\n";
+//    plist->Reverse();
+//    plist->PrintList();
+
+//    cout<<"Reversing to original list\n";
+//    plist->Reverse();
+//    plist->PrintList();
+
+//    for (p=plist->Reset(); p>=5;p--)
+//      {cout<<plist->GetPos()<<": "<<plist->Read(p)<<"\n";}
+  
+//    cout<<"Deleting "<<plist->Delete()<<"\n";
+//    cout<<"Deleting "<<plist->Delete()<<"\n";
+//    plist->PrintList();
+
+//    plist->Append(plist);
+//    plist->PrintList();
+//    cout<<"List 1 sorted:\n";
+//    plist->SortList();
+//    plist->PrintList();
+
+//  }