#include "indent.hpp"
#include <iostream>
typedef std::ostream marg_ostream;

boost::iostreams::filtering_ostream out;
marg_ostream& mout(void)
{ 
    return out;
}
//#define DEBUG_PRINT
void operator++(marg_ostream& sout)
{
    #ifdef DEBUG_PRINT
    sout<<"operator++(marg_ostream&)\n";
    #endif
    sout<<indent_in;
}
void operator--(marg_ostream& sout)
{
    sout<<indent_out;
    #ifdef DEBUG_PRINT
    sout<<"operator--(marg_ostream&)\n";
    #endif
}
  struct
test
  {
    test(char const* a_str,double a_dbl)
      : my_str(a_str)
      , my_dbl(a_dbl)
      {}
      char const*
    my_str
      ;
      double
    my_dbl
      ;
  };

//#define SPECIALIZED_TEST_PTR        

  marg_ostream&
operator<<
  ( marg_ostream& sout
  , test const& a_test
  )
  {
  ; sout<<":my_str="<<a_test.my_str<<":my_dbl="<<a_test.my_dbl<<"\n"
  ; return sout
  ;}

#ifndef  SPECIALIZED_TEST_PTR
  marg_ostream&
operator<<
  ( marg_ostream& sout
  , test const* a_test
  )
  {
  ; if(a_test)
    {
    ; sout<<"*(test*)="<<*a_test
    ;}
    else
    {
    ; sout<<"(test*)0"
    ;}
  ; return sout;
  ;}
  marg_ostream&
operator<<
  ( marg_ostream& sout
  , test* a_test
  )
  {
  ;  return sout<<static_cast<test const*>(a_test)
  ;}
#endif
int main(void)
  {
//  ; boost::iostreams::filtering_ostream out
  ; indent_filter::push(out,2)
  ; out.push(std::cout)
  ; mout()<<"line1\n"
  ; ++mout()
  ; mout()<<"line1.1"<<std::endl
  ; ++mout()
  ; mout()<<"line1.1.1"<<std::endl
  ; --mout()
  ; unsigned u=22
  ; mout()<<"line1.2:unsigned="<<u<<std::endl
  ; float f=3.1416
  ; mout()<<"line1.3:float="<<f<<std::endl
  ; --mout()
  ; test a_test("a_test string",9.999)
  ; mout()<<"line2:a_test="<<a_test<<std::endl
  ; ++mout()
  ; mout()<<"(test*)0="<<static_cast<test const*>(0)<<std::endl
  ; mout()<<"&a_test="<<static_cast<test const*>(&a_test)<<std::endl
  ; return 0
  ;}
