mirror of
https://github.com/catchorg/Catch2.git
synced 2024-11-22 13:26:10 +01:00
Provide a public method to get StringRef's underlying pointer
This allows reducing the amount of friends needed for its interface and some extra tricks later. The bad part is that the pointer can become invalidated via calls to other StringRef's public methods, but c'est la vie.
This commit is contained in:
parent
950ccf4749
commit
05cd05743a
@ -43,7 +43,7 @@ namespace Catch {
|
|||||||
const_cast<StringRef*>( this )->takeOwnership();
|
const_cast<StringRef*>( this )->takeOwnership();
|
||||||
return m_start;
|
return m_start;
|
||||||
}
|
}
|
||||||
auto StringRef::data() const noexcept -> char const* {
|
auto StringRef::currentData() const noexcept -> char const* {
|
||||||
return m_start;
|
return m_start;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,11 +112,11 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto operator << ( std::ostream& os, StringRef const& str ) -> std::ostream& {
|
auto operator << ( std::ostream& os, StringRef const& str ) -> std::ostream& {
|
||||||
return os.write(str.m_start, str.m_size);
|
return os.write(str.currentData(), str.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
auto operator+=( std::string& lhs, StringRef const& rhs ) -> std::string& {
|
auto operator+=( std::string& lhs, StringRef const& rhs ) -> std::string& {
|
||||||
lhs.append(rhs.m_start, rhs.m_size);
|
lhs.append(rhs.currentData(), rhs.size());
|
||||||
return lhs;
|
return lhs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,16 +84,12 @@ namespace Catch {
|
|||||||
|
|
||||||
void swap( StringRef& other ) noexcept;
|
void swap( StringRef& other ) noexcept;
|
||||||
|
|
||||||
friend auto operator << (std::ostream& os, StringRef const& sr)->std::ostream&;
|
|
||||||
|
|
||||||
public: // operators
|
public: // operators
|
||||||
auto operator == ( StringRef const& other ) const noexcept -> bool;
|
auto operator == ( StringRef const& other ) const noexcept -> bool;
|
||||||
auto operator != ( StringRef const& other ) const noexcept -> bool;
|
auto operator != ( StringRef const& other ) const noexcept -> bool;
|
||||||
|
|
||||||
auto operator[] ( size_type index ) const noexcept -> char;
|
auto operator[] ( size_type index ) const noexcept -> char;
|
||||||
|
|
||||||
friend auto operator += ( std::string& lhs, StringRef const& rhs ) -> std::string&;
|
|
||||||
|
|
||||||
public: // named queries
|
public: // named queries
|
||||||
auto empty() const noexcept -> bool {
|
auto empty() const noexcept -> bool {
|
||||||
return m_size == 0;
|
return m_size == 0;
|
||||||
@ -108,16 +104,22 @@ namespace Catch {
|
|||||||
public: // substrings and searches
|
public: // substrings and searches
|
||||||
auto substr( size_type start, size_type size ) const noexcept -> StringRef;
|
auto substr( size_type start, size_type size ) const noexcept -> StringRef;
|
||||||
|
|
||||||
|
// Returns the current start pointer.
|
||||||
|
// Note that the pointer can change when if the StringRef is a substring
|
||||||
|
auto currentData() const noexcept -> char const*;
|
||||||
|
|
||||||
private: // ownership queries - may not be consistent between calls
|
private: // ownership queries - may not be consistent between calls
|
||||||
auto isOwned() const noexcept -> bool;
|
auto isOwned() const noexcept -> bool;
|
||||||
auto isSubstring() const noexcept -> bool;
|
auto isSubstring() const noexcept -> bool;
|
||||||
auto data() const noexcept -> char const*;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
auto operator + ( StringRef const& lhs, StringRef const& rhs ) -> std::string;
|
auto operator + ( StringRef const& lhs, StringRef const& rhs ) -> std::string;
|
||||||
auto operator + ( StringRef const& lhs, char const* rhs ) -> std::string;
|
auto operator + ( StringRef const& lhs, char const* rhs ) -> std::string;
|
||||||
auto operator + ( char const* lhs, StringRef const& rhs ) -> std::string;
|
auto operator + ( char const* lhs, StringRef const& rhs ) -> std::string;
|
||||||
|
|
||||||
|
auto operator += ( std::string& lhs, StringRef const& sr ) -> std::string&;
|
||||||
|
auto operator << ( std::ostream& os, StringRef const& sr ) -> std::ostream&;
|
||||||
|
|
||||||
|
|
||||||
inline auto operator "" _sr( char const* rawChars, std::size_t size ) noexcept -> StringRef {
|
inline auto operator "" _sr( char const* rawChars, std::size_t size ) noexcept -> StringRef {
|
||||||
return StringRef( rawChars, size );
|
return StringRef( rawChars, size );
|
||||||
|
@ -637,11 +637,11 @@ String.tests.cpp:<line number>: passed: std::strcmp( ss.c_str(), "hello" ) == 0
|
|||||||
String.tests.cpp:<line number>: passed: ss == "hello" for: hello == "hello"
|
String.tests.cpp:<line number>: passed: ss == "hello" for: hello == "hello"
|
||||||
String.tests.cpp:<line number>: passed: isSubstring( ss ) for: true
|
String.tests.cpp:<line number>: passed: isSubstring( ss ) for: true
|
||||||
String.tests.cpp:<line number>: passed: isOwned( ss ) == false for: false == false
|
String.tests.cpp:<line number>: passed: isOwned( ss ) == false for: false == false
|
||||||
String.tests.cpp:<line number>: passed: rawChars == data( s ) for: "hello world!" == "hello world!"
|
String.tests.cpp:<line number>: passed: rawChars == s.currentData() for: "hello world!" == "hello world!"
|
||||||
String.tests.cpp:<line number>: passed: ss.c_str() != rawChars for: "hello" != "hello world!"
|
String.tests.cpp:<line number>: passed: ss.c_str() != rawChars for: "hello" != "hello world!"
|
||||||
String.tests.cpp:<line number>: passed: isSubstring( ss ) == false for: false == false
|
String.tests.cpp:<line number>: passed: isSubstring( ss ) == false for: false == false
|
||||||
String.tests.cpp:<line number>: passed: isOwned( ss ) for: true
|
String.tests.cpp:<line number>: passed: isOwned( ss ) for: true
|
||||||
String.tests.cpp:<line number>: passed: data( ss ) != data( s ) for: "hello" != "hello world!"
|
String.tests.cpp:<line number>: passed: ss.currentData() != s.currentData() for: "hello" != "hello world!"
|
||||||
String.tests.cpp:<line number>: passed: ss.size() == 6 for: 6 == 6
|
String.tests.cpp:<line number>: passed: ss.size() == 6 for: 6 == 6
|
||||||
String.tests.cpp:<line number>: passed: std::strcmp( ss.c_str(), "world!" ) == 0 for: 0 == 0
|
String.tests.cpp:<line number>: passed: std::strcmp( ss.c_str(), "world!" ) == 0 for: 0 == 0
|
||||||
String.tests.cpp:<line number>: passed: s.c_str() == s2.c_str() for: "hello world!" == "hello world!"
|
String.tests.cpp:<line number>: passed: s.c_str() == s2.c_str() for: "hello world!" == "hello world!"
|
||||||
|
@ -5076,7 +5076,7 @@ with expansion:
|
|||||||
|
|
||||||
String.tests.cpp:<line number>:
|
String.tests.cpp:<line number>:
|
||||||
PASSED:
|
PASSED:
|
||||||
REQUIRE( rawChars == data( s ) )
|
REQUIRE( rawChars == s.currentData() )
|
||||||
with expansion:
|
with expansion:
|
||||||
"hello world!" == "hello world!"
|
"hello world!" == "hello world!"
|
||||||
|
|
||||||
@ -5100,7 +5100,7 @@ with expansion:
|
|||||||
|
|
||||||
String.tests.cpp:<line number>:
|
String.tests.cpp:<line number>:
|
||||||
PASSED:
|
PASSED:
|
||||||
REQUIRE( data( ss ) != data( s ) )
|
REQUIRE( ss.currentData() != s.currentData() )
|
||||||
with expansion:
|
with expansion:
|
||||||
"hello" != "hello world!"
|
"hello" != "hello world!"
|
||||||
|
|
||||||
|
@ -5808,7 +5808,7 @@ Message from section two
|
|||||||
</Expression>
|
</Expression>
|
||||||
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
|
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
|
||||||
<Original>
|
<Original>
|
||||||
rawChars == data( s )
|
rawChars == s.currentData()
|
||||||
</Original>
|
</Original>
|
||||||
<Expanded>
|
<Expanded>
|
||||||
"hello world!" == "hello world!"
|
"hello world!" == "hello world!"
|
||||||
@ -5840,7 +5840,7 @@ Message from section two
|
|||||||
</Expression>
|
</Expression>
|
||||||
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
|
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
|
||||||
<Original>
|
<Original>
|
||||||
data( ss ) != data( s )
|
ss.currentData() != s.currentData()
|
||||||
</Original>
|
</Original>
|
||||||
<Expanded>
|
<Expanded>
|
||||||
"hello" != "hello world!"
|
"hello" != "hello world!"
|
||||||
|
@ -14,9 +14,6 @@ namespace Catch {
|
|||||||
static auto isSubstring( StringRef const& stringRef ) -> bool {
|
static auto isSubstring( StringRef const& stringRef ) -> bool {
|
||||||
return stringRef.isSubstring();
|
return stringRef.isSubstring();
|
||||||
}
|
}
|
||||||
static auto data( StringRef const& stringRef ) -> char const* {
|
|
||||||
return stringRef.data();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
auto isOwned( StringRef const& stringRef ) -> bool {
|
auto isOwned( StringRef const& stringRef ) -> bool {
|
||||||
@ -25,14 +22,11 @@ namespace Catch {
|
|||||||
auto isSubstring( StringRef const& stringRef ) -> bool {
|
auto isSubstring( StringRef const& stringRef ) -> bool {
|
||||||
return StringRefTestAccess::isSubstring( stringRef );
|
return StringRefTestAccess::isSubstring( stringRef );
|
||||||
}
|
}
|
||||||
auto data( StringRef const& stringRef ) -> char const* {
|
|
||||||
return StringRefTestAccess::data( stringRef );
|
|
||||||
}
|
|
||||||
} // namespace Catch2
|
} // namespace Catch2
|
||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
inline auto toString( Catch::StringRef const& stringRef ) -> std::string {
|
inline auto toString( Catch::StringRef const& stringRef ) -> std::string {
|
||||||
return std::string( data( stringRef ), stringRef.size() );
|
return std::string( stringRef.currentData(), stringRef.size() );
|
||||||
}
|
}
|
||||||
} // namespace Catch
|
} // namespace Catch
|
||||||
|
|
||||||
@ -53,7 +47,7 @@ TEST_CASE( "StringRef", "[Strings][StringRef]" ) {
|
|||||||
REQUIRE( s.size() == 5 );
|
REQUIRE( s.size() == 5 );
|
||||||
REQUIRE( isSubstring( s ) == false );
|
REQUIRE( isSubstring( s ) == false );
|
||||||
|
|
||||||
auto rawChars = data( s );
|
auto rawChars = s.currentData();
|
||||||
REQUIRE( std::strcmp( rawChars, "hello" ) == 0 );
|
REQUIRE( std::strcmp( rawChars, "hello" ) == 0 );
|
||||||
|
|
||||||
SECTION( "c_str() does not cause copy" ) {
|
SECTION( "c_str() does not cause copy" ) {
|
||||||
@ -74,7 +68,6 @@ TEST_CASE( "StringRef", "[Strings][StringRef]" ) {
|
|||||||
|
|
||||||
REQUIRE( isSubstring( original ) == false );
|
REQUIRE( isSubstring( original ) == false );
|
||||||
REQUIRE( isOwned( original ) );
|
REQUIRE( isOwned( original ) );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -92,14 +85,14 @@ TEST_CASE( "StringRef", "[Strings][StringRef]" ) {
|
|||||||
REQUIRE( isSubstring( ss ) );
|
REQUIRE( isSubstring( ss ) );
|
||||||
REQUIRE( isOwned( ss ) == false );
|
REQUIRE( isOwned( ss ) == false );
|
||||||
|
|
||||||
auto rawChars = data( ss );
|
auto rawChars = ss.currentData();
|
||||||
REQUIRE( rawChars == data( s ) ); // same pointer value
|
REQUIRE( rawChars == s.currentData() ); // same pointer value
|
||||||
REQUIRE( ss.c_str() != rawChars );
|
REQUIRE( ss.c_str() != rawChars );
|
||||||
|
|
||||||
REQUIRE( isSubstring( ss ) == false );
|
REQUIRE( isSubstring( ss ) == false );
|
||||||
REQUIRE( isOwned( ss ) );
|
REQUIRE( isOwned( ss ) );
|
||||||
|
|
||||||
REQUIRE( data( ss ) != data( s ) ); // different pointer value
|
REQUIRE( ss.currentData() != s.currentData() ); // different pointer value
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION( "non-zero-based substring") {
|
SECTION( "non-zero-based substring") {
|
||||||
|
Loading…
Reference in New Issue
Block a user