/* This test script is part of GDB, the GNU debugger.

   Copyright 1999-2021 Free Software Foundation, Inc.

   This program 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 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include <iostream>

using namespace std;

void marker1()
{
  return;
}

class A1 {
  int x;
  int y;

friend ostream& operator<<(ostream& outs, A1 one);

public:

  A1(int a, int b)
  {
   x=a;
   y=b;
  }

A1 operator+=(int value);
A1 operator+(const A1&);
A1 operator-(const A1&);
A1 operator%(const A1&);
int operator==(const A1&);
int operator!=(const A1&);
int operator&&(const A1&);
int operator||(const A1&);
A1 operator<<(int);
A1 operator>>(int);
A1 operator|(const A1&);
A1 operator^(const A1&);
A1 operator&(const A1&);
int operator<(const A1&);
int operator<=(const A1&);
int operator>=(const A1&);
int operator>(const A1&);
A1 operator*(const A1&);
A1 operator/(const A1&);
A1 operator=(const A1&);

A1 operator~();
A1 operator+();
A1 operator-();
int operator!();
A1 operator++();
A1 operator++(int);
A1 operator--(); 
A1 operator--(int);

};


A1 A1::operator+(const A1& second)
{
 A1 sum(0,0);
 sum.x = x + second.x;
 sum.y = y + second.y;
 
 return (sum);
}

A1 A1::operator*(const A1& second)
{
 A1 product(0,0);
 product.x = this->x * second.x;
 product.y = this->y * second.y;
 
 return product;
}

A1 A1::operator-(const A1& second)
{
 A1 diff(0,0);
 diff.x = x - second.x;
 diff.y = y - second.y;
 
 return diff;
}

A1 A1::operator/(const A1& second)
{
 A1 div(0,0);
 div.x = x / second.x;
 div.y = y / second.y;
 
 return div;
}

A1 A1::operator%(const A1& second)
{
 A1 rem(0,0);
 rem.x = x % second.x;
 rem.y = y % second.y;
 
 return rem;
}

int A1::operator==(const A1& second)
{
 int a = (x == second.x);
 int b = (y == second.y);
 
 return (a && b);
}

int A1::operator!=(const A1& second)
{
 int a = (x != second.x);
 int b = (y != second.y);
 
 return (a || b);
}

int A1::operator&&(const A1& second)
{
 return ( x && second.x);
}

int A1::operator||(const A1& second)
{
 return ( x || second.x);
}

A1 A1::operator<<(int value)
{
 A1 lshft(0,0);
 lshft.x = x << value;
 lshft.y = y << value;
 
 return lshft;
}

A1 A1::operator>>(int value)
{
 A1 rshft(0,0);
 rshft.x = x >> value;
 rshft.y = y >> value;
 
 return rshft;
}

A1 A1::operator|(const A1& second)
{
 A1 abitor(0,0);
 abitor.x = x | second.x;
 abitor.y = y | second.y;
 
 return abitor;
}

A1 A1::operator^(const A1& second)
{
 A1 axor(0,0);
 axor.x = x ^ second.x;
 axor.y = y ^ second.y;
 
 return axor;
}

A1 A1::operator&(const A1& second)
{
 A1 abitand(0,0);
 abitand.x = x & second.x;
 abitand.y = y & second.y;
 
 return abitand;
}

int A1::operator<(const A1& second)
{
 A1 b(0,0);
 b.x = 3;
 return (x < second.x);
}

int A1::operator<=(const A1& second)
{
 return (x <= second.x);
}

int A1::operator>=(const A1& second)
{
 return (x >= second.x);
}

int A1::operator>(const A1& second)
{
 return (x > second.x);
}

int A1::operator!(void)
{
 return (!x);
}

A1 A1::operator-(void)
{
 A1 neg(0,0);
 neg.x = -x;
 neg.y = -y;

 return (neg);
}

A1 A1::operator+(void)
{
 A1 pos(0,0);
 pos.x = +x;
 pos.y = +y;

 return (pos);
}

A1 A1::operator~(void)
{
 A1 acompl(0,0);
 acompl.x = ~x;
 acompl.y = ~y;

 return (acompl);
}

A1 A1::operator++() // pre increment
{
 x = x +1;
 
 return (*this);
}

A1 A1::operator++(int) // post increment
{
 y = y +1;
 
 return (*this);
}

A1 A1::operator--() // pre decrement
{
 x = x -1;
 
 return (*this);
}

A1 A1::operator--(int) // post decrement
{
 y = y -1;
 
 return (*this);
}


A1 A1::operator=(const A1& second)
{

 x = second.x;
 y = second.y;

 return (*this);
}

A1 A1::operator+=(int value)
{

 x += value;
 y += value;

 return (*this);
}

ostream& operator<<(ostream& outs, A1 one)
{
 return (outs << endl << "x = " << one.x << endl << "y = " << one.y << endl << "-------" << endl); 
}

class A2 {
  public:
A2 operator+();
};

A2 A2::operator+()
{
  return A2 ();
}

class Member
{
public:
  int z;
};

bool operator== (const Member &m1, const Member &m2)
{
  return m1.z == m2.z;
}

class Container
{
public:
  Member m;

  Member& operator* ();
};

Member& Container::operator* ()
{
  return this->m;
}

int main (void)
{
 A1 one(2,3);
 A1 two(4,5);
 A1 three(0,0);
 Container c;
 Member mem1, mem2;
 int val;
 
 mem1.z = 5;
 mem2.z = 7;

 marker1(); // marker1-returns-here
 cout << one; // marker1-returns-here
 cout << two;
 three = one + two;
 cout << "+ " <<  three;
 three = one - two;
 cout <<  "- " << three;
 three = one * two;
 cout <<"* " <<  three;
 three = one / two;
 cout << "/ " << three;
 three = one % two;
 cout << "% " << three;
 three = one | two;
 cout << "| " <<three;
 three = one ^ two;
 cout << "^ " <<three;
 three = one & two;
 cout << "& "<< three;

 val = one && two;
 cout << "&& " << val << endl << "-----"<<endl;
 val = one || two;
 cout << "|| " << val << endl << "-----"<<endl;
 val = one == two;
 cout << " == " << val << endl << "-----"<<endl;
 val = one != two;
 cout << "!= " << val << endl << "-----"<<endl;
 val = one >= two;
 cout << ">= " << val << endl << "-----"<<endl;
 val = one <= two;
 cout << "<= " << val << endl << "-----"<<endl;
 val = one < two;
 cout << "< " << val << endl << "-----"<<endl;
 val = one > two;
 cout << "> " << val << endl << "-----"<<endl;
 
 three = one << 2;
 cout << "lsh " << three;
 three = one >> 2;
 cout << "rsh " << three;

 three = one;
 cout << " = "<< three;
 three += 5;
 cout << " += "<< three;
 
 val = (!one);
 cout << "! " << val << endl << "-----"<<endl;
 three = (+one);
 cout << "+ " << three;
 three = (-one);
 cout << "- " << three;
 three = (~one);
 cout << " ~" << three;
 three++;
 cout << "postinc " << three;
 three--;
 cout << "postdec " << three;
 
 --three;
 cout << "predec " << three;
 ++three;
 cout << "preinc " << three;

 (*c).z = 1;

 return 0;

}
