21#if defined(BSONCXX_POLY_USE_STD)
29using std::basic_string_view;
30using std::string_view;
36#elif defined(BSONCXX_POLY_USE_IMPLS)
54template <
typename Char,
typename Traits = std::
char_traits<Char>>
55class basic_string_view : bsoncxx::detail::equality_operators, bsoncxx::detail::ordering_operators {
57 using pointer = Char*;
58 using const_pointer = Char
const*;
59 using size_type = std::size_t;
60 using difference_type = std::ptrdiff_t;
61 using value_type = Char;
64 static constexpr size_type npos =
static_cast<size_type
>(-1);
68 const_pointer _begin =
nullptr;
73 using traits_type = Traits;
74 using reference = Char&;
75 using const_reference = Char
const&;
76 using const_iterator = const_pointer;
77 using iterator = const_iterator;
78 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
79 using reverse_iterator = const_reverse_iterator;
81 constexpr basic_string_view() noexcept = default;
82 constexpr basic_string_view(basic_string_view const&) noexcept = default;
83 BSONCXX_PRIVATE_CONSTEXPR_CXX14 basic_string_view& operator=(basic_string_view const&) noexcept = default;
85 constexpr basic_string_view(const_pointer s, size_type count) : _begin(s), _size(count) {}
87 constexpr basic_string_view(const_pointer s) : _begin(s), _size(traits_type::length(s)) {}
89 template <
typename Alloc>
90 constexpr basic_string_view(std::basic_string<value_type, traits_type, Alloc>
const& str) noexcept
91 : _begin(str.data()), _size(str.size()) {}
93#if defined(__cpp_lib_string_view)
94 constexpr basic_string_view(std::basic_string_view<value_type, traits_type> sv) noexcept
95 : _begin(sv.data()), _size(sv.size()) {}
98 basic_string_view(std::nullptr_t) =
delete;
100 constexpr const_iterator begin() const noexcept {
101 return const_iterator(_begin);
103 constexpr const_iterator end() const noexcept {
104 return begin() + size();
106 constexpr const_iterator cbegin() const noexcept {
109 constexpr const_iterator cend() const noexcept {
113 constexpr const_reverse_iterator rbegin() const noexcept {
114 return const_reverse_iterator{end()};
117 constexpr const_reverse_iterator rend() const noexcept {
118 return const_reverse_iterator{begin()};
121 constexpr const_reverse_iterator crbegin() const noexcept {
122 return const_reverse_iterator{cend()};
125 constexpr const_reverse_iterator crend() const noexcept {
126 return const_reverse_iterator{crbegin()};
129 constexpr const_reference operator[](size_type offset)
const {
130 return _begin[offset];
133 BSONCXX_PRIVATE_CONSTEXPR_CXX14 const_reference at(size_type pos)
const {
135 throw std::out_of_range{
"bsoncxx::stdx::basic_string_view::at()"};
140 constexpr const_reference front()
const {
144 constexpr const_reference back()
const {
145 return (*
this)[size() - 1];
148 constexpr const_pointer data() const noexcept {
152 constexpr size_type size() const noexcept {
156 constexpr size_type length() const noexcept {
160 constexpr bool empty() const noexcept {
164 constexpr size_type max_size() const noexcept {
165 return static_cast<size_type
>(std::numeric_limits<difference_type>::max());
168 BSONCXX_PRIVATE_CONSTEXPR_CXX14
void remove_prefix(size_type n) {
173 BSONCXX_PRIVATE_CONSTEXPR_CXX14
void remove_suffix(size_type n) {
177 BSONCXX_PRIVATE_CONSTEXPR_CXX14
void swap(basic_string_view& other) {
178 std::swap(_begin, other._begin);
179 std::swap(_size, other._size);
182 size_type copy(pointer dest, size_type count, size_type pos = 0)
const {
184 throw std::out_of_range{
"bsoncxx::stdx::basic_string_view::substr()"};
186 count = (std::min)(count, size() - pos);
187 Traits::copy(dest, data() + pos, count);
191 BSONCXX_PRIVATE_CONSTEXPR_CXX14 basic_string_view substr(size_type pos = 0, size_type count = npos)
const {
193 throw std::out_of_range{
"bsoncxx::stdx::basic_string_view::substr()"};
195 return basic_string_view(_begin + pos, (std::min)(count, size() - pos));
198 constexpr int compare(basic_string_view other)
const noexcept {
200 return _compare2(Traits::compare(data(), other.data(), (std::min)(size(), other.size())), other);
203 constexpr int compare(const_pointer cstr)
const {
204 return compare(basic_string_view(cstr));
207 constexpr int compare(size_type pos1, size_type count1, basic_string_view other)
const {
208 return substr(pos1, count1).compare(other);
211 constexpr int compare(size_type pos1, size_type count1, const_pointer cstr)
const {
212 return compare(pos1, count1, basic_string_view(cstr));
215 constexpr int compare(size_type pos1, size_type count1, basic_string_view other, size_type pos2, size_type count2)
217 return substr(pos1, count1).compare(other.substr(pos2, count2));
220 constexpr int compare(size_type pos1, size_type count1, const_pointer str, size_type count2)
const {
221 return substr(pos1, count1).compare(basic_string_view(str, count2));
224 BSONCXX_PRIVATE_CONSTEXPR_CXX14 size_type find(basic_string_view infix, size_type pos = 0) const noexcept {
228 basic_string_view sub = this->substr(pos);
233 const_iterator found = std::search(sub.begin(), sub.end(), infix.begin(), infix.end());
234 if (found == sub.end()) {
237 return static_cast<size_type
>(found - begin());
240 BSONCXX_PRIVATE_CONSTEXPR_CXX14 size_type rfind(basic_string_view infix, size_type pos = npos)
const noexcept {
242 size_type
const substr_size = pos != npos ? pos + infix.size() : pos;
244 return (std::min)(pos, size());
246 basic_string_view searched = this->substr(0, substr_size);
247 auto f = std::search(searched.rbegin(), searched.rend(), infix.rbegin(), infix.rend());
248 if (f == searched.rend()) {
251 return static_cast<size_type
>(rend() - f) - infix.size();
254 constexpr size_type find_first_of(basic_string_view set, size_type pos = 0) const noexcept {
255 return _find_if(pos, [&](value_type chr) {
return set.find(chr) != npos; });
258 constexpr size_type find_last_of(basic_string_view set, size_type pos = npos)
const noexcept {
259 return _rfind_if(pos, [&](value_type chr) {
return set.find(chr) != npos; });
262 constexpr size_type find_first_not_of(basic_string_view set, size_type pos = 0) const noexcept {
263 return _find_if(pos, [&](value_type chr) {
return set.find(chr) == npos; });
266 constexpr size_type find_last_not_of(basic_string_view set, size_type pos = npos)
const noexcept {
267 return _rfind_if(pos, [&](value_type chr) {
return set.find(chr) == npos; });
270#pragma push_macro("DECL_FINDERS")
272#define DECL_FINDERS(Name, DefaultPos) \
273 constexpr size_type Name(value_type chr, size_type pos = DefaultPos) const noexcept { \
274 return Name(basic_string_view(&chr, 1), pos); \
276 constexpr size_type Name(const_pointer cstr, size_type pos, size_type count) const { \
277 return Name(basic_string_view(cstr, count), pos); \
279 constexpr size_type Name(const_pointer cstr, size_type pos = DefaultPos) const { \
280 return Name(basic_string_view(cstr), pos); \
282 BSONCXX_PRIVATE_FORCE_SEMICOLON
284 DECL_FINDERS(find, 0);
285 DECL_FINDERS(rfind, npos);
286 DECL_FINDERS(find_first_of, 0);
287 DECL_FINDERS(find_last_of, npos);
288 DECL_FINDERS(find_first_not_of, 0);
289 DECL_FINDERS(find_last_not_of, npos);
290#pragma pop_macro("DECL_FINDERS")
293 template <
typename Allocator>
294 explicit operator std::basic_string<Char, Traits, Allocator>()
const {
295 return std::basic_string<Char, Traits, Allocator>(data(), size());
298#if defined(__cpp_lib_string_view)
299 explicit operator std::basic_string_view<value_type, traits_type>() const noexcept {
300 return std::basic_string_view<value_type, traits_type>(data(), size());
306 constexpr int _compare2(
int diff, basic_string_view other)
const noexcept {
308 return diff ? diff :
static_cast<int>(size() - other.size());
312 constexpr friend bool
313 tag_invoke(bsoncxx::detail::equal_to, basic_string_view left, basic_string_view right)
noexcept {
314 return left.size() == right.size() && left.compare(right) == 0;
318 constexpr friend bsoncxx::detail::strong_ordering
319 tag_invoke(bsoncxx::detail::compare_three_way cmp, basic_string_view left, basic_string_view right)
noexcept {
320 return cmp(left.compare(right), 0);
323 friend std::basic_ostream<Char, Traits>& operator<<(std::basic_ostream<Char, Traits>& out, basic_string_view self) {
324 out << std::basic_string<Char, Traits>(self);
330 template <
typename F>
331 BSONCXX_PRIVATE_CONSTEXPR_CXX14 size_type _find_if(size_type pos, F pred)
const noexcept {
332 auto const sub = substr(pos);
333 iterator
const found = std::find_if(sub.begin(), sub.end(), pred);
334 if (found == end()) {
337 return static_cast<size_type
>(found - begin());
342 template <
typename F>
343 BSONCXX_PRIVATE_CONSTEXPR_CXX14 size_type _rfind_if(size_type pos, F pred)
const noexcept {
345 auto const rpos = pos == npos ? npos : pos + 1;
347 auto const prefix = substr(0, rpos);
348 const_reverse_iterator
const found = std::find_if(prefix.rbegin(), prefix.rend(), pred);
349 if (found == rend()) {
353 return static_cast<size_type
>(rend() - found) - 1u;
359template <
typename C,
typename Tr>
360constexpr std::size_t basic_string_view<C, Tr>::npos;
370template <
typename CharT,
typename Traits>
371struct hash<bsoncxx::v1::stdx::basic_string_view<CharT, Traits>> :
private std::hash<std::basic_string<CharT, Traits>> {
372 std::size_t operator()(bsoncxx::v1::stdx::basic_string_view<CharT, Traits>
const& str)
const {
373 return std::hash<std::basic_string<CharT, Traits>>::operator()(
374 std::basic_string<CharT, Traits>(str.data(), str.size()));
381#error "Cannot find a valid polyfill for string_view"
398#if defined(BSONCXX_PRIVATE_DOXYGEN_PREPROCESSOR)
Provides macros describing the bsoncxx library configuration.
The bsoncxx v1 macro guard postlude header.
The bsoncxx v1 macro guard prelude header.
A polyfill for std::string_view.
Definition string_view.hpp:411
Declares C++17 standard library polyfills.
Declares entities whose ABI stability is guaranteed for documented symbols.
The top-level namespace within which all bsoncxx library entities are declared.