• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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