Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 10:02:51

0001 
0002 //              Copyright Catch2 Authors
0003 // Distributed under the Boost Software License, Version 1.0.
0004 //   (See accompanying file LICENSE.txt or copy at
0005 //        https://www.boost.org/LICENSE_1_0.txt)
0006 
0007 // SPDX-License-Identifier: BSL-1.0
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          * Represents a column of text with specific width and indentation
0023          *
0024          * When written out to a stream, it will perform linebreaking
0025          * of the provided text so that the written lines fit within
0026          * target width.
0027          */
0028         class Column {
0029             // String to be written out
0030             std::string m_string;
0031             // Width of the column for linebreaking
0032             size_t m_width = CATCH_CONFIG_CONSOLE_WIDTH - 1;
0033             // Indentation of other lines (including first if initial indent is unset)
0034             size_t m_indent = 0;
0035             // Indentation of the first line
0036             size_t m_initialIndent = std::string::npos;
0037 
0038         public:
0039             /**
0040              * Iterates "lines" in `Column` and return sthem
0041              */
0042             class const_iterator {
0043                 friend Column;
0044                 struct EndTag {};
0045 
0046                 Column const& m_column;
0047                 // Where does the current line start?
0048                 size_t m_lineStart = 0;
0049                 // How long should the current line be?
0050                 size_t m_lineLength = 0;
0051                 // How far have we checked the string to iterate?
0052                 size_t m_parsedTo = 0;
0053                 // Should a '-' be appended to the line?
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                 // Calculates the length of the current line
0060                 void calcLength();
0061 
0062                 // Returns current indentation width
0063                 size_t indentSize() const;
0064 
0065                 // Creates an indented and (optionally) suffixed string from
0066                 // current iterator position, indentation and length.
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         //! Creates a column that serves as an empty space of specific width
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     } // namespace TextFlow
0168 } // namespace Catch
0169 #endif // CATCH_TEXTFLOW_HPP_INCLUDED