Listing 1
#include <iostream>
#include <ostream>
using namespace std;
// an example, user-defined class with custom stream operators
// state object packed in the long slot
// the hypothetical complex class
class mycomplex
{
double re_, im_;
public:
mycomplex(double r, double i) : re_(r), im_(i) {}
static int myindex()
{
static int index = ios_base::xalloc();
return index;
}
ostream& print(ostream &os) const
{
// get the stream state from the private slot
long &val = os.iword(myindex());
char left, right;
if (val == 0)
{
// this stream does not have the bracketing set, use defaults
left = '(';
right = ')';
}
else
{
left = (char)((val & 0xff00) >> 8);
right = (char)(val & 0xff);
}
return os << left << re_ << ", " << im_ << right;
}
// other operations omitted
};
ostream & operator<<(ostream &os, const mycomplex &cplx)
{
return cplx.print(os);
}
// the "state" object, here only for convenience
struct bracketing
{
bracketing(char l, char r) : left_(l), right_(r) {}
char left_, right_;
};
// convenience modifier with inserter operator
bracketing setbrackets(char l, char r)
{
return bracketing(l, r);
}
ostream & operator<<(ostream &os, bracketing b)
{
// set the stream state in the private slot
long &val = os.iword(mycomplex::myindex());
val = (b.left_ << 8) + b.right_;
return os;
}
int main()
{
mycomplex c(3.14, 2.71);
// use default bracketing style
cout << c << endl;
// change the bracketing style
cout << setbrackets('[', ']');
cout << c << endl;
}