/* c-listf.c     v1.0  (C) 2000 adolfo&di-mare.com */

#include "clistf.h"
#include "iostream.h"
#include "iomanip.h"

typedef unsigned long UL;
typedef unsigned long T;

void print_list(clistfT<T> &L) {
    cout << "  [";

    clistfT<T>::iterator p = L.begin();
    while (p != L.end()) {
        cout << *p << ":";
        p++;
    }
    cout << "] ";
}


void print_list_ai(clistfT<T> &L) {
    clistfT<T>::iterator   pi;
    clistf::list_link * next;

//  assert( (L._last.marked() ? L._last.um()->next.ai() == L.begin().ai() : 1));
/*
    pi = L.last(); next = pi.um(); next = next->next.ai();
    cout << "\nlast <" << pi.ai() << ">--> " << *pi << " ";
    cout << "next [" << next << "]";
    assert (pi == L.last());

    pi = L.begin(); next = pi.um(); next = next->next.ai();
    cout << "\nbegin<" << pi.ai() << ">--> " << *pi << " ";
    cout << "next [" << next << "]";
    assert (pi == L.begin());
*/
    cout << "\n";
    pi = L.begin();
    while (pi != L.end()) {
        cout << "\n     <" << pi.ai() << ">--> " << setw(2) << *pi  << " ";
        next = pi.um(); next = next->next.ai();
        cout << "next [" << next << "]";
        pi++;
        cout << " == [" << pi.ai() << "]";
    }
    cout << "\n";
}

void primes(clistfT<T> &L, unsigned n) {
/*------------------------------------------------*\
| Prepends to L the prime numbers smaller than "n" |
\*------------------------------------------------*/

    for (UL i = 1; i<n; i++) {
        int j, is_prime = 1;
        for (j = 2; j<i; j++) {
            if (0 == i % j) {
               is_prime = 0;
            }
        }
        if (is_prime) {
            clistfT<T>::iterator q = clistfT<T>::create(i);
            clistfT<T>::node    *p = q.np();

            *q = i;
            L.push_front(p->lk);
        }
    }
}

int main() {
    clistfT<T> L;

{   // primes
    clistfT<T> L;
    primes(L, 100);
    print_list_ai(L);
}   // primes

{   // linking
    cout << "\n\n=============================";
    cout << "  #(L) == " << L.count();
    for (T i=5; i<10; i++) {
    //  clistfT<T>::node    *p;//new clistfT<T>::node(i);
        clistfT<T>::iterator q = clistfT<T>::create(i);
        clistfT<T>::node    *p = q.np();

        assert(p != 0);
        p->e += 5;
        *q   += 5;
        cout << "\n     <" << &p->lk << "> -> " << *q;
//      cout << "\n<" << p->e << " -> " << *q << ">";
        assert(p->e == *q); assert(ptrbit::aligned(p));

        L.push_back(p->lk);
        cout << "  #(L) == " << L.count();

        print_list_ai(L);
/*
        cout
           << "("
           << (UL) (p)               << "|"
           << (UL) (p->lk.address()) << "->"
           << (UL) (p->lk.value())
           << ")"
           ;
*/
    }
}   // linking

{   // nth && pos
    clistfT<T>::iterator q;
    q = L.end();  assert(!L.valid(q));

    cout << "\n\n ";
    for (int i=0; i<L.count(); i++) {
        q = L.nth(i);
        assert(L.valid(q));
        cout << "L[" << i << "] = " << *q << " --> ";
    }
    cout << "L.end()\n ";
    for (i=0; i<L.count(); i++) {
        q = L.nth(i);
        assert(L.valid(q));
        cout << "L[" << L.pos(q) << "] = " << *q << " --> ";
    }
    cout << L.pos(++q);
}   // nth && pos

{   // prev
    clistfT<T>::iterator p,q;
    cout << "\n\n ";
    q = L.last();  assert(L.valid(q));
    p = q;
    for (int i=1; i<L.count(); i++) {
        cout << "L[" << L.pos(p) << "] = " << *p << " --> ";
        p = q.prev(); q = p;
        assert(L.valid(p));
    }
    cout << "L[" << L.pos(p) << "] = " << *p;

}   // prev

{
    cout << "\n\n=============================";
    cout << "  #(L) == " << L.count();

    print_list_ai(L);
    while (L.count() > 3) {
        cout << "\n     #(L) == " << L.count();
        clistfT<T>::iterator q = L.unlink_after(L.begin());
        cout << "  Unlinking " << *q;
        clistfT<T>::destroy(q);
        cout << "  #(L) == " << L.count();

        print_list_ai(L);
    }

    {   assert(3 == L.count());
        cout << "\n     #(L) == " << L.count();
        clistfT<T>::iterator q = L.unlink_after(++L.begin());
        cout << "  Unlinking " << *q;
        clistfT<T>::destroy(q);
        cout << "  #(L) == " << L.count();

        print_list_ai(L);
    }

    {   assert(2 == L.count());
        cout << "\n     #(L) == " << L.count();
        clistfT<T>::iterator q = L.unlink_after(L.begin());
        cout << "  Unlinking " << *q;
        clistfT<T>::destroy(q);
        cout << "  #(L) == " << L.count();

        print_list_ai(L);
    }

    while (!L.empty()) {
        cout << "\n     #(L) == " << L.count();
        clistfT<T>::iterator q = L.unlink_after(0);
        cout << "  Unlinking " << *q;
        clistfT<T>::destroy(q);
        cout << "  #(L) == " << L.count();
    }

    cout << "\n\n=============================";
    cout << "  #(L) == " << L.count();
}   // unlinking
    return 0;
}

void ptrbit_test() {
    ptrbit t;
    char   v[2];
    UL      diff;

    t.set(NULL);
    diff = (UL)t.ai()-(UL)t.vp();
    assert (!t.marked() && t.ai() == NULL || diff == 0);

    t.mark();
    diff = (UL)t.ai()-(UL)t.vp();
    assert (t.marked() && diff == 1);

    t.set(&t);
    diff = (UL)t.ai()-(UL)t.vp();
    assert (!t.marked() && t.vp()==t.ai() && diff == 0);

    t.mark();
    diff = (UL)t.ai()-(UL)t.vp();
    assert (t.marked() && t.ai() != &t && t.vp()!=t.ai() && diff == 1);

    t.unmark();
    diff = (UL)t.ai()-(UL)t.vp();
    assert (!t.marked() && t.ai() == &t && diff == 0);

    t.set(&v[1]);
    diff = (UL)t.ai()-(UL)t.vp();
    assert (t.marked() && t.vp()!=t.ai() && diff == 1 && t.ai()==&v[1]);

    t.unmark();
    diff = (UL)t.ai()-(UL)t.vp();
    assert (!t.marked() && t.vp()==t.ai() && diff == 0 && t.ai()==v);

}  // ptrbit_test()

/* EOF:   c-listf.c */
