File indexing completed on 2025-01-30 10:02:51
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef CATCH_TEXTFLOW_HPP_INCLUDED
0009 #define CATCH_TEXTFLOW_HPP_INCLUDED
0010
0011 #include <cassert>
0012 #include <catch2/internal/catch_console_width.hpp>
0013 #include <string>
0014 #include <vector>
0015
0016 namespace Catch {
0017 namespace TextFlow {
0018
0019 class Columns;
0020
0021
0022
0023
0024
0025
0026
0027
0028 class Column {
0029
0030 std::string m_string;
0031
0032 size_t m_width = CATCH_CONFIG_CONSOLE_WIDTH - 1;
0033
0034 size_t m_indent = 0;
0035
0036 size_t m_initialIndent = std::string::npos;
0037
0038 public:
0039
0040
0041
0042 class const_iterator {
0043 friend Column;
0044 struct EndTag {};
0045
0046 Column const& m_column;
0047
0048 size_t m_lineStart = 0;
0049
0050 size_t m_lineLength = 0;
0051
0052 size_t m_parsedTo = 0;
0053
0054 bool m_addHyphen = false;
0055
0056 const_iterator( Column const& column, EndTag ):
0057 m_column( column ), m_lineStart( m_column.m_string.size() ) {}
0058
0059
0060 void calcLength();
0061
0062
0063 size_t indentSize() const;
0064
0065
0066
0067 std::string addIndentAndSuffix( size_t position,
0068 size_t length ) const;
0069
0070 public:
0071 using difference_type = std::ptrdiff_t;
0072 using value_type = std::string;
0073 using pointer = value_type*;
0074 using reference = value_type&;
0075 using iterator_category = std::forward_iterator_tag;
0076
0077 explicit const_iterator( Column const& column );
0078
0079 std::string operator*() const;
0080
0081 const_iterator& operator++();
0082 const_iterator operator++( int );
0083
0084 bool operator==( const_iterator const& other ) const {
0085 return m_lineStart == other.m_lineStart && &m_column == &other.m_column;
0086 }
0087 bool operator!=( const_iterator const& other ) const {
0088 return !operator==( other );
0089 }
0090 };
0091 using iterator = const_iterator;
0092
0093 explicit Column( std::string const& text ): m_string( text ) {}
0094
0095 Column& width( size_t newWidth ) {
0096 assert( newWidth > 0 );
0097 m_width = newWidth;
0098 return *this;
0099 }
0100 Column& indent( size_t newIndent ) {
0101 m_indent = newIndent;
0102 return *this;
0103 }
0104 Column& initialIndent( size_t newIndent ) {
0105 m_initialIndent = newIndent;
0106 return *this;
0107 }
0108
0109 size_t width() const { return m_width; }
0110 const_iterator begin() const { return const_iterator( *this ); }
0111 const_iterator end() const { return { *this, const_iterator::EndTag{} }; }
0112
0113 friend std::ostream& operator<<( std::ostream& os,
0114 Column const& col );
0115
0116 Columns operator+( Column const& other );
0117 };
0118
0119
0120 Column Spacer( size_t spaceWidth );
0121
0122 class Columns {
0123 std::vector<Column> m_columns;
0124
0125 public:
0126 class iterator {
0127 friend Columns;
0128 struct EndTag {};
0129
0130 std::vector<Column> const& m_columns;
0131 std::vector<Column::const_iterator> m_iterators;
0132 size_t m_activeIterators;
0133
0134 iterator( Columns const& columns, EndTag );
0135
0136 public:
0137 using difference_type = std::ptrdiff_t;
0138 using value_type = std::string;
0139 using pointer = value_type*;
0140 using reference = value_type&;
0141 using iterator_category = std::forward_iterator_tag;
0142
0143 explicit iterator( Columns const& columns );
0144
0145 auto operator==( iterator const& other ) const -> bool {
0146 return m_iterators == other.m_iterators;
0147 }
0148 auto operator!=( iterator const& other ) const -> bool {
0149 return m_iterators != other.m_iterators;
0150 }
0151 std::string operator*() const;
0152 iterator& operator++();
0153 iterator operator++( int );
0154 };
0155 using const_iterator = iterator;
0156
0157 iterator begin() const { return iterator( *this ); }
0158 iterator end() const { return { *this, iterator::EndTag() }; }
0159
0160 Columns& operator+=( Column const& col );
0161 Columns operator+( Column const& col );
0162
0163 friend std::ostream& operator<<( std::ostream& os,
0164 Columns const& cols );
0165 };
0166
0167 }
0168 }
0169 #endif