Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma once
- #include <string_view>
- #include <memory>
- #include <string>
- #include <algorithm>
- #include <compare>
- struct life_string_view {
- std::string_view _data;
- std::shared_ptr<void> _life;
- // Constructor
- life_string_view(std::string_view data, std::shared_ptr<void> life)
- : _data(data), _life(std::move(life)) {}
- // Factory method
- template <class T>
- static life_string_view allocate(T&& data) {
- auto p = std::make_shared<std::decay_t<T>>(std::forward<T>(data));
- return {std::string_view(*p), p};
- }
- // Member types
- using traits_type = std::string_view::traits_type;
- using value_type = std::string_view::value_type;
- using pointer = std::string_view::pointer;
- using const_pointer = std::string_view::const_pointer;
- using reference = std::string_view::reference;
- using const_reference = std::string_view::const_reference;
- using const_iterator = std::string_view::const_iterator;
- using iterator = const_iterator;
- using const_reverse_iterator = std::string_view::const_reverse_iterator;
- using reverse_iterator = const_reverse_iterator;
- using size_type = std::string_view::size_type;
- using difference_type = std::string_view::difference_type;
- static constexpr size_type npos = std::string_view::npos;
- // Iterators
- const_iterator begin() const noexcept { return _data.begin(); }
- const_iterator end() const noexcept { return _data.end(); }
- const_iterator cbegin() const noexcept { return _data.cbegin(); }
- const_iterator cend() const noexcept { return _data.cend(); }
- const_reverse_iterator rbegin() const noexcept { return _data.rbegin(); }
- const_reverse_iterator rend() const noexcept { return _data.rend(); }
- const_reverse_iterator crbegin() const noexcept { return _data.crbegin(); }
- const_reverse_iterator crend() const noexcept { return _data.crend(); }
- // Capacity
- size_type size() const noexcept { return _data.size(); }
- size_type length() const noexcept { return _data.length(); }
- size_type max_size() const noexcept { return _data.max_size(); }
- bool empty() const noexcept { return _data.empty(); }
- // Element access
- const_reference operator[](size_type pos) const { return _data[pos]; }
- const_reference at(size_type pos) const { return _data.at(pos); }
- const_reference front() const { return _data.front(); }
- const_reference back() const { return _data.back(); }
- const_pointer data() const noexcept { return _data.data(); }
- // Modifiers
- void remove_prefix(size_type n) { _data.remove_prefix(n); }
- void remove_suffix(size_type n) { _data.remove_suffix(n); }
- void swap(life_string_view& other) noexcept {
- std::swap(_data, other._data);
- std::swap(_life, other._life);
- }
- // Operations
- size_type copy(char* dest, size_type count, size_type pos = 0) const {
- return _data.copy(dest, count, pos);
- }
- life_string_view substr(size_type pos = 0, size_type count = npos) const {
- return {_data.substr(pos, count), _life};
- }
- int compare(std::string_view sv) const noexcept { return _data.compare(sv); }
- // C++20
- #if __cpp_lib_starts_ends_with >= 201711L
- bool starts_with(std::string_view sv) const noexcept { return _data.starts_with(sv); }
- bool ends_with(std::string_view sv) const noexcept { return _data.ends_with(sv); }
- #endif
- // C++23
- #if __cpp_lib_string_contains >= 202011L
- bool contains(std::string_view sv) const noexcept { return _data.contains(sv); }
- #endif
- // Search
- size_type find(std::string_view sv, size_type pos = 0) const noexcept { return _data.find(sv, pos); }
- size_type rfind(std::string_view sv, size_type pos = npos) const noexcept { return _data.rfind(sv, pos); }
- size_type find_first_of(std::string_view sv, size_type pos = 0) const noexcept { return _data.find_first_of(sv, pos); }
- size_type find_last_of(std::string_view sv, size_type pos = npos) const noexcept { return _data.find_last_of(sv, pos); }
- size_type find_first_not_of(std::string_view sv, size_type pos = 0) const noexcept { return _data.find_first_not_of(sv, pos); }
- size_type find_last_not_of(std::string_view sv, size_type pos = npos) const noexcept { return _data.find_last_not_of(sv, pos); }
- // Three-way comparison (C++20)
- #if __cpp_impl_three_way_comparison >= 201907L
- auto operator<=>(const life_string_view& other) const noexcept = default;
- #endif
- // Comparison operators
- bool operator==(const life_string_view& other) const noexcept { return _data == other._data; }
- bool operator!=(const life_string_view& other) const noexcept { return _data != other._data; }
- bool operator< (const life_string_view& other) const noexcept { return _data < other._data; }
- bool operator<=(const life_string_view& other) const noexcept { return _data <= other._data; }
- bool operator> (const life_string_view& other) const noexcept { return _data > other._data; }
- bool operator>=(const life_string_view& other) const noexcept { return _data >= other._data; }
- // Stream output
- friend std::ostream& operator<<(std::ostream& os, const life_string_view& lsv) {
- return os << lsv._data;
- }
- };
Advertisement
Add Comment
Please, Sign In to add comment