cpp-common/bt2c: add `CStringView::startsWith`
[babeltrace.git] / src / cpp-common / bt2c / c-string-view.hpp
CommitLineData
339e8bc4
PP
1/*
2 * Copyright (c) 2023 Philippe Proulx <pproulx@efficios.com>
3 *
4 * SPDX-License-Identifier: MIT
5 */
6
7#ifndef BABELTRACE_CPP_COMMON_BT2C_C_STRING_VIEW_HPP
8#define BABELTRACE_CPP_COMMON_BT2C_C_STRING_VIEW_HPP
9
10#include <cstddef>
11#include <cstring>
12#include <string>
13
14#include "common/assert.h"
15#include "cpp-common/bt2s/string-view.hpp"
7c9d996f 16#include "cpp-common/vendor/fmt/format.h" /* IWYU pragma: keep */
339e8bc4 17
821af099
SM
18#include "type-traits.hpp"
19
339e8bc4
PP
20namespace bt2c {
21
22/*
23 * A view on a constant null-terminated C string.
24 *
25 * Similar to `bt2s::string_view`, but len() and end() compute the
26 * length on demand.
27 */
28class CStringView final
29{
30public:
31 /*
32 * Builds an empty view (data() returns `nullptr`).
33 *
34 * Intentionally not explicit.
35 */
26d1608e 36 constexpr CStringView() noexcept = default;
339e8bc4
PP
37
38 /*
39 * Builds a view of the C string `str` (may be `nullptr`).
40 *
41 * Intentionally not explicit.
42 */
26d1608e 43 constexpr CStringView(const char * const str) noexcept : _mStr {str}
339e8bc4
PP
44 {
45 }
46
a0ae532f
SM
47 /*
48 * Builds a view of the string `str`.
49 *
50 * Intentionally not explicit.
51 */
52 CStringView(const std::string& str) noexcept : _mStr {str.c_str()}
53 {
54 }
55
339e8bc4
PP
56 /*
57 * Makes this view view the C string `str` (may be `nullptr`).
58 *
59 * Intentionally not explicit.
60 */
61 CStringView& operator=(const char * const str) noexcept
62 {
63 _mStr = str;
64 return *this;
65 }
66
67 /*
68 * Viewed null-terminated C string (may be `nullptr`).
69 */
70 const char *data() const noexcept
71 {
72 return _mStr;
73 }
74
75 /*
76 * Alias of data().
77 */
78 operator const char *() const noexcept
79 {
80 return this->data();
81 }
82
83 /*
84 * Alias of data().
85 */
86 const char *operator*() const noexcept
87 {
88 return this->data();
89 }
90
91 /*
92 * Alias of data().
93 *
94 * data() must not return `nullptr`.
95 */
96 const char *begin() const noexcept
97 {
98 BT_ASSERT_DBG(_mStr);
99 return this->data();
100 }
101
102 /*
103 * Pointer to the null character of the viewed C string.
104 *
105 * data() must not return `nullptr`.
106 */
107 const char *end() const noexcept
108 {
109 BT_ASSERT_DBG(_mStr);
110 return _mStr + this->len();
111 }
112
113 /*
114 * Length of the viewed C string, excluding the null character.
115 *
116 * data() must not return `nullptr`.
117 */
118 std::size_t len() const noexcept
119 {
120 BT_ASSERT_DBG(_mStr);
121 return std::strlen(_mStr);
122 }
123
124 /*
125 * Returns an `std::string` instance containing a copy of the viewed
126 * C string.
127 *
128 * data() must not return `nullptr`.
129 */
130 std::string str() const
131 {
132 BT_ASSERT_DBG(_mStr);
133 return std::string {_mStr};
134 }
135
136 /*
137 * Alias of str().
138 */
139 operator std::string() const
140 {
141 return this->str();
142 }
143
144 /*
145 * Returns a `bt2s::string_view` instance to view the contents,
146 * excluding the null character, of the viewed C string.
147 */
148 bt2s::string_view strView() const noexcept
149 {
150 if (_mStr) {
151 return bt2s::string_view {this->begin(), this->len()};
152 } else {
153 return {};
154 }
155 }
156
157 /*
158 * Alias of strView().
159 */
160 operator bt2s::string_view() const noexcept
161 {
162 return this->strView();
163 }
164
165 /*
166 * Returns the character at index `i`.
167 *
168 * `i` must be less than what len() returns.
169 *
170 * data() must not return `nullptr`.
171 */
172 char operator[](const std::size_t i) const noexcept
173 {
174 BT_ASSERT_DBG(_mStr);
175 BT_ASSERT_DBG(i < this->len());
176 return _mStr[i];
177 }
178
dc0f6dd1
SM
179 bool startsWith(const bt2c::CStringView prefix) const noexcept
180 {
181 BT_ASSERT_DBG(_mStr);
182 BT_ASSERT_DBG(prefix);
183 return std::strncmp(_mStr, prefix, prefix.len()) == 0;
184 }
185
339e8bc4
PP
186private:
187 const char *_mStr = nullptr;
188};
189
485083ae 190inline const char *format_as(const CStringView& str)
339e8bc4 191{
e64addc7
SM
192 return str ? *str : "(null)";
193}
339e8bc4 194
821af099
SM
195namespace internal {
196
197template <typename StrT>
198const char *asConstCharPtr(StrT&& val) noexcept
199{
200 return val.data();
201}
202
203inline const char *asConstCharPtr(const char * const val) noexcept
204{
205 return val;
206}
207
208template <typename StrT>
209using ComparableWithCStringView =
210 IsOneOf<typename std::decay<StrT>::type, CStringView, std::string, const char *>;
211
212} /* namespace internal */
213
214/*
215 * Returns true if `lhs` is equal to `rhs`.
216 *
217 * `LhsT` and `RhsT` may be any of:
218 *
219 * • `const char *`
220 * • `std::string`
221 * • `CStringView`
222 *
223 * Both `lhs` and `rhs` must not have an underlying `nullptr` raw data.
224 */
225template <
226 typename LhsT, typename RhsT,
227 typename = typename std::enable_if<internal::ComparableWithCStringView<LhsT>::value>::type,
228 typename = typename std::enable_if<internal::ComparableWithCStringView<RhsT>::value>::type>
229bool operator==(LhsT&& lhs, RhsT&& rhs) noexcept
230{
231 const auto rawLhs = internal::asConstCharPtr(lhs);
232 const auto rawRhs = internal::asConstCharPtr(rhs);
233
234 BT_ASSERT_DBG(rawLhs);
235 BT_ASSERT_DBG(rawRhs);
236 return std::strcmp(rawLhs, rawRhs) == 0;
237}
238
239/*
240 * Returns true if `lhs` is not equal to `rhs`.
241 *
242 * `LhsT` and `RhsT` may be any of:
243 *
244 * • `const char *`
245 * • `std::string`
246 * • `CStringView`
247 *
248 * Both `lhs` and `rhs` must not have an underlying `nullptr` raw data.
249 */
ab3bed93
SM
250template <
251 typename LhsT, typename RhsT,
252 typename = typename std::enable_if<internal::ComparableWithCStringView<LhsT>::value>::type,
253 typename = typename std::enable_if<internal::ComparableWithCStringView<RhsT>::value>::type>
821af099
SM
254bool operator!=(LhsT&& lhs, RhsT&& rhs) noexcept
255{
256 return !(std::forward<LhsT>(lhs) == std::forward<RhsT>(rhs));
257}
258
e64addc7 259} /* namespace bt2c */
339e8bc4
PP
260
261#endif /* BABELTRACE_CPP_COMMON_BT2C_C_STRING_VIEW_HPP */
This page took 0.036117 seconds and 4 git commands to generate.