forked from flutter/engine
-
Notifications
You must be signed in to change notification settings - Fork 0
/
string_view.h
167 lines (136 loc) · 4.89 KB
/
string_view.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef FLUTTER_FML_STRING_VIEW_H_
#define FLUTTER_FML_STRING_VIEW_H_
#include <iosfwd>
#include <string>
#include <type_traits>
#include "flutter/fml/logging.h"
// MSVC 2015 doesn't support "extended constexpr" from C++14.
#if __cplusplus >= 201402L
// C++14 relaxed the limitation of the content of a constexpr function.
#define CONSTEXPR_IN_CPP14 constexpr
#else
#define CONSTEXPR_IN_CPP14
#endif
namespace fml {
// A string-like object that points to a sized piece of memory.
class StringView {
public:
// Types.
using const_iterator = const char*;
using iterator = const_iterator;
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
using reverse_iterator = const_reverse_iterator;
constexpr static size_t npos = static_cast<size_t>(-1);
// Constructors.
constexpr StringView() : data_(""), size_(0u) {}
constexpr StringView(const StringView& string_view)
: data_(string_view.data_), size_(string_view.size_) {}
constexpr StringView(const char* str, size_t len) : data_(str), size_(len) {}
explicit constexpr StringView(const char* str)
: data_(str), size_(constexpr_strlen(str)) {}
// Implicit constructor for constant C strings.
template <size_t N>
constexpr StringView(const char (&str)[N])
: data_(str), size_(constexpr_strlen(str)) {}
// Implicit constructor.
StringView(const std::string& str) : data_(str.data()), size_(str.size()) {}
// Copy operators.
StringView& operator=(const StringView& other) {
data_ = other.data_;
size_ = other.size_;
return *this;
}
// Capacity methods.
constexpr size_t size() const { return size_; }
constexpr bool empty() const { return size_ == 0u; }
// Element access methods.
constexpr char operator[](size_t pos) const { return data_[pos]; };
constexpr char at(size_t pos) const { return data_[pos]; };
constexpr char front() const { return data_[0]; };
constexpr char back() const { return data_[size_ - 1]; };
constexpr const char* data() const { return data_; }
// Iterators.
constexpr const_iterator begin() const { return cbegin(); }
constexpr const_iterator end() const { return cend(); }
constexpr const_iterator cbegin() const { return data_; }
constexpr const_iterator cend() const { return data_ + size_; }
const_reverse_iterator rbegin() const {
return const_reverse_iterator(cend());
}
const_reverse_iterator rend() const {
return const_reverse_iterator(cbegin());
}
const_reverse_iterator crbegin() const {
return const_reverse_iterator(cend());
}
const_reverse_iterator crend() const {
return const_reverse_iterator(cbegin());
}
// Modifier methods.
CONSTEXPR_IN_CPP14 void clear() {
data_ = "";
size_ = 0;
}
CONSTEXPR_IN_CPP14 void remove_prefix(size_t n) {
FML_DCHECK(n <= size_);
data_ += n;
size_ -= n;
}
CONSTEXPR_IN_CPP14 void remove_suffix(size_t n) {
FML_DCHECK(n <= size_);
size_ -= n;
}
CONSTEXPR_IN_CPP14 void swap(StringView& other) {
const char* data = data_;
data_ = other.data_;
other.data_ = data;
size_t size = size_;
size_ = other.size_;
other.size_ = size;
}
// String conversion.
std::string ToString() const { return std::string(data_, size_); }
// String operations.
constexpr StringView substr(size_t pos = 0, size_t n = npos) const {
return StringView(data_ + pos, min(n, size_ - pos));
}
// Returns negative, 0, or positive when |this| is lexigraphically
// less than, equal to, or greater than |other|, a la
// std::basic_string_view::compare.
int compare(StringView other);
size_t find(StringView s, size_t pos = 0) const;
size_t find(char c, size_t pos = 0) const;
size_t rfind(StringView s, size_t pos = npos) const;
size_t rfind(char c, size_t pos = npos) const;
size_t find_first_of(StringView s, size_t pos = 0) const;
size_t find_last_of(StringView s, size_t pos = npos) const;
size_t find_first_not_of(StringView s, size_t pos = 0) const;
size_t find_last_not_of(StringView s, size_t pos = npos) const;
private:
constexpr static size_t min(size_t v1, size_t v2) {
return v1 < v2 ? v1 : v2;
}
constexpr static int constexpr_strlen(const char* str) {
#if defined(_MSC_VER)
return *str ? 1 + constexpr_strlen(str + 1) : 0;
#else
return __builtin_strlen(str);
#endif
}
const char* data_;
size_t size_;
};
// Comparison.
bool operator==(StringView lhs, StringView rhs);
bool operator!=(StringView lhs, StringView rhs);
bool operator<(StringView lhs, StringView rhs);
bool operator>(StringView lhs, StringView rhs);
bool operator<=(StringView lhs, StringView rhs);
bool operator>=(StringView lhs, StringView rhs);
// IO.
std::ostream& operator<<(std::ostream& o, StringView string_view);
} // namespace fml
#endif // FLUTTER_FML_STRING_VIEW_H_