#include <stdio.h>
#include<iostream>
using namespace std;
#define endl '\n'
class syp{
ostream* ost; // output stream pointer
public:
syp(ostream* is){ // accepting 'cout' as constructor argument
ost = is; // assigning 'cout' to output stream ost
}
friend syp operator<<(const syp&, const char*); //(lft operand -> class obj,rht operand -> char*/int /double)
friend syp operator<<(const syp&, const int); // e.g. syp<<8;
friend syp operator<<(const syp& s, const double x);
friend syp operator<<(const syp& s, const char c);
};
syp operator<<(const syp& s, const char c){
s.ost->put(c); // put (const char) is a function of ostream class
return s; // return class syp object 's'
}
syp operator<<(const syp& s, const char* os){
s.ost->write(os,strlen(os)); // write (const char*, length) is a function of ostream class
return s;
}
syp operator<<(const syp& s, const int x){
s.ost->operator<<(x); // operator<<(const int) is an operator of ostream class
return s;
}
syp operator<<(const syp& s, const double x){
s.ost->operator<<(x); //operator<<(const double) is an operator of ostream class
return s;
}
int main(){
double d1 = 12.3;
int i1 = 45;
syp s(&cout);
spy << "abc" << endl; // #define endl '\n' -> i.e. char '\n', this uses operator<<(class object, const char )
// Cascading
// As a compiler calculating e.g. --> 1 + 2 + 3 => (1 + 2) + 3 => 3 + 3
// In the same way --> s<<'a'<<2<<"hello" ; returns class syp object s
// o/p on screen => a
// => s << 2<<"hello" ; returns class object s
// o/p => 2
// => s<<"hello" ;
// o/p => hello
s << "d1=" << d1 << " i1=" << i1 << 'z' << endl;
return 0;
}