17 #include <bsoncxx/config/prelude.hpp>
19 #if defined(BSONCXX_POLY_USE_MNMLSTC)
21 #include <core/string.hpp>
27 using ::core::basic_string_view;
28 using ::core::string_view;
34 #elif defined(BSONCXX_POLY_USE_BOOST)
36 #include <boost/version.hpp>
38 #if BOOST_VERSION >= 106100
40 #include <boost/utility/string_view.hpp>
46 using ::boost::basic_string_view;
47 using ::boost::string_view;
55 #include <boost/utility/string_ref.hpp>
61 template <
typename charT,
typename traits = std::
char_traits<
charT>>
62 using basic_string_view = ::boost::basic_string_ref<charT, traits>;
63 using string_view = ::boost::string_ref;
71 #elif defined(BSONCXX_POLY_USE_STD_EXPERIMENTAL)
73 #include <experimental/string_view>
79 using ::std::experimental::basic_string_view;
80 using ::std::experimental::string_view;
86 #elif defined(BSONCXX_POLY_USE_STD)
88 #include <string_view>
94 using ::std::basic_string_view;
95 using ::std::string_view;
101 #elif defined(BSONCXX_POLY_USE_IMPLS)
111 #include <bsoncxx/stdx/operators.hpp>
112 #include <bsoncxx/stdx/type_traits.hpp>
121 template <
typename Char,
typename Traits = std::
char_traits<Char>>
122 class basic_string_view : bsoncxx::detail::equality_operators, bsoncxx::detail::ordering_operators {
125 using pointer = Char*;
127 using const_pointer =
const Char*;
129 using size_type = std::size_t;
131 using difference_type = std::ptrdiff_t;
133 using value_type = Char;
136 static constexpr size_type npos =
static_cast<size_type
>(-1);
140 const_pointer _begin =
nullptr;
145 using traits_type = Traits;
146 using reference = Char&;
147 using const_reference =
const Char&;
148 using const_iterator = const_pointer;
149 using iterator = const_iterator;
150 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
151 using reverse_iterator = const_reverse_iterator;
156 constexpr basic_string_view() noexcept = default;
157 constexpr basic_string_view(const basic_string_view&) noexcept = default;
158 bsoncxx_cxx14_constexpr basic_string_view& operator=(const basic_string_view&) noexcept =
165 constexpr basic_string_view(const_pointer s, size_type count) : _begin(s), _size(count) {}
172 constexpr basic_string_view(const_pointer s) : _begin(s), _size(traits_type::length(s)) {}
180 template <
typename Alloc>
181 constexpr basic_string_view(
182 const std::basic_string<value_type, traits_type, Alloc>& str) noexcept
183 : _begin(str.data()), _size(str.size()) {}
185 #if __cpp_lib_string_view
186 constexpr basic_string_view(std::basic_string_view<value_type, traits_type> sv) noexcept
187 : _begin(sv.data()), _size(sv.size()) {}
191 basic_string_view(std::nullptr_t) =
delete;
193 constexpr const_iterator begin() const noexcept {
194 return const_iterator(_begin);
196 constexpr const_iterator end() const noexcept {
197 return begin() + size();
199 constexpr const_iterator cbegin() const noexcept {
202 constexpr const_iterator cend() const noexcept {
206 constexpr const_reverse_iterator rbegin() const noexcept {
207 return const_reverse_iterator{end()};
210 constexpr const_reverse_iterator rend() const noexcept {
211 return const_reverse_iterator{begin()};
214 constexpr const_reverse_iterator crbegin() const noexcept {
215 return const_reverse_iterator{cend()};
218 constexpr const_reverse_iterator crend() const noexcept {
219 return const_reverse_iterator{crbegin()};
228 constexpr const_reference operator[](size_type offset)
const {
229 return _begin[offset];
238 bsoncxx_cxx14_constexpr const_reference at(size_type pos)
const {
240 throw std::out_of_range{
"bsoncxx::stdx::basic_string_view::at()"};
245 constexpr const_reference front()
const {
249 constexpr const_reference back()
const {
250 return (*
this)[size() - 1];
254 constexpr const_pointer data() const noexcept {
258 constexpr size_type size() const noexcept {
262 constexpr size_type length() const noexcept {
266 constexpr
bool empty() const noexcept {
270 constexpr size_type max_size() const noexcept {
271 return static_cast<size_type
>(std::numeric_limits<difference_type>::max());
279 bsoncxx_cxx14_constexpr
void remove_prefix(size_type n) {
289 bsoncxx_cxx14_constexpr
void remove_suffix(size_type n) {
296 bsoncxx_cxx14_constexpr
void swap(basic_string_view& other) {
297 std::swap(_begin, other._begin);
298 std::swap(_size, other._size);
312 size_type copy(pointer dest, size_type count, size_type pos = 0)
const {
314 throw std::out_of_range{
"bsoncxx::stdx::basic_string_view::substr()"};
316 count = (std::min)(count, size() - pos);
317 Traits::copy(dest, data() + pos, count);
330 bsoncxx_cxx14_constexpr basic_string_view substr(size_type pos = 0,
331 size_type count = npos)
const {
333 throw std::out_of_range{
"bsoncxx::stdx::basic_string_view::substr()"};
335 return basic_string_view(_begin + pos, (std::min)(count, size() - pos));
346 constexpr
int compare(basic_string_view other)
const noexcept {
348 return _compare2(Traits::compare(data(), other.data(), (std::min)(size(), other.size())),
357 constexpr
int compare(const_pointer cstr)
const {
358 return compare(basic_string_view(cstr));
366 constexpr
int compare(size_type pos1, size_type count1, basic_string_view other)
const {
367 return substr(pos1, count1).compare(other);
375 constexpr
int compare(size_type pos1, size_type count1, const_pointer cstr)
const {
376 return compare(pos1, count1, basic_string_view(cstr));
384 constexpr
int compare(size_type pos1,
386 basic_string_view other,
388 size_type count2)
const {
389 return substr(pos1, count1).compare(other.substr(pos2, count2));
397 constexpr
int compare(size_type pos1,
400 size_type count2)
const {
401 return substr(pos1, count1).compare(basic_string_view(str, count2));
408 bsoncxx_cxx14_constexpr size_type find(basic_string_view infix, size_type pos = 0) const
413 basic_string_view sub = this->substr(pos);
418 const_iterator found = std::search(sub.begin(), sub.end(), infix.begin(), infix.end());
419 if (found == sub.end()) {
422 return static_cast<size_type
>(found - begin());
429 bsoncxx_cxx14_constexpr size_type rfind(basic_string_view infix, size_type pos = npos)
const
432 const size_type substr_size = pos != npos ? pos + infix.size() : pos;
434 return (std::min)(pos, size());
436 basic_string_view searched = this->substr(0, substr_size);
437 auto f = std::search(searched.rbegin(), searched.rend(), infix.rbegin(), infix.rend());
438 if (f == searched.rend()) {
441 return static_cast<size_type
>(rend() - f) - infix.size();
448 constexpr size_type find_first_of(basic_string_view set, size_type pos = 0) const noexcept {
449 return _find_if(pos, [&](value_type chr) {
return set.find(chr) != npos; });
456 constexpr size_type find_last_of(basic_string_view set, size_type pos = npos)
const noexcept {
457 return _rfind_if(pos, [&](value_type chr) {
return set.find(chr) != npos; });
464 constexpr size_type find_first_not_of(basic_string_view set, size_type pos = 0) const noexcept {
465 return _find_if(pos, [&](value_type chr) {
return set.find(chr) == npos; });
472 constexpr size_type find_last_not_of(basic_string_view set, size_type pos = npos)
const
474 return _rfind_if(pos, [&](value_type chr) {
return set.find(chr) == npos; });
477 #pragma push_macro("DECL_FINDERS")
479 #define DECL_FINDERS(Name, DefaultPos) \
480 constexpr size_type Name(value_type chr, size_type pos = DefaultPos) const noexcept { \
481 return Name(basic_string_view(&chr, 1), pos); \
483 constexpr size_type Name(const_pointer cstr, size_type pos, size_type count) const { \
484 return Name(basic_string_view(cstr, count), pos); \
486 constexpr size_type Name(const_pointer cstr, size_type pos = DefaultPos) const { \
487 return Name(basic_string_view(cstr), pos); \
489 BSONCXX_FORCE_SEMICOLON
490 DECL_FINDERS(find, 0);
491 DECL_FINDERS(rfind, npos);
492 DECL_FINDERS(find_first_of, 0);
493 DECL_FINDERS(find_last_of, npos);
494 DECL_FINDERS(find_first_not_of, 0);
495 DECL_FINDERS(find_last_not_of, npos);
496 #pragma pop_macro("DECL_FINDERS")
501 template <
typename Allocator>
502 explicit operator std::basic_string<Char, Traits, Allocator>()
const {
503 return std::basic_string<Char, Traits, Allocator>(data(), size());
506 #if __cpp_lib_string_view
507 explicit operator std::basic_string_view<value_type, traits_type>() const noexcept {
508 return std::basic_string_view<value_type, traits_type>(data(), size());
514 constexpr
int _compare2(
int diff, basic_string_view other)
const noexcept {
516 return diff ? diff :
static_cast<int>(size() - other.size());
520 constexpr
friend bool tag_invoke(bsoncxx::detail::equal_to,
521 basic_string_view left,
522 basic_string_view right) noexcept {
523 return left.size() == right.size() && left.compare(right) == 0;
527 constexpr
friend bsoncxx::detail::strong_ordering tag_invoke(
528 bsoncxx::detail::compare_three_way cmp,
529 basic_string_view left,
530 basic_string_view right) noexcept {
531 return cmp(left.compare(right), 0);
534 friend std::basic_ostream<Char, Traits>& operator<<(std::basic_ostream<Char, Traits>& out,
535 basic_string_view
self) {
536 out << std::basic_string<Char, Traits>(
self);
542 template <
typename F>
543 bsoncxx_cxx14_constexpr size_type _find_if(size_type pos, F pred)
const noexcept {
544 const auto sub = substr(pos);
545 const iterator found = std::find_if(sub.begin(), sub.end(), pred);
546 if (found == end()) {
549 return static_cast<size_type
>(found - begin());
554 template <
typename F>
555 bsoncxx_cxx14_constexpr size_type _rfind_if(size_type pos, F pred)
const noexcept {
557 const auto rpos = pos == npos ? npos : pos + 1;
559 const auto prefix = substr(0, rpos);
560 const const_reverse_iterator found = std::find_if(prefix.rbegin(), prefix.rend(), pred);
561 if (found == rend()) {
565 return static_cast<size_type
>(rend() - found) - 1u;
570 template <
typename C,
typename Tr>
571 const std::size_t basic_string_view<C, Tr>::npos;
573 using string_view = basic_string_view<char>;
581 template <
typename CharT,
typename Traits>
582 struct hash<
bsoncxx::v_noabi::stdx::basic_string_view<CharT, Traits>>
583 :
private std::hash<std::basic_string<CharT, Traits>> {
584 std::size_t operator()(
585 const bsoncxx::v_noabi::stdx::basic_string_view<CharT, Traits>& str)
const {
586 return std::hash<std::basic_string<CharT, Traits>>::operator()(
587 std::basic_string<CharT, Traits>(str.data(), str.size()));
594 #error "Cannot find a valid polyfill for string_view"
597 #include <bsoncxx/config/postlude.hpp>
602 using ::bsoncxx::v_noabi::stdx::basic_string_view;
603 using ::bsoncxx::v_noabi::stdx::string_view;
The top-level namespace for bsoncxx library entities.
Definition: element-fwd.hpp:19