83 lines
3.0 KiB
Plaintext

#pragma once
#if !defined(BAD_APPLE_OS_STRING_VIEW_INCLUDED)
#define BAD_APPLE_OS_STRING_VIEW_INCLUDED
#include <limits>
#include <stdexcept>
#include <string>
namespace std
{
template<typename CharT, typename Traits = char_traits<CharT>>
class basic_string_view
{
public:
using traits_type = Traits;
using value_type = CharT;
using pointer = CharT*;
using const_pointer = const CharT*;
using reference = CharT&;
using const_reference = const CharT&;
using iterator = const CharT*;
using const_iterator = const CharT*;
// TODO: reverse iterators
using size_type = size_t;
using difference_type = ptrdiff_t;
private:
const_pointer _begin = nullptr;
const_pointer _end = nullptr;
public:
constexpr basic_string_view() noexcept = default;
constexpr basic_string_view(const basic_string_view&) noexcept = default;
constexpr basic_string_view(const_pointer s, size_type count) noexcept : _begin(s), _end(s + count) {}
constexpr basic_string_view(const_pointer s) noexcept : _begin(s), _end(s)
{
while (*_end) { ++_end; }
}
template<typename It, typename End>
constexpr basic_string_view(It first, End last) noexcept : _begin(first), _end(last) {}
constexpr basic_string_view(nullptr_t) = delete;
constexpr basic_string_view& operator=(const basic_string_view&) noexcept = default;
[[nodiscard]] constexpr iterator begin() const noexcept { return _begin; }
[[nodiscard]] constexpr const_iterator cbegin() const noexcept { return _begin; }
[[nodiscard]] constexpr iterator end() const noexcept { return _end; }
[[nodiscard]] constexpr const_iterator cend() const noexcept { return _end; }
// TODO: reverse iterators
[[nodiscard]] constexpr const_reference operator[](size_type pos) const noexcept { return _begin[pos]; }
[[nodiscard]] constexpr const_reference at(size_type pos) const
{
if (pos >= size()) {
__ba_throw out_of_range();
}
return _begin[pos];
}
[[nodiscard]] constexpr const_reference front() const noexcept { return *_begin; }
[[nodiscard]] constexpr const_reference back() const noexcept { return _end[-1]; }
[[nodiscard]] constexpr const_pointer data() const noexcept { return _begin; }
[[nodiscard]] constexpr size_type size() const noexcept { return _end - _begin; }
[[nodiscard]] constexpr size_type length() const noexcept { return _end - _begin; }
[[nodiscard]] constexpr size_type max_size() const noexcept { return numeric_limits<size_type>::max(); }
[[nodiscard]] constexpr bool empty() const noexcept { return size() == 0; }
constexpr void remove_prefix(size_type n) noexcept { _begin += n; }
constexpr void remove_suffix(size_type n) noexcept { _end -= n; }
constexpr void swap(basic_string_view& v) noexcept
{
swap(_begin, v._begin);
swap(_end, v._end);
}
};
using string_view = basic_string_view<char>;
using wstring_view = basic_string_view<wchar_t>;
}
#endif // !defined(BAD_APPLE_OS_STRING_VIEW_INCLUDED)