1#pragma once
2
3#include <string>
4
5namespace nn::util {
6
7// todo: verify implementations of these functions
8// most are currently just a copy of clang 4.0.1's string_view
9template <typename charT, typename traits = std::char_traits<charT>>
10class basic_string_view {
11public:
12 typedef basic_string_view<charT, traits> self_type;
13 typedef const charT* const_pointer;
14 typedef const charT& const_reference;
15 typedef const_pointer const_iterator;
16 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
17 typedef size_t size_type;
18
19 static const size_type npos = static_cast<size_type>(-1);
20
21 basic_string_view() : m_Str(nullptr), m_Len(0) {}
22 basic_string_view(const_pointer str, size_type len) : m_Str(str), m_Len(len) {}
23 basic_string_view(const_pointer str) : m_Str(str), m_Len(str ? traits::length(str) : 0) {}
24
25 const_pointer begin() const { return m_Str; }
26 const_pointer end() const { return m_Str + m_Len; }
27 const_pointer cbegin() const { return m_Str; }
28 const_pointer cend() const { return m_Str + m_Len; }
29 const_reverse_iterator rbegin() const { return end(); }
30 const_reverse_iterator rend() const { return begin(); }
31 const_reverse_iterator crbegin() const { return cend(); }
32 const_reverse_iterator crend() const { return cbegin(); }
33
34 size_type size() const { return m_Len; }
35 size_type length() const { return m_Len; }
36 const_pointer data() const { return m_Str; }
37 bool empty() const { return m_Len == 0; }
38
39 self_type substr(size_type pos = 0, size_type n = npos) const {
40 size_type rlen = std::min(n, size() - pos);
41 return self_type(data() + pos, rlen);
42 }
43
44 const_reference operator[](size_type pos) const { return m_Str[pos]; }
45 const_reference at(size_type pos) const { return m_Str[pos]; }
46 const_reference front() const { return m_Str[0]; }
47 const_reference back() const { return m_Str[m_Len - 1]; }
48
49 void clear() {
50 m_Str = nullptr;
51 m_Len = 0;
52 }
53
54 void remove_prefix(size_type n) {
55 m_Str += n;
56 m_Len -= n;
57 }
58
59 void remove_suffix(size_type n) { m_Len -= n; }
60
61 int compare(const self_type& str) const {
62 size_type rlen = std::min(a: m_Len, b: str.m_Len);
63 int result = traits::compare(m_Str, str.m_Str, rlen);
64 if (result != 0) {
65 return result;
66 } else if (str.size() < size()) {
67 return 1;
68 } else if (size() < str.size()) {
69 return -1;
70 }
71 return 0;
72 }
73
74 int compare(const_pointer str) const { return compare(self_type(str)); }
75
76 // todo: implement these, not sure what's the best way for cross compat
77 size_type find(const self_type& str, size_type pos = 0) const;
78 size_type find(charT c, size_type pos = 0) const;
79 size_type find(const_pointer str, size_type pos = 0) const;
80 size_type rfind(const self_type& str, size_type pos = 0) const;
81 size_type rfind(charT c, size_type pos = 0) const;
82 size_type rfind(const_pointer str, size_type pos = 0) const;
83 size_type find_first_of(const self_type& str, size_type pos = 0) const;
84 size_type find_first_of(const_pointer str, size_type pos = 0) const;
85 size_type find_last_of(const self_type& str, size_type pos = 0) const;
86 size_type find_last_of(const_pointer str, size_type pos = 0) const;
87 size_type find_first_not_of(const self_type& str, size_type pos = 0) const;
88 size_type find_first_not_of(charT c, size_type pos = 0) const;
89 size_type find_first_not_of(const_pointer str, size_type pos = 0) const;
90 size_type find_last_not_of(const self_type& str, size_type pos = 0) const;
91 size_type find_last_not_of(charT c, size_type pos = 0) const;
92 size_type find_last_not_of(const_pointer str, size_type pos = 0) const;
93
94 friend bool operator==(const basic_string_view& lhs, const basic_string_view& rhs) {
95 return lhs.compare(rhs) == 0;
96 }
97
98 friend bool operator!=(const basic_string_view& lhs, const basic_string_view& rhs) {
99 return lhs.compare(rhs) != 0;
100 }
101
102private:
103 const_pointer m_Str;
104 size_type m_Len;
105};
106
107using string_view = basic_string_view<char>;
108
109} // namespace nn::util
110