struct bar;
struct foo {
  operator bar*();
};

class Foo {
Foo operator+(const Foo& rhs) const;

const Foo& operator ==(Foo& me);

bool operator>(const Foo& rhs) const;

InStream& operator <<(InStream& in);
}

const Foo& Foo::operator ==(Foo& me)
{
}

Foo Foo::operator+(const Foo& rhs) const
{
}

bool Foo::operator>(const Foo& rhs) const
{
}

class Example
{
char m_array [256];

Example& operator=(const Example&rhs);
Example& operator+=(const Example&rhs);
const Example operator+(const Example&other) const;
bool operator==(const Example&other) const;
bool operator!=(const Example&other) const;
Example operator+(const Example& x, const Example& y);
Example operator*(const Example& x, const Example& y);

double& operator()(int row, int col);
double operator()(int row, int col) const;
void operator++();
int& operator*();
Example& operator++();        // prefix ++
Example operator++(int);      // postfix ++

bool operator <(const Example& lhs, const Example& rhs) const;

int operator()(int index)
{
  i = ~~3;
  return index + 1;
}

char& operator[](unsigned i)
{
  return m_array [i & 0xff];
}
}
bool Example::operator==(const Example&other) const
{
  /*TODO: compare something? */
  return false;
}

bool Example::operator!=(const Example&other) const
{
  return !operator ==(other);
}

void a()
{
  Op op = &X::operator==;
  if (!A) {
    if (op != &X::operator==) {
      A(1) = a;
    }
  }
  if (!A) {
    if (op != &X::operator==) {
      A(1) = a;
    }
  }
}

void *operator new(std::size_t) throw(std::bad_alloc);
void *operator new[](std::size_t) throw(std::bad_alloc);
void operator delete(void *) throw();
void operator delete[](void *) throw();
