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 #include <cassert>
14 
15 namespace Catch {
16 
17     /// A non-owning string class (similar to the forthcoming std::string_view)
18     /// Note that, because a StringRef may be a substring of another string,
19     /// it may not be null terminated.
20     class StringRef {
21     public:
22         using size_type = std::size_t;
23         using const_iterator = const char*;
24 
25     private:
26         static constexpr char const* const s_empty = "";
27 
28         char const* m_start = s_empty;
29         size_type m_size = 0;
30 
31     public: // construction
32         constexpr StringRef() noexcept = default;
33 
34         StringRef( char const* rawChars ) noexcept;
35 
StringRef(char const * rawChars,size_type size)36         constexpr StringRef( char const* rawChars, size_type size ) noexcept
37         :   m_start( rawChars ),
38             m_size( size )
39         {}
40 
StringRef(std::string const & stdString)41         StringRef( std::string const& stdString ) noexcept
42         :   m_start( stdString.c_str() ),
43             m_size( stdString.size() )
44         {}
45 
string()46         explicit operator std::string() const {
47             return std::string(m_start, m_size);
48         }
49 
50     public: // operators
51         auto operator == ( StringRef const& other ) const noexcept -> bool;
52         auto operator != (StringRef const& other) const noexcept -> bool {
53             return !(*this == other);
54         }
55 
56         auto operator[] ( size_type index ) const noexcept -> char {
57             assert(index < m_size);
58             return m_start[index];
59         }
60 
61     public: // named queries
62         constexpr auto empty() const noexcept -> bool {
63             return m_size == 0;
64         }
65         constexpr auto size() const noexcept -> size_type {
66             return m_size;
67         }
68 
69         // Returns the current start pointer. If the StringRef is not
70         // null-terminated, throws std::domain_exception
71         auto c_str() const -> char const*;
72 
73     public: // substrings and searches
74         // Returns a substring of [start, start + length).
75         // If start + length > size(), then the substring is [start, size()).
76         // If start > size(), then the substring is empty.
77         auto substr( size_type start, size_type length ) const noexcept -> StringRef;
78 
79         // Returns the current start pointer. May not be null-terminated.
80         auto data() const noexcept -> char const*;
81 
82         constexpr auto isNullTerminated() const noexcept -> bool {
83             return m_start[m_size] == '\0';
84         }
85 
86     public: // iterators
begin()87         constexpr const_iterator begin() const { return m_start; }
end()88         constexpr const_iterator end() const { return m_start + m_size; }
89     };
90 
91     auto operator += ( std::string& lhs, StringRef const& sr ) -> std::string&;
92     auto operator << ( std::ostream& os, StringRef const& sr ) -> std::ostream&;
93 
94 
95     constexpr auto operator "" _sr( char const* rawChars, std::size_t size ) noexcept -> StringRef {
96         return StringRef( rawChars, size );
97     }
98 } // namespace Catch
99 
100 constexpr auto operator "" _catch_sr( char const* rawChars, std::size_t size ) noexcept -> Catch::StringRef {
101     return Catch::StringRef( rawChars, size );
102 }
103 
104 #endif // CATCH_STRINGREF_H_INCLUDED
105