|
|
@@ -1,6 +1,6 @@ |
|
|
|
/* |
|
|
|
* 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 |
|
|
|
* Copyright (c) 2018 Two Blue Cubes Ltd. All rights reserved. |
|
|
@@ -15,7 +15,7 @@ |
|
|
|
|
|
|
|
#define CATCH_VERSION_MAJOR 2 |
|
|
|
#define CATCH_VERSION_MINOR 4 |
|
|
|
#define CATCH_VERSION_PATCH 1 |
|
|
|
#define CATCH_VERSION_PATCH 2 |
|
|
|
|
|
|
|
#ifdef __clang__ |
|
|
|
# pragma clang system_header |
|
|
@@ -356,6 +356,10 @@ namespace Catch { |
|
|
|
#include <string> |
|
|
|
#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 { |
|
|
|
|
|
|
|
struct CaseSensitive { enum Choice { |
|
|
@@ -397,6 +401,11 @@ namespace Catch { |
|
|
|
|
|
|
|
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 |
|
|
|
// >> +StreamEndStop |
|
|
|
// as well as |
|
|
@@ -850,14 +859,7 @@ inline id performOptionalSelector( id obj, SEL sel ) { |
|
|
|
#pragma warning(disable:4180) // We attempt to stream a function (address) by const&, which MSVC complains about but is harmless |
|
|
|
#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 { |
|
|
|
// Bring in operator<< from global namespace into Catch namespace |
|
|
|
using ::operator<<; |
|
|
|
|
|
|
|
namespace Detail { |
|
|
|
|
|
|
|
extern const std::string unprintableString; |
|
|
@@ -5121,6 +5123,7 @@ namespace Catch { |
|
|
|
|
|
|
|
struct LeakDetector { |
|
|
|
LeakDetector(); |
|
|
|
~LeakDetector(); |
|
|
|
}; |
|
|
|
|
|
|
|
} |
|
|
@@ -5772,7 +5775,7 @@ namespace Catch { |
|
|
|
// |
|
|
|
// See https://github.com/philsquared/Clara for more details |
|
|
|
|
|
|
|
// Clara v1.1.4 |
|
|
|
// Clara v1.1.5 |
|
|
|
|
|
|
|
|
|
|
|
#ifndef CATCH_CLARA_CONFIG_CONSOLE_WIDTH |
|
|
@@ -5798,8 +5801,8 @@ namespace Catch { |
|
|
|
// |
|
|
|
// 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 |
|
|
|
|
|
|
@@ -5813,314 +5816,324 @@ namespace Catch { |
|
|
|
#define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH 80 |
|
|
|
#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 ----------- |
|
|
|
// ........... back in clara.hpp |
|
|
|
|
|
|
|
#include <string> |
|
|
|
#include <memory> |
|
|
|
#include <set> |
|
|
|
#include <algorithm> |
|
|
@@ -7119,6 +7132,18 @@ namespace Catch { |
|
|
|
return ParserResult::runtimeError( "Unrecognised verbosity, '" + verbosity + "'" ); |
|
|
|
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 |
|
|
|
= ExeName( config.processName ) |
|
|
@@ -7144,7 +7169,7 @@ namespace Catch { |
|
|
|
| Opt( config.outputFilename, "filename" ) |
|
|
|
["-o"]["--out"] |
|
|
|
( "output filename" ) |
|
|
|
| Opt( config.reporterName, "name" ) |
|
|
|
| Opt( setReporter, "name" ) |
|
|
|
["-r"]["--reporter"] |
|
|
|
( "reporter to use (defaults to console)" ) |
|
|
|
| Opt( config.name, "name" ) |
|
|
@@ -8292,6 +8317,10 @@ namespace Catch { |
|
|
|
Catch::LeakDetector::LeakDetector() {} |
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
Catch::LeakDetector::~LeakDetector() { |
|
|
|
Catch::cleanUp(); |
|
|
|
} |
|
|
|
// end catch_leak_detector.cpp |
|
|
|
// start catch_list.cpp |
|
|
|
|
|
|
@@ -8315,7 +8344,7 @@ namespace Catch { |
|
|
|
|
|
|
|
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 ); |
|
|
|
|
|
|
@@ -8433,7 +8462,7 @@ namespace Catch { |
|
|
|
return tagCounts.size(); |
|
|
|
} |
|
|
|
|
|
|
|
std::size_t listReporters( Config const& /*config*/ ) { |
|
|
|
std::size_t listReporters() { |
|
|
|
Catch::cout() << "Available reporters:\n"; |
|
|
|
IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories(); |
|
|
|
std::size_t maxNameLen = 0; |
|
|
@@ -8464,7 +8493,7 @@ namespace Catch { |
|
|
|
if( config.listTags() ) |
|
|
|
listedCount = listedCount.valueOr(0) + listTags( config ); |
|
|
|
if( config.listReporters() ) |
|
|
|
listedCount = listedCount.valueOr(0) + listReporters( config ); |
|
|
|
listedCount = listedCount.valueOr(0) + listReporters(); |
|
|
|
return listedCount; |
|
|
|
} |
|
|
|
|
|
|
@@ -9930,13 +9959,22 @@ namespace Catch { |
|
|
|
void libIdentify(); |
|
|
|
|
|
|
|
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 ); |
|
|
|
|
|
|
|
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(); |
|
|
|
|
|
|
|
clara::Parser const& cli() const; |
|
|
@@ -10148,22 +10186,8 @@ namespace Catch { |
|
|
|
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) |
|
|
|
int Session::run( int argc, wchar_t* const argv[] ) { |
|
|
|
int Session::applyCommandLine( int argc, wchar_t const * const * argv ) { |
|
|
|
|
|
|
|
char **utf8Argv = new char *[ argc ]; |
|
|
|
|
|
|
@@ -10175,7 +10199,7 @@ namespace Catch { |
|
|
|
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 ) |
|
|
|
delete [] utf8Argv[ i ]; |
|
|
@@ -10185,6 +10209,12 @@ namespace Catch { |
|
|
|
return returnCode; |
|
|
|
} |
|
|
|
#endif |
|
|
|
|
|
|
|
void Session::useConfigData( ConfigData const& configData ) { |
|
|
|
m_configData = configData; |
|
|
|
m_config.reset(); |
|
|
|
} |
|
|
|
|
|
|
|
int Session::run() { |
|
|
|
if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeStart ) != 0 ) { |
|
|
|
Catch::cout() << "...waiting for enter/ return before starting" << std::endl; |
|
|
@@ -11686,7 +11716,7 @@ std::string StringMaker<bool>::convert(bool b) { |
|
|
|
return b ? "true" : "false"; |
|
|
|
} |
|
|
|
|
|
|
|
std::string StringMaker<char>::convert(char value) { |
|
|
|
std::string StringMaker<signed char>::convert(signed char value) { |
|
|
|
if (value == '\r') { |
|
|
|
return "'\\r'"; |
|
|
|
} else if (value == '\f') { |
|
|
@@ -11703,8 +11733,8 @@ std::string StringMaker<char>::convert(char value) { |
|
|
|
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) { |
|
|
|
return ::Catch::Detail::stringify(static_cast<char>(c)); |
|
|
@@ -11836,7 +11866,7 @@ namespace Catch { |
|
|
|
} |
|
|
|
|
|
|
|
Version const& libraryVersion() { |
|
|
|
static Version version( 2, 4, 1, "", 0 ); |
|
|
|
static Version version( 2, 4, 2, "", 0 ); |
|
|
|
return version; |
|
|
|
} |
|
|
|
|
|
|
@@ -13517,6 +13547,9 @@ namespace Catch { |
|
|
|
m_xml.startElement( "Catch" ); |
|
|
|
if( !m_config->name().empty() ) |
|
|
|
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 ) { |
|
|
@@ -13792,6 +13825,14 @@ int main (int argc, char * const argv[]) { |
|
|
|
|
|
|
|
#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 |
|
|
|
#define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ ) |
|
|
|
#define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ ) |
|
|
@@ -13851,6 +13892,14 @@ int main (int argc, char * const argv[]) { |
|
|
|
#define SUCCEED( ... ) INTERNAL_CATCH_MSG( "SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) |
|
|
|
#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 |
|
|
|
|
|
|
|
#define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) |
|
|
@@ -13931,6 +13980,9 @@ using Catch::Detail::Approx; |
|
|
|
#define CATCH_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 |
|
|
|
#else |
|
|
|
|
|
|
@@ -13980,6 +14032,9 @@ using Catch::Detail::Approx; |
|
|
|
#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 STATIC_REQUIRE( ... ) (void)(0) |
|
|
|
#define STATIC_REQUIRE_FALSE( ... ) (void)(0) |
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
#define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature ) |