// except2.cc

// Test throwing through a C function: qsort()

// Due to a bug in GCC, this file must be compiled with optimization

#include <iostream.h>
#include <stdlib.h>

class A
{
private:
  int value;

public:
  void set (int x) { value = x; }
  int get () const { return value; }
  bool operator == (const A &x) const { return value == x.value; }
  bool operator < (const A &x) const { return value < x.value; }
  bool operator > (const A &x) const { return value > x.value; }
  void check () const;
};

void A::check () const
{
  if (value == 11)
    throw this;
}

int compare (const A *p1, const A *p2)
{
  p1->check ();
  p2->check ();
  if (*p1 < *p2)
    return -1;
  else if (*p1 > *p2)
    return 1;
  else
    return 0;
}

extern "C" int compare (const void *p1, const void *p2)
{
  return compare ((const A *)p1, (const A *)p2);
}


void test (int n)
{
  A *a = new A[n];
  for (int i = 0; i < n; ++i)
    a[i].set ((n-i) ^ 5);
  for (int i = 0; i < n; ++i)
    cout << ' ' << a[i].get ();
  cout << endl;
  try
    {
      qsort (a, n, sizeof (A), compare);
      for (int i = 0; i < n; ++i)
        a[i].check ();
    }
  catch (const A *p)
    {
      cout << "Caught access to a[" << p - a << "] = " << p->get () << endl;
    }
  for (int i = 0; i < n; ++i)
    cout << ' ' << a[i].get ();
  cout << endl;
  delete[] a;
}

int main (void)
{
  test (10);
  test (20);
  return 0;
}
