1 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- 2 // vi: set et ts=4 sw=2 sts=2: 3 #ifndef PSURFACE_INDENT_HH 4 #define PSURFACE_INDENT_HH 5 6 #include <ostream> 7 #include <string> 8 9 namespace psurface { 10 /** @addtogroup Common 11 * 12 * @{ 13 */ 14 /** 15 * @file 16 * @brief Utility class for handling nested indentation in output. 17 * @author Jö Fahlke 18 */ 19 //! Utility class for handling nested indentation in output. 20 /** 21 * An indentation object hast a string basic_indent and an indentation 22 * level. When it is put into a std::ostream using << it will print its 23 * basic_indent as many times as its indentation level. By default the 24 * basic_indent will be two spaces and the indentation level will be 0. 25 * 26 * An Indent object may also have a reference to a parent Indent object. If 27 * it has, that object it put into the stream with the << operator before 28 * the indentation of this object is put into the stream. This effectively 29 * chains Indent objects together. 30 * 31 * You can use the ++ operator to raise and the -- operator to lower the 32 * indentation by one level. 33 * 34 * You can use the + operator with a numeric second argument morelevel to 35 * create a copy of the Indent object with the indentation level increased 36 * morelevel times. This is mainly useful to pass indent+1 to a function, 37 * where indent is an indentation object. 38 * 39 * You can use the + operator with a string second argument newindent to 40 * create a new Indent object with this object as parent, a basic_indent of 41 * newindent, and an indentation level of one. This is mainly useful to 42 * pass indent+"> " to a function, where "> " is a possibly different 43 * indentation string then the one used by indent indentation object. 44 * 45 * \note The idea is for functions receive indentation objects as call by 46 * value parameters. This way, the indentation object of the caller 47 * will not be modified by the function and the function can simply 48 * return at anytime without having to clean up. 49 */ 50 class Indent 51 { 52 const Indent* parent; 53 std::string basic_indent; 54 unsigned level; 55 56 public: 57 //! setup without parent 58 /** 59 * \note Initial indentation level is 0 by default for this constructor. 60 */ Indent(const std::string & basic_indent_=" ",unsigned level_=0)61 inline Indent(const std::string& basic_indent_ = " ", unsigned level_ = 0) 62 : parent(0), basic_indent(basic_indent_), level(level_) 63 { } 64 65 //! setup without parent and basic_indentation of two spaces Indent(unsigned level_)66 inline Indent(unsigned level_) 67 : parent(0), basic_indent(" "), level(level_) 68 { } 69 70 //! setup with parent 71 /** 72 * \note Initial indentation level is 1 by default for this constructor. 73 */ Indent(const Indent * parent_,const std::string & basic_indent_=" ",unsigned level_=1)74 inline Indent(const Indent* parent_, 75 const std::string& basic_indent_ = " ", unsigned level_ = 1) 76 : parent(parent_), basic_indent(basic_indent_), level(level_) 77 { } 78 79 //! setup with parent Indent(const Indent * parent_,unsigned level_)80 inline Indent(const Indent* parent_, unsigned level_) 81 : parent(parent_), basic_indent(" "), level(level_) 82 { } 83 84 //! create new indentation object with this one as parent operator +(const std::string & newindent) const85 inline Indent operator+(const std::string& newindent) const { 86 return Indent(this, newindent); 87 } 88 //! create a copy of this indetation object with raised level operator +(unsigned morelevel) const89 inline Indent operator+(unsigned morelevel) const { 90 return Indent(parent, basic_indent, level+morelevel); 91 } 92 //! raise indentation level operator ++()93 inline Indent& operator++() { ++level; return *this; } 94 //! lower indentation level operator --()95 inline Indent& operator--() { --level; return *this; } 96 97 //! write indentation to a stream 98 friend inline std::ostream& operator<<(std::ostream& s, 99 const Indent& indent); 100 }; 101 102 //! write indentation to a stream operator <<(std::ostream & s,const Indent & indent)103 inline std::ostream& operator<<(std::ostream& s, const Indent& indent) { 104 if(indent.parent) 105 s << *indent.parent; 106 for(unsigned i = 0; i < indent.level; ++i) 107 s << indent.basic_indent; 108 return s; 109 } 110 111 /** }@ group Common */ 112 113 } // namespace Dune 114 115 #endif // DUNE_COMMON_INDENT_HH 116