#include <iostream>
#include <fstream>

class IndentClass {
    public:
        IndentClass();
        ~IndentClass();
    
    private:
        std::string IndentText;
        int _Indent;
    
    public:
        inline void SetIndentText(const char* Text);
        inline void Indent(int Amount);
        inline void SetIndent(int Amount);
        
        inline void ind (std::ostream& ofs);
        
        class Ind_t {
            public:
                IndentClass& state;
                Ind_t (IndentClass& _state) : state(_state) {}
                friend inline std::ostream& operator<< (std::ostream& ofs, Ind_t& ind);
        };
        class IndS_t {
            public:
                IndentClass& state;
                IndS_t (IndentClass& _state) : state(_state) {}
                friend inline std::ostream& operator<< (std::ostream& ofs, IndS_t& ind);
        };
        class IndE_t {
            public:
                IndentClass& state;
                IndE_t (IndentClass& _state) : state(_state) {}
                friend inline std::ostream& operator<< (std::ostream& ofs, IndE_t& ind);
        };
        Ind_t Ind;
        IndS_t IndS;
        IndE_t IndE;
};

IndentClass::IndentClass () : IndentText("    "), _Indent(0), Ind(*this), IndS(*this), IndE(*this) {
    
}

IndentClass::~IndentClass () {
}

void IndentClass::SetIndentText (const char* Text) {
    IndentText = Text;
}

void IndentClass::Indent (int Amount) {
    _Indent += Amount;
}

void IndentClass::SetIndent(int Amount) {
    _Indent = Amount;
}

void IndentClass::ind (std::ostream& ofs) {
    for (int i = 0;i < _Indent;i++) {
        ofs << IndentText;
    }
}

std::ostream& operator<< (std::ostream& ofs, IndentClass::Ind_t& ind) {
    ind.state.ind(ofs);
    return ofs;
}

std::ostream& operator<< (std::ostream& ofs, IndentClass::IndS_t& inds) {
    inds.state.ind(ofs);
    inds.state.Indent(1);
    return ofs;
}

std::ostream& operator<< (std::ostream& ofs, IndentClass::IndE_t& inde) {
    inde.state.Indent(-1);
    inde.state.ind(ofs);
    return ofs;
}

int main () {
    IndentClass i;
    
    std::cout << i.IndS << "test" << std::endl;
    std::cout << i.Ind << "test" << std::endl;
    std::cout << i.IndE << "test" << std::endl;
    
    return 0;
}
