Это можно сделать с помощью пользовательского потокового манипулятора, который сохраняет желаемый уровень отступа в слове внутреннего расширяемого массива потока.Вы можете запросить такое слово, используя функцию ios_base::xalloc
.Эта функция даст вам индекс вашего слова.Вы можете получить к нему доступ, используя ios_base::iword
.Один из способов реализовать это было бы так:
struct indent {
indent(int level) : level(level) {}
private:
friend std::ostream& operator<<(std::ostream& stream, const indent& val);
int level;
};
std::ostream& operator<<(std::ostream& stream, const indent& val) {
for(int i = 0; i < val.level; i++) {
stream << " ";
}
return stream;
}
std::ostream& operator<<(std::ostream & oStream, const OwnClass& iOwnClass) {
oStream << indent(oStream.iword(index)) << "[SomeMember1: " <<
iOwnClass._ownMember1 << "]\n";
oStream << indent(oStream.iword(index)) << "[SomeMember2: " <<
iOwnClass._ownMember2 << "]\n";
}
. Вы должны выяснить, где хранить index
.Это эффективно позволяет вам добавлять пользовательское состояние в поток (обратите внимание, что это не будет потокобезопасным из коробки).Каждая функция, которая требует отступа, должна добавить запрошенный отступ в поток и вычесть его снова, когда это будет сделано.Вы можете убедиться, что это всегда происходит, используя защитный элемент для добавления / вычитания требуемого отступа (ИМХО, это более элегантно, чем использование манипулятора):
class indent_guard {
public:
indent_guard(int level, std::ostream& stream, int index)
: level(level),
stream(stream),
index(index)
{
stream.iword(index) += level;
}
~indent_guard() {
stream.iword(index) -= level;
}
private:
int level;
std::ostream& stream;
int index;
};
Вы можете использовать его следующим образом:
void some_func() {
indent_guard(2, std::cout, index);
// all output inside this function will be indented by 2 spaces
some_func(); // recursive call - output will be indented by 4 spaces
// here it will be 2 spaces again
}