diff options
| author | Phil Nash | 2017-06-29 11:18:14 +0100 |
|---|---|---|
| committer | Phil Nash | 2017-06-29 11:18:14 +0100 |
| commit | 78e799443531a84c5f337109d462af53249ed49c (patch) | |
| tree | a7dffa857b65d022145b258a7b7a3b110f902409 /include/internal/catch_stringref.cpp | |
| parent | cb0a5194af7e092fde6f1f7deffb2758e28e65fe (diff) | |
| download | catch3-78e799443531a84c5f337109d462af53249ed49c.tar.gz | |
Added string classes
Diffstat (limited to 'include/internal/catch_stringref.cpp')
| -rw-r--r-- | include/internal/catch_stringref.cpp | 140 |
1 files changed, 140 insertions, 0 deletions
diff --git a/include/internal/catch_stringref.cpp b/include/internal/catch_stringref.cpp new file mode 100644 index 00000000..d577d3af --- /dev/null +++ b/include/internal/catch_stringref.cpp @@ -0,0 +1,140 @@ +/* + * Copyright 2016 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ + +#include "catch_stringref.h" +#include "catch_stringbuilder.h" +#include "catch_string.h" +#include "catch_stringdata.h" + +#include <cstring> +#include <ostream> + +namespace Catch { + + StringRef StringRef::s_emptyStringRef = ""; + + StringRef::StringRef() + : StringRef( s_emptyStringRef ) + {} + + StringRef::StringRef( StringRef const& other ) + : m_start( other.m_start ), + m_size( other.m_size ), + m_data( other.m_data ) + { + if( m_data ) + m_data->addRef(); + } + + StringRef::StringRef( StringRef&& other ) noexcept + : m_start( other.m_start ), + m_size( other.m_size ), + m_data( other.m_data ) + { + other.m_data = nullptr; + } + + StringRef::StringRef( char const* rawChars ) + : m_start( rawChars ), + m_size( std::strlen( rawChars ) ) + {} + + StringRef::StringRef( char const* rawChars, size_type size ) + : m_start( rawChars ), + m_size( size ) + { + size_type rawSize = rawChars == nullptr ? 0 : std::strlen( rawChars ); + if( rawSize < size ) + size = rawSize; + } + + StringRef::StringRef( String const& other ) + : m_start( other.c_str() ), + m_size( other.size() ), + m_data( nullptr ) + {} + + StringRef::StringRef( String&& str ) noexcept + : m_start( str.c_str() ), + m_size( str.size() ), + m_data( str.m_data ) + { + str.m_data = StringData::getEmpty(); + } + + StringRef::~StringRef() noexcept { + if( isOwned() ) + m_data->release(); + } + + auto StringRef::operator = ( StringRef other ) -> StringRef& { + swap( other ); + return *this; + } + + void StringRef::swap( StringRef& other ) noexcept { + std::swap( m_start, other.m_start ); + std::swap( m_size, other.m_size ); + std::swap( m_data, other.m_data ); + } + + auto StringRef::c_str() const -> char const* { + if( isSubstring() ) + const_cast<StringRef*>( this )->takeOwnership(); + return m_start; + } + auto StringRef::data() const noexcept -> char const* { + return m_start; + } + + auto StringRef::isOwned() const noexcept -> bool { + return m_data != nullptr; + } + auto StringRef::isSubstring() const noexcept -> bool { + return m_start[m_size] != '\0'; + } + + void StringRef::takeOwnership() { + if( !isOwned() ) { + StringRef temp = String( *this ); + swap( temp ); + } + } + auto StringRef::substr( size_type start, size_type size ) const noexcept -> StringRef { + if( start < m_size ) + return StringRef( m_start+start, size ); + else + return StringRef(); + } + auto StringRef::operator == ( StringRef const& other ) const noexcept -> bool { + return + size() == other.size() && + (std::strncmp( m_start, other.m_start, size() ) == 0); + } + auto StringRef::operator != ( StringRef const& other ) const noexcept -> bool { + return !operator==( other ); + } + + auto operator + ( StringRef const& lhs, StringRef const& rhs ) -> String { + StringBuilder buf; + buf.reserve( lhs.size() + rhs.size() ); + buf.append( lhs ); + buf.append( rhs ); + return String( std::move( buf ) ); + } + auto operator + ( StringRef const& lhs, const char* rhs ) -> String { + return lhs + StringRef( rhs ); + } + auto operator + ( char const* lhs, StringRef const& rhs ) -> String { + return StringRef( lhs ) + rhs; + } + + std::ostream& operator << ( std::ostream& os, StringRef const& str ) { + return os << str.c_str(); + } + +} // namespace Catch |