| /* | /* | ||||
| * Catch v2.4.1 | |||||
| * Generated: 2018-09-28 15:50:15.645795 | |||||
| * Catch v2.4.2 | |||||
| * Generated: 2018-10-26 21:12:29.223927 | |||||
| * ---------------------------------------------------------- | * ---------------------------------------------------------- | ||||
| * This file has been merged from multiple headers. Please don't edit it directly | * This file has been merged from multiple headers. Please don't edit it directly | ||||
| * Copyright (c) 2018 Two Blue Cubes Ltd. All rights reserved. | * Copyright (c) 2018 Two Blue Cubes Ltd. All rights reserved. | ||||
| #define CATCH_VERSION_MAJOR 2 | #define CATCH_VERSION_MAJOR 2 | ||||
| #define CATCH_VERSION_MINOR 4 | #define CATCH_VERSION_MINOR 4 | ||||
| #define CATCH_VERSION_PATCH 1 | |||||
| #define CATCH_VERSION_PATCH 2 | |||||
| #ifdef __clang__ | #ifdef __clang__ | ||||
| # pragma clang system_header | # pragma clang system_header | ||||
| #include <string> | #include <string> | ||||
| #include <cstdint> | #include <cstdint> | ||||
| // We need a dummy global operator<< so we can bring it into Catch namespace later | |||||
| struct Catch_global_namespace_dummy {}; | |||||
| std::ostream& operator<<(std::ostream&, Catch_global_namespace_dummy); | |||||
| namespace Catch { | namespace Catch { | ||||
| struct CaseSensitive { enum Choice { | struct CaseSensitive { enum Choice { | ||||
| std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ); | std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ); | ||||
| // Bring in operator<< from global namespace into Catch namespace | |||||
| // This is necessary because the overload of operator<< above makes | |||||
| // lookup stop at namespace Catch | |||||
| using ::operator<<; | |||||
| // Use this in variadic streaming macros to allow | // Use this in variadic streaming macros to allow | ||||
| // >> +StreamEndStop | // >> +StreamEndStop | ||||
| // as well as | // as well as | ||||
| #pragma warning(disable:4180) // We attempt to stream a function (address) by const&, which MSVC complains about but is harmless | #pragma warning(disable:4180) // We attempt to stream a function (address) by const&, which MSVC complains about but is harmless | ||||
| #endif | #endif | ||||
| // We need a dummy global operator<< so we can bring it into Catch namespace later | |||||
| struct Catch_global_namespace_dummy {}; | |||||
| std::ostream& operator<<(std::ostream&, Catch_global_namespace_dummy); | |||||
| namespace Catch { | namespace Catch { | ||||
| // Bring in operator<< from global namespace into Catch namespace | |||||
| using ::operator<<; | |||||
| namespace Detail { | namespace Detail { | ||||
| extern const std::string unprintableString; | extern const std::string unprintableString; | ||||
| struct LeakDetector { | struct LeakDetector { | ||||
| LeakDetector(); | LeakDetector(); | ||||
| ~LeakDetector(); | |||||
| }; | }; | ||||
| } | } | ||||
| // | // | ||||
| // See https://github.com/philsquared/Clara for more details | // See https://github.com/philsquared/Clara for more details | ||||
| // Clara v1.1.4 | |||||
| // Clara v1.1.5 | |||||
| #ifndef CATCH_CLARA_CONFIG_CONSOLE_WIDTH | #ifndef CATCH_CLARA_CONFIG_CONSOLE_WIDTH | ||||
| // | // | ||||
| // A single-header library for wrapping and laying out basic text, by Phil Nash | // A single-header library for wrapping and laying out basic text, by Phil Nash | ||||
| // | // | ||||
| // This work is licensed under the BSD 2-Clause license. | |||||
| // See the accompanying LICENSE file, or the one at https://opensource.org/licenses/BSD-2-Clause | |||||
| // Distributed under the Boost Software License, Version 1.0. (See accompanying | |||||
| // file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |||||
| // | // | ||||
| // This project is hosted at https://github.com/philsquared/textflowcpp | // This project is hosted at https://github.com/philsquared/textflowcpp | ||||
| #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH 80 | #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH 80 | ||||
| #endif | #endif | ||||
| namespace Catch { namespace clara { namespace TextFlow { | |||||
| inline auto isWhitespace( char c ) -> bool { | |||||
| static std::string chars = " \t\n\r"; | |||||
| return chars.find( c ) != std::string::npos; | |||||
| } | |||||
| inline auto isBreakableBefore( char c ) -> bool { | |||||
| static std::string chars = "[({<|"; | |||||
| return chars.find( c ) != std::string::npos; | |||||
| } | |||||
| inline auto isBreakableAfter( char c ) -> bool { | |||||
| static std::string chars = "])}>.,:;*+-=&/\\"; | |||||
| return chars.find( c ) != std::string::npos; | |||||
| } | |||||
| class Columns; | |||||
| class Column { | |||||
| std::vector<std::string> m_strings; | |||||
| size_t m_width = CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH; | |||||
| size_t m_indent = 0; | |||||
| size_t m_initialIndent = std::string::npos; | |||||
| public: | |||||
| class iterator { | |||||
| friend Column; | |||||
| Column const& m_column; | |||||
| size_t m_stringIndex = 0; | |||||
| size_t m_pos = 0; | |||||
| size_t m_len = 0; | |||||
| size_t m_end = 0; | |||||
| bool m_suffix = false; | |||||
| iterator( Column const& column, size_t stringIndex ) | |||||
| : m_column( column ), | |||||
| m_stringIndex( stringIndex ) | |||||
| {} | |||||
| auto line() const -> std::string const& { return m_column.m_strings[m_stringIndex]; } | |||||
| auto isBoundary( size_t at ) const -> bool { | |||||
| assert( at > 0 ); | |||||
| assert( at <= line().size() ); | |||||
| return at == line().size() || | |||||
| ( isWhitespace( line()[at] ) && !isWhitespace( line()[at-1] ) ) || | |||||
| isBreakableBefore( line()[at] ) || | |||||
| isBreakableAfter( line()[at-1] ); | |||||
| } | |||||
| void calcLength() { | |||||
| assert( m_stringIndex < m_column.m_strings.size() ); | |||||
| m_suffix = false; | |||||
| auto width = m_column.m_width-indent(); | |||||
| m_end = m_pos; | |||||
| while( m_end < line().size() && line()[m_end] != '\n' ) | |||||
| ++m_end; | |||||
| if( m_end < m_pos + width ) { | |||||
| m_len = m_end - m_pos; | |||||
| } | |||||
| else { | |||||
| size_t len = width; | |||||
| while (len > 0 && !isBoundary(m_pos + len)) | |||||
| --len; | |||||
| while (len > 0 && isWhitespace( line()[m_pos + len - 1] )) | |||||
| --len; | |||||
| if (len > 0) { | |||||
| m_len = len; | |||||
| } else { | |||||
| m_suffix = true; | |||||
| m_len = width - 1; | |||||
| } | |||||
| } | |||||
| } | |||||
| auto indent() const -> size_t { | |||||
| auto initial = m_pos == 0 && m_stringIndex == 0 ? m_column.m_initialIndent : std::string::npos; | |||||
| return initial == std::string::npos ? m_column.m_indent : initial; | |||||
| } | |||||
| auto addIndentAndSuffix(std::string const &plain) const -> std::string { | |||||
| return std::string( indent(), ' ' ) + (m_suffix ? plain + "-" : plain); | |||||
| } | |||||
| public: | |||||
| explicit iterator( Column const& column ) : m_column( column ) { | |||||
| assert( m_column.m_width > m_column.m_indent ); | |||||
| assert( m_column.m_initialIndent == std::string::npos || m_column.m_width > m_column.m_initialIndent ); | |||||
| calcLength(); | |||||
| if( m_len == 0 ) | |||||
| m_stringIndex++; // Empty string | |||||
| } | |||||
| auto operator *() const -> std::string { | |||||
| assert( m_stringIndex < m_column.m_strings.size() ); | |||||
| assert( m_pos <= m_end ); | |||||
| if( m_pos + m_column.m_width < m_end ) | |||||
| return addIndentAndSuffix(line().substr(m_pos, m_len)); | |||||
| else | |||||
| return addIndentAndSuffix(line().substr(m_pos, m_end - m_pos)); | |||||
| } | |||||
| auto operator ++() -> iterator& { | |||||
| m_pos += m_len; | |||||
| if( m_pos < line().size() && line()[m_pos] == '\n' ) | |||||
| m_pos += 1; | |||||
| else | |||||
| while( m_pos < line().size() && isWhitespace( line()[m_pos] ) ) | |||||
| ++m_pos; | |||||
| if( m_pos == line().size() ) { | |||||
| m_pos = 0; | |||||
| ++m_stringIndex; | |||||
| } | |||||
| if( m_stringIndex < m_column.m_strings.size() ) | |||||
| calcLength(); | |||||
| return *this; | |||||
| } | |||||
| auto operator ++(int) -> iterator { | |||||
| iterator prev( *this ); | |||||
| operator++(); | |||||
| return prev; | |||||
| } | |||||
| auto operator ==( iterator const& other ) const -> bool { | |||||
| return | |||||
| m_pos == other.m_pos && | |||||
| m_stringIndex == other.m_stringIndex && | |||||
| &m_column == &other.m_column; | |||||
| } | |||||
| auto operator !=( iterator const& other ) const -> bool { | |||||
| return !operator==( other ); | |||||
| } | |||||
| }; | |||||
| using const_iterator = iterator; | |||||
| explicit Column( std::string const& text ) { m_strings.push_back( text ); } | |||||
| auto width( size_t newWidth ) -> Column& { | |||||
| assert( newWidth > 0 ); | |||||
| m_width = newWidth; | |||||
| return *this; | |||||
| } | |||||
| auto indent( size_t newIndent ) -> Column& { | |||||
| m_indent = newIndent; | |||||
| return *this; | |||||
| } | |||||
| auto initialIndent( size_t newIndent ) -> Column& { | |||||
| m_initialIndent = newIndent; | |||||
| return *this; | |||||
| } | |||||
| auto width() const -> size_t { return m_width; } | |||||
| auto begin() const -> iterator { return iterator( *this ); } | |||||
| auto end() const -> iterator { return { *this, m_strings.size() }; } | |||||
| inline friend std::ostream& operator << ( std::ostream& os, Column const& col ) { | |||||
| bool first = true; | |||||
| for( auto line : col ) { | |||||
| if( first ) | |||||
| first = false; | |||||
| else | |||||
| os << "\n"; | |||||
| os << line; | |||||
| } | |||||
| return os; | |||||
| } | |||||
| auto operator + ( Column const& other ) -> Columns; | |||||
| auto toString() const -> std::string { | |||||
| std::ostringstream oss; | |||||
| oss << *this; | |||||
| return oss.str(); | |||||
| } | |||||
| }; | |||||
| class Spacer : public Column { | |||||
| public: | |||||
| explicit Spacer( size_t spaceWidth ) : Column( "" ) { | |||||
| width( spaceWidth ); | |||||
| } | |||||
| }; | |||||
| class Columns { | |||||
| std::vector<Column> m_columns; | |||||
| public: | |||||
| class iterator { | |||||
| friend Columns; | |||||
| struct EndTag {}; | |||||
| std::vector<Column> const& m_columns; | |||||
| std::vector<Column::iterator> m_iterators; | |||||
| size_t m_activeIterators; | |||||
| iterator( Columns const& columns, EndTag ) | |||||
| : m_columns( columns.m_columns ), | |||||
| m_activeIterators( 0 ) | |||||
| { | |||||
| m_iterators.reserve( m_columns.size() ); | |||||
| namespace Catch { | |||||
| namespace clara { | |||||
| namespace TextFlow { | |||||
| for( auto const& col : m_columns ) | |||||
| m_iterators.push_back( col.end() ); | |||||
| } | |||||
| inline auto isWhitespace(char c) -> bool { | |||||
| static std::string chars = " \t\n\r"; | |||||
| return chars.find(c) != std::string::npos; | |||||
| } | |||||
| inline auto isBreakableBefore(char c) -> bool { | |||||
| static std::string chars = "[({<|"; | |||||
| return chars.find(c) != std::string::npos; | |||||
| } | |||||
| inline auto isBreakableAfter(char c) -> bool { | |||||
| static std::string chars = "])}>.,:;*+-=&/\\"; | |||||
| return chars.find(c) != std::string::npos; | |||||
| } | |||||
| public: | |||||
| explicit iterator( Columns const& columns ) | |||||
| : m_columns( columns.m_columns ), | |||||
| m_activeIterators( m_columns.size() ) | |||||
| { | |||||
| m_iterators.reserve( m_columns.size() ); | |||||
| class Columns; | |||||
| for( auto const& col : m_columns ) | |||||
| m_iterators.push_back( col.begin() ); | |||||
| } | |||||
| class Column { | |||||
| std::vector<std::string> m_strings; | |||||
| size_t m_width = CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH; | |||||
| size_t m_indent = 0; | |||||
| size_t m_initialIndent = std::string::npos; | |||||
| auto operator ==( iterator const& other ) const -> bool { | |||||
| return m_iterators == other.m_iterators; | |||||
| } | |||||
| auto operator !=( iterator const& other ) const -> bool { | |||||
| return m_iterators != other.m_iterators; | |||||
| } | |||||
| auto operator *() const -> std::string { | |||||
| std::string row, padding; | |||||
| public: | |||||
| class iterator { | |||||
| friend Column; | |||||
| Column const& m_column; | |||||
| size_t m_stringIndex = 0; | |||||
| size_t m_pos = 0; | |||||
| size_t m_len = 0; | |||||
| size_t m_end = 0; | |||||
| bool m_suffix = false; | |||||
| iterator(Column const& column, size_t stringIndex) | |||||
| : m_column(column), | |||||
| m_stringIndex(stringIndex) {} | |||||
| auto line() const -> std::string const& { return m_column.m_strings[m_stringIndex]; } | |||||
| auto isBoundary(size_t at) const -> bool { | |||||
| assert(at > 0); | |||||
| assert(at <= line().size()); | |||||
| return at == line().size() || | |||||
| (isWhitespace(line()[at]) && !isWhitespace(line()[at - 1])) || | |||||
| isBreakableBefore(line()[at]) || | |||||
| isBreakableAfter(line()[at - 1]); | |||||
| } | |||||
| void calcLength() { | |||||
| assert(m_stringIndex < m_column.m_strings.size()); | |||||
| m_suffix = false; | |||||
| auto width = m_column.m_width - indent(); | |||||
| m_end = m_pos; | |||||
| while (m_end < line().size() && line()[m_end] != '\n') | |||||
| ++m_end; | |||||
| if (m_end < m_pos + width) { | |||||
| m_len = m_end - m_pos; | |||||
| } else { | |||||
| size_t len = width; | |||||
| while (len > 0 && !isBoundary(m_pos + len)) | |||||
| --len; | |||||
| while (len > 0 && isWhitespace(line()[m_pos + len - 1])) | |||||
| --len; | |||||
| if (len > 0) { | |||||
| m_len = len; | |||||
| } else { | |||||
| m_suffix = true; | |||||
| m_len = width - 1; | |||||
| } | |||||
| } | |||||
| } | |||||
| auto indent() const -> size_t { | |||||
| auto initial = m_pos == 0 && m_stringIndex == 0 ? m_column.m_initialIndent : std::string::npos; | |||||
| return initial == std::string::npos ? m_column.m_indent : initial; | |||||
| } | |||||
| auto addIndentAndSuffix(std::string const &plain) const -> std::string { | |||||
| return std::string(indent(), ' ') + (m_suffix ? plain + "-" : plain); | |||||
| } | |||||
| public: | |||||
| using difference_type = std::ptrdiff_t; | |||||
| using value_type = std::string; | |||||
| using pointer = value_type * ; | |||||
| using reference = value_type & ; | |||||
| using iterator_category = std::forward_iterator_tag; | |||||
| explicit iterator(Column const& column) : m_column(column) { | |||||
| assert(m_column.m_width > m_column.m_indent); | |||||
| assert(m_column.m_initialIndent == std::string::npos || m_column.m_width > m_column.m_initialIndent); | |||||
| calcLength(); | |||||
| if (m_len == 0) | |||||
| m_stringIndex++; // Empty string | |||||
| } | |||||
| auto operator *() const -> std::string { | |||||
| assert(m_stringIndex < m_column.m_strings.size()); | |||||
| assert(m_pos <= m_end); | |||||
| return addIndentAndSuffix(line().substr(m_pos, m_len)); | |||||
| } | |||||
| auto operator ++() -> iterator& { | |||||
| m_pos += m_len; | |||||
| if (m_pos < line().size() && line()[m_pos] == '\n') | |||||
| m_pos += 1; | |||||
| else | |||||
| while (m_pos < line().size() && isWhitespace(line()[m_pos])) | |||||
| ++m_pos; | |||||
| if (m_pos == line().size()) { | |||||
| m_pos = 0; | |||||
| ++m_stringIndex; | |||||
| } | |||||
| if (m_stringIndex < m_column.m_strings.size()) | |||||
| calcLength(); | |||||
| return *this; | |||||
| } | |||||
| auto operator ++(int) -> iterator { | |||||
| iterator prev(*this); | |||||
| operator++(); | |||||
| return prev; | |||||
| } | |||||
| auto operator ==(iterator const& other) const -> bool { | |||||
| return | |||||
| m_pos == other.m_pos && | |||||
| m_stringIndex == other.m_stringIndex && | |||||
| &m_column == &other.m_column; | |||||
| } | |||||
| auto operator !=(iterator const& other) const -> bool { | |||||
| return !operator==(other); | |||||
| } | |||||
| }; | |||||
| using const_iterator = iterator; | |||||
| explicit Column(std::string const& text) { m_strings.push_back(text); } | |||||
| auto width(size_t newWidth) -> Column& { | |||||
| assert(newWidth > 0); | |||||
| m_width = newWidth; | |||||
| return *this; | |||||
| } | |||||
| auto indent(size_t newIndent) -> Column& { | |||||
| m_indent = newIndent; | |||||
| return *this; | |||||
| } | |||||
| auto initialIndent(size_t newIndent) -> Column& { | |||||
| m_initialIndent = newIndent; | |||||
| return *this; | |||||
| } | |||||
| auto width() const -> size_t { return m_width; } | |||||
| auto begin() const -> iterator { return iterator(*this); } | |||||
| auto end() const -> iterator { return { *this, m_strings.size() }; } | |||||
| inline friend std::ostream& operator << (std::ostream& os, Column const& col) { | |||||
| bool first = true; | |||||
| for (auto line : col) { | |||||
| if (first) | |||||
| first = false; | |||||
| else | |||||
| os << "\n"; | |||||
| os << line; | |||||
| } | |||||
| return os; | |||||
| } | |||||
| auto operator + (Column const& other)->Columns; | |||||
| auto toString() const -> std::string { | |||||
| std::ostringstream oss; | |||||
| oss << *this; | |||||
| return oss.str(); | |||||
| } | |||||
| }; | |||||
| for( size_t i = 0; i < m_columns.size(); ++i ) { | |||||
| auto width = m_columns[i].width(); | |||||
| if( m_iterators[i] != m_columns[i].end() ) { | |||||
| std::string col = *m_iterators[i]; | |||||
| row += padding + col; | |||||
| if( col.size() < width ) | |||||
| padding = std::string( width - col.size(), ' ' ); | |||||
| else | |||||
| padding = ""; | |||||
| } | |||||
| else { | |||||
| padding += std::string( width, ' ' ); | |||||
| } | |||||
| } | |||||
| return row; | |||||
| } | |||||
| auto operator ++() -> iterator& { | |||||
| for( size_t i = 0; i < m_columns.size(); ++i ) { | |||||
| if (m_iterators[i] != m_columns[i].end()) | |||||
| ++m_iterators[i]; | |||||
| } | |||||
| return *this; | |||||
| } | |||||
| auto operator ++(int) -> iterator { | |||||
| iterator prev( *this ); | |||||
| operator++(); | |||||
| return prev; | |||||
| } | |||||
| }; | |||||
| using const_iterator = iterator; | |||||
| class Spacer : public Column { | |||||
| auto begin() const -> iterator { return iterator( *this ); } | |||||
| auto end() const -> iterator { return { *this, iterator::EndTag() }; } | |||||
| public: | |||||
| explicit Spacer(size_t spaceWidth) : Column("") { | |||||
| width(spaceWidth); | |||||
| } | |||||
| }; | |||||
| auto operator += ( Column const& col ) -> Columns& { | |||||
| m_columns.push_back( col ); | |||||
| return *this; | |||||
| } | |||||
| auto operator + ( Column const& col ) -> Columns { | |||||
| Columns combined = *this; | |||||
| combined += col; | |||||
| return combined; | |||||
| } | |||||
| class Columns { | |||||
| std::vector<Column> m_columns; | |||||
| inline friend std::ostream& operator << ( std::ostream& os, Columns const& cols ) { | |||||
| public: | |||||
| bool first = true; | |||||
| for( auto line : cols ) { | |||||
| if( first ) | |||||
| first = false; | |||||
| else | |||||
| os << "\n"; | |||||
| os << line; | |||||
| } | |||||
| return os; | |||||
| } | |||||
| class iterator { | |||||
| friend Columns; | |||||
| struct EndTag {}; | |||||
| std::vector<Column> const& m_columns; | |||||
| std::vector<Column::iterator> m_iterators; | |||||
| size_t m_activeIterators; | |||||
| iterator(Columns const& columns, EndTag) | |||||
| : m_columns(columns.m_columns), | |||||
| m_activeIterators(0) { | |||||
| m_iterators.reserve(m_columns.size()); | |||||
| for (auto const& col : m_columns) | |||||
| m_iterators.push_back(col.end()); | |||||
| } | |||||
| public: | |||||
| using difference_type = std::ptrdiff_t; | |||||
| using value_type = std::string; | |||||
| using pointer = value_type * ; | |||||
| using reference = value_type & ; | |||||
| using iterator_category = std::forward_iterator_tag; | |||||
| explicit iterator(Columns const& columns) | |||||
| : m_columns(columns.m_columns), | |||||
| m_activeIterators(m_columns.size()) { | |||||
| m_iterators.reserve(m_columns.size()); | |||||
| for (auto const& col : m_columns) | |||||
| m_iterators.push_back(col.begin()); | |||||
| } | |||||
| auto operator ==(iterator const& other) const -> bool { | |||||
| return m_iterators == other.m_iterators; | |||||
| } | |||||
| auto operator !=(iterator const& other) const -> bool { | |||||
| return m_iterators != other.m_iterators; | |||||
| } | |||||
| auto operator *() const -> std::string { | |||||
| std::string row, padding; | |||||
| for (size_t i = 0; i < m_columns.size(); ++i) { | |||||
| auto width = m_columns[i].width(); | |||||
| if (m_iterators[i] != m_columns[i].end()) { | |||||
| std::string col = *m_iterators[i]; | |||||
| row += padding + col; | |||||
| if (col.size() < width) | |||||
| padding = std::string(width - col.size(), ' '); | |||||
| else | |||||
| padding = ""; | |||||
| } else { | |||||
| padding += std::string(width, ' '); | |||||
| } | |||||
| } | |||||
| return row; | |||||
| } | |||||
| auto operator ++() -> iterator& { | |||||
| for (size_t i = 0; i < m_columns.size(); ++i) { | |||||
| if (m_iterators[i] != m_columns[i].end()) | |||||
| ++m_iterators[i]; | |||||
| } | |||||
| return *this; | |||||
| } | |||||
| auto operator ++(int) -> iterator { | |||||
| iterator prev(*this); | |||||
| operator++(); | |||||
| return prev; | |||||
| } | |||||
| }; | |||||
| using const_iterator = iterator; | |||||
| auto begin() const -> iterator { return iterator(*this); } | |||||
| auto end() const -> iterator { return { *this, iterator::EndTag() }; } | |||||
| auto operator += (Column const& col) -> Columns& { | |||||
| m_columns.push_back(col); | |||||
| return *this; | |||||
| } | |||||
| auto operator + (Column const& col) -> Columns { | |||||
| Columns combined = *this; | |||||
| combined += col; | |||||
| return combined; | |||||
| } | |||||
| inline friend std::ostream& operator << (std::ostream& os, Columns const& cols) { | |||||
| bool first = true; | |||||
| for (auto line : cols) { | |||||
| if (first) | |||||
| first = false; | |||||
| else | |||||
| os << "\n"; | |||||
| os << line; | |||||
| } | |||||
| return os; | |||||
| } | |||||
| auto toString() const -> std::string { | |||||
| std::ostringstream oss; | |||||
| oss << *this; | |||||
| return oss.str(); | |||||
| } | |||||
| }; | |||||
| auto toString() const -> std::string { | |||||
| std::ostringstream oss; | |||||
| oss << *this; | |||||
| return oss.str(); | |||||
| } | |||||
| }; | |||||
| inline auto Column::operator + (Column const& other) -> Columns { | |||||
| Columns cols; | |||||
| cols += *this; | |||||
| cols += other; | |||||
| return cols; | |||||
| } | |||||
| } | |||||
| inline auto Column::operator + ( Column const& other ) -> Columns { | |||||
| Columns cols; | |||||
| cols += *this; | |||||
| cols += other; | |||||
| return cols; | |||||
| } | |||||
| }}} // namespace Catch::clara::TextFlow | |||||
| } | |||||
| } | |||||
| // ----------- end of #include from clara_textflow.hpp ----------- | // ----------- end of #include from clara_textflow.hpp ----------- | ||||
| // ........... back in clara.hpp | // ........... back in clara.hpp | ||||
| #include <string> | |||||
| #include <memory> | #include <memory> | ||||
| #include <set> | #include <set> | ||||
| #include <algorithm> | #include <algorithm> | ||||
| return ParserResult::runtimeError( "Unrecognised verbosity, '" + verbosity + "'" ); | return ParserResult::runtimeError( "Unrecognised verbosity, '" + verbosity + "'" ); | ||||
| return ParserResult::ok( ParseResultType::Matched ); | return ParserResult::ok( ParseResultType::Matched ); | ||||
| }; | }; | ||||
| auto const setReporter = [&]( std::string const& reporter ) { | |||||
| IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories(); | |||||
| auto lcReporter = toLower( reporter ); | |||||
| auto result = factories.find( lcReporter ); | |||||
| if( factories.end() != result ) | |||||
| config.reporterName = lcReporter; | |||||
| else | |||||
| return ParserResult::runtimeError( "Unrecognized reporter, '" + reporter + "'. Check available with --list-reporters" ); | |||||
| return ParserResult::ok( ParseResultType::Matched ); | |||||
| }; | |||||
| auto cli | auto cli | ||||
| = ExeName( config.processName ) | = ExeName( config.processName ) | ||||
| | Opt( config.outputFilename, "filename" ) | | Opt( config.outputFilename, "filename" ) | ||||
| ["-o"]["--out"] | ["-o"]["--out"] | ||||
| ( "output filename" ) | ( "output filename" ) | ||||
| | Opt( config.reporterName, "name" ) | |||||
| | Opt( setReporter, "name" ) | |||||
| ["-r"]["--reporter"] | ["-r"]["--reporter"] | ||||
| ( "reporter to use (defaults to console)" ) | ( "reporter to use (defaults to console)" ) | ||||
| | Opt( config.name, "name" ) | | Opt( config.name, "name" ) | ||||
| Catch::LeakDetector::LeakDetector() {} | Catch::LeakDetector::LeakDetector() {} | ||||
| #endif | #endif | ||||
| Catch::LeakDetector::~LeakDetector() { | |||||
| Catch::cleanUp(); | |||||
| } | |||||
| // end catch_leak_detector.cpp | // end catch_leak_detector.cpp | ||||
| // start catch_list.cpp | // start catch_list.cpp | ||||
| std::size_t listTags( Config const& config ); | std::size_t listTags( Config const& config ); | ||||
| std::size_t listReporters( Config const& /*config*/ ); | |||||
| std::size_t listReporters(); | |||||
| Option<std::size_t> list( Config const& config ); | Option<std::size_t> list( Config const& config ); | ||||
| return tagCounts.size(); | return tagCounts.size(); | ||||
| } | } | ||||
| std::size_t listReporters( Config const& /*config*/ ) { | |||||
| std::size_t listReporters() { | |||||
| Catch::cout() << "Available reporters:\n"; | Catch::cout() << "Available reporters:\n"; | ||||
| IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories(); | IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories(); | ||||
| std::size_t maxNameLen = 0; | std::size_t maxNameLen = 0; | ||||
| if( config.listTags() ) | if( config.listTags() ) | ||||
| listedCount = listedCount.valueOr(0) + listTags( config ); | listedCount = listedCount.valueOr(0) + listTags( config ); | ||||
| if( config.listReporters() ) | if( config.listReporters() ) | ||||
| listedCount = listedCount.valueOr(0) + listReporters( config ); | |||||
| listedCount = listedCount.valueOr(0) + listReporters(); | |||||
| return listedCount; | return listedCount; | ||||
| } | } | ||||
| void libIdentify(); | void libIdentify(); | ||||
| int applyCommandLine( int argc, char const * const * argv ); | int applyCommandLine( int argc, char const * const * argv ); | ||||
| #if defined(CATCH_CONFIG_WCHAR) && defined(WIN32) && defined(UNICODE) | |||||
| int applyCommandLine( int argc, wchar_t const * const * argv ); | |||||
| #endif | |||||
| void useConfigData( ConfigData const& configData ); | void useConfigData( ConfigData const& configData ); | ||||
| int run( int argc, char* argv[] ); | |||||
| #if defined(CATCH_CONFIG_WCHAR) && defined(WIN32) && defined(UNICODE) | |||||
| int run( int argc, wchar_t* const argv[] ); | |||||
| #endif | |||||
| template<typename CharT> | |||||
| int run(int argc, CharT const * const argv[]) { | |||||
| if (m_startupExceptions) | |||||
| return 1; | |||||
| int returnCode = applyCommandLine(argc, argv); | |||||
| if (returnCode == 0) | |||||
| returnCode = run(); | |||||
| return returnCode; | |||||
| } | |||||
| int run(); | int run(); | ||||
| clara::Parser const& cli() const; | clara::Parser const& cli() const; | ||||
| return 0; | return 0; | ||||
| } | } | ||||
| void Session::useConfigData( ConfigData const& configData ) { | |||||
| m_configData = configData; | |||||
| m_config.reset(); | |||||
| } | |||||
| int Session::run( int argc, char* argv[] ) { | |||||
| if( m_startupExceptions ) | |||||
| return 1; | |||||
| int returnCode = applyCommandLine( argc, argv ); | |||||
| if( returnCode == 0 ) | |||||
| returnCode = run(); | |||||
| return returnCode; | |||||
| } | |||||
| #if defined(CATCH_CONFIG_WCHAR) && defined(WIN32) && defined(UNICODE) | #if defined(CATCH_CONFIG_WCHAR) && defined(WIN32) && defined(UNICODE) | ||||
| int Session::run( int argc, wchar_t* const argv[] ) { | |||||
| int Session::applyCommandLine( int argc, wchar_t const * const * argv ) { | |||||
| char **utf8Argv = new char *[ argc ]; | char **utf8Argv = new char *[ argc ]; | ||||
| WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, utf8Argv[i], bufSize, NULL, NULL ); | WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, utf8Argv[i], bufSize, NULL, NULL ); | ||||
| } | } | ||||
| int returnCode = run( argc, utf8Argv ); | |||||
| int returnCode = applyCommandLine( argc, utf8Argv ); | |||||
| for ( int i = 0; i < argc; ++i ) | for ( int i = 0; i < argc; ++i ) | ||||
| delete [] utf8Argv[ i ]; | delete [] utf8Argv[ i ]; | ||||
| return returnCode; | return returnCode; | ||||
| } | } | ||||
| #endif | #endif | ||||
| void Session::useConfigData( ConfigData const& configData ) { | |||||
| m_configData = configData; | |||||
| m_config.reset(); | |||||
| } | |||||
| int Session::run() { | int Session::run() { | ||||
| if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeStart ) != 0 ) { | if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeStart ) != 0 ) { | ||||
| Catch::cout() << "...waiting for enter/ return before starting" << std::endl; | Catch::cout() << "...waiting for enter/ return before starting" << std::endl; | ||||
| return b ? "true" : "false"; | return b ? "true" : "false"; | ||||
| } | } | ||||
| std::string StringMaker<char>::convert(char value) { | |||||
| std::string StringMaker<signed char>::convert(signed char value) { | |||||
| if (value == '\r') { | if (value == '\r') { | ||||
| return "'\\r'"; | return "'\\r'"; | ||||
| } else if (value == '\f') { | } else if (value == '\f') { | ||||
| return chstr; | return chstr; | ||||
| } | } | ||||
| } | } | ||||
| std::string StringMaker<signed char>::convert(signed char c) { | |||||
| return ::Catch::Detail::stringify(static_cast<char>(c)); | |||||
| std::string StringMaker<char>::convert(char c) { | |||||
| return ::Catch::Detail::stringify(static_cast<signed char>(c)); | |||||
| } | } | ||||
| std::string StringMaker<unsigned char>::convert(unsigned char c) { | std::string StringMaker<unsigned char>::convert(unsigned char c) { | ||||
| return ::Catch::Detail::stringify(static_cast<char>(c)); | return ::Catch::Detail::stringify(static_cast<char>(c)); | ||||
| } | } | ||||
| Version const& libraryVersion() { | Version const& libraryVersion() { | ||||
| static Version version( 2, 4, 1, "", 0 ); | |||||
| static Version version( 2, 4, 2, "", 0 ); | |||||
| return version; | return version; | ||||
| } | } | ||||
| m_xml.startElement( "Catch" ); | m_xml.startElement( "Catch" ); | ||||
| if( !m_config->name().empty() ) | if( !m_config->name().empty() ) | ||||
| m_xml.writeAttribute( "name", m_config->name() ); | m_xml.writeAttribute( "name", m_config->name() ); | ||||
| if( m_config->rngSeed() != 0 ) | |||||
| m_xml.scopedElement( "Randomness" ) | |||||
| .writeAttribute( "seed", m_config->rngSeed() ); | |||||
| } | } | ||||
| void XmlReporter::testGroupStarting( GroupInfo const& groupInfo ) { | void XmlReporter::testGroupStarting( GroupInfo const& groupInfo ) { | ||||
| #define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE() | #define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE() | ||||
| #if !defined(CATCH_CONFIG_RUNTIME_STATIC_REQUIRE) | |||||
| #define CATCH_STATIC_REQUIRE( ... ) static_assert( __VA_ARGS__ , #__VA_ARGS__ ); CATCH_SUCCEED( #__VA_ARGS__ ) | |||||
| #define CATCH_STATIC_REQUIRE_FALSE( ... ) static_assert( !(__VA_ARGS__), "!(" #__VA_ARGS__ ")" ); CATCH_SUCCEED( #__VA_ARGS__ ) | |||||
| #else | |||||
| #define CATCH_STATIC_REQUIRE( ... ) CATCH_REQUIRE( __VA_ARGS__ ) | |||||
| #define CATCH_STATIC_REQUIRE_FALSE( ... ) CATCH_REQUIRE_FALSE( __VA_ARGS__ ) | |||||
| #endif | |||||
| // "BDD-style" convenience wrappers | // "BDD-style" convenience wrappers | ||||
| #define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ ) | #define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ ) | ||||
| #define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ ) | #define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ ) | ||||
| #define SUCCEED( ... ) INTERNAL_CATCH_MSG( "SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) | #define SUCCEED( ... ) INTERNAL_CATCH_MSG( "SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) | ||||
| #define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE() | #define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE() | ||||
| #if !defined(CATCH_CONFIG_RUNTIME_STATIC_REQUIRE) | |||||
| #define STATIC_REQUIRE( ... ) static_assert( __VA_ARGS__, #__VA_ARGS__ ); SUCCEED( #__VA_ARGS__ ) | |||||
| #define STATIC_REQUIRE_FALSE( ... ) static_assert( !(__VA_ARGS__), "!(" #__VA_ARGS__ ")" ); SUCCEED( "!(" #__VA_ARGS__ ")" ) | |||||
| #else | |||||
| #define STATIC_REQUIRE( ... ) REQUIRE( __VA_ARGS__ ) | |||||
| #define STATIC_REQUIRE_FALSE( ... ) REQUIRE_FALSE( __VA_ARGS__ ) | |||||
| #endif | |||||
| #endif | #endif | ||||
| #define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) | #define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) | ||||
| #define CATCH_THEN( desc ) | #define CATCH_THEN( desc ) | ||||
| #define CATCH_AND_THEN( desc ) | #define CATCH_AND_THEN( desc ) | ||||
| #define CATCH_STATIC_REQUIRE( ... ) (void)(0) | |||||
| #define CATCH_STATIC_REQUIRE_FALSE( ... ) (void)(0) | |||||
| // If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required | // If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required | ||||
| #else | #else | ||||
| #define SUCCEED( ... ) (void)(0) | #define SUCCEED( ... ) (void)(0) | ||||
| #define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )) | #define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )) | ||||
| #define STATIC_REQUIRE( ... ) (void)(0) | |||||
| #define STATIC_REQUIRE_FALSE( ... ) (void)(0) | |||||
| #endif | #endif | ||||
| #define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature ) | #define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature ) |