1 /* 2 * Copyright 2016 Two Blue Cubes Ltd. All rights reserved. 3 * 4 * Distributed under the Boost Software License, Version 1.0. (See accompanying 5 * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6 */ 7 #ifndef CATCH_STRINGREF_H_INCLUDED 8 #define CATCH_STRINGREF_H_INCLUDED 9 10 #include <cstddef> 11 #include <string> 12 #include <iosfwd> 13 14 namespace Catch { 15 16 /// A non-owning string class (similar to the forthcoming std::string_view) 17 /// Note that, because a StringRef may be a substring of another string, 18 /// it may not be null terminated. c_str() must return a null terminated 19 /// string, however, and so the StringRef will internally take ownership 20 /// (taking a copy), if necessary. In theory this ownership is not externally 21 /// visible - but it does mean (substring) StringRefs should not be shared between 22 /// threads. 23 class StringRef { 24 public: 25 using size_type = std::size_t; 26 27 private: 28 friend struct StringRefTestAccess; 29 30 char const* m_start; 31 size_type m_size; 32 33 char* m_data = nullptr; 34 35 void takeOwnership(); 36 37 static constexpr char const* const s_empty = ""; 38 39 public: // construction/ assignment StringRef()40 StringRef() noexcept 41 : StringRef( s_empty, 0 ) 42 {} 43 StringRef(StringRef const & other)44 StringRef( StringRef const& other ) noexcept 45 : m_start( other.m_start ), 46 m_size( other.m_size ) 47 {} 48 StringRef(StringRef && other)49 StringRef( StringRef&& other ) noexcept 50 : m_start( other.m_start ), 51 m_size( other.m_size ), 52 m_data( other.m_data ) 53 { 54 other.m_data = nullptr; 55 } 56 57 StringRef( char const* rawChars ) noexcept; 58 StringRef(char const * rawChars,size_type size)59 StringRef( char const* rawChars, size_type size ) noexcept 60 : m_start( rawChars ), 61 m_size( size ) 62 {} 63 StringRef(std::string const & stdString)64 StringRef( std::string const& stdString ) noexcept 65 : m_start( stdString.c_str() ), 66 m_size( stdString.size() ) 67 {} 68 ~StringRef()69 ~StringRef() noexcept { 70 delete[] m_data; 71 } 72 73 auto operator = ( StringRef const &other ) noexcept -> StringRef& { 74 delete[] m_data; 75 m_data = nullptr; 76 m_start = other.m_start; 77 m_size = other.m_size; 78 return *this; 79 } 80 81 operator std::string() const; 82 83 void swap( StringRef& other ) noexcept; 84 85 public: // operators 86 auto operator == ( StringRef const& other ) const noexcept -> bool; 87 auto operator != ( StringRef const& other ) const noexcept -> bool; 88 89 auto operator[] ( size_type index ) const noexcept -> char; 90 91 public: // named queries 92 auto empty() const noexcept -> bool { 93 return m_size == 0; 94 } 95 auto size() const noexcept -> size_type { 96 return m_size; 97 } 98 99 auto numberOfCharacters() const noexcept -> size_type; 100 auto c_str() const -> char const*; 101 102 public: // substrings and searches 103 auto substr( size_type start, size_type size ) const noexcept -> StringRef; 104 105 // Returns the current start pointer. 106 // Note that the pointer can change when if the StringRef is a substring 107 auto currentData() const noexcept -> char const*; 108 109 private: // ownership queries - may not be consistent between calls 110 auto isOwned() const noexcept -> bool; 111 auto isSubstring() const noexcept -> bool; 112 }; 113 114 auto operator + ( StringRef const& lhs, StringRef const& rhs ) -> std::string; 115 auto operator + ( StringRef const& lhs, char const* rhs ) -> std::string; 116 auto operator + ( char const* lhs, StringRef const& rhs ) -> std::string; 117 118 auto operator += ( std::string& lhs, StringRef const& sr ) -> std::string&; 119 auto operator << ( std::ostream& os, StringRef const& sr ) -> std::ostream&; 120 121 122 inline auto operator "" _sr( char const* rawChars, std::size_t size ) noexcept -> StringRef { 123 return StringRef( rawChars, size ); 124 } 125 126 } // namespace Catch 127 128 inline auto operator "" _catch_sr( char const* rawChars, std::size_t size ) noexcept -> Catch::StringRef { 129 return Catch::StringRef( rawChars, size ); 130 } 131 132 #endif // CATCH_STRINGREF_H_INCLUDED 133