/* * Copyright 2015 - 2022 gary@drinkingtea.net * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ #pragma once #include "bit.hpp" #include "cstrops.hpp" #include "iterator.hpp" namespace ox::detail { class BaseStringView { public: template struct iterator: public Iterator { private: PtrType m_t = nullptr; std::size_t m_offset = 0; std::size_t m_max = 0; public: constexpr iterator() noexcept = default; constexpr iterator(PtrType t, std::size_t offset, std::size_t max) noexcept { m_t = t; m_offset = offset; m_max = max; } [[nodiscard]] constexpr auto offset() const noexcept { return m_offset; } constexpr iterator operator+(std::size_t s) const noexcept { if constexpr(reverse) { return iterator(m_t, max(m_offset - s, 0), m_max); } else { return iterator(m_t, min(m_offset + s, m_max), m_max); } } constexpr auto operator-(const iterator &other) const noexcept { if constexpr(reverse) { return m_offset + other.m_offset; } else { return m_offset - other.m_offset; } } constexpr iterator operator-(std::size_t s) const noexcept { if constexpr(reverse) { return iterator(m_t, min(m_offset + s, m_max), m_max); } else { return iterator(m_t, max(m_offset - s, 0), m_max); } } constexpr iterator &operator+=(std::size_t s) noexcept { if constexpr(reverse) { m_offset = max(m_offset - s, 0); } else { m_offset = min(m_offset + s, m_max); } return *this; } constexpr iterator &operator-=(std::size_t s) noexcept { if constexpr(reverse) { m_offset = min(m_offset + s, m_max); } else { m_offset = max(m_offset - s, 0); } return *this; } constexpr iterator &operator++() noexcept { return operator+=(1); } constexpr iterator &operator--() noexcept { return operator-=(1); } constexpr RefType operator*() const noexcept { return m_t[m_offset]; } constexpr RefType operator[](std::size_t s) const noexcept { return m_t[s]; } constexpr bool operator<(const iterator &other) const noexcept { return m_offset < other.m_offset; } constexpr bool operator>(const iterator &other) const noexcept { return m_offset > other.m_offset; } constexpr bool operator<=(const iterator &other) const noexcept { return m_offset <= other.m_offset; } constexpr bool operator>=(const iterator &other) const noexcept { return m_offset >= other.m_offset; } constexpr bool operator==(const iterator &other) const noexcept { return m_t == other.m_t && m_offset == other.m_offset && m_max == other.m_max; } constexpr bool operator!=(const iterator &other) const noexcept { return m_t != other.m_t || m_offset != other.m_offset || m_max != other.m_max; } }; private: const char *m_str = nullptr; std::size_t m_len = 0; protected: constexpr BaseStringView() noexcept = default; constexpr BaseStringView(BaseStringView const&sv) noexcept = default; constexpr explicit BaseStringView(std::nullptr_t) noexcept {} constexpr explicit BaseStringView(const char *str) noexcept: m_str(str), m_len(str ? ox_strlen(str) : 0) {} constexpr explicit BaseStringView(const char *str, std::size_t len) noexcept: m_str(str), m_len(len) {} public: [[nodiscard]] constexpr iterator begin() const noexcept { return {m_str, 0, m_len}; } [[nodiscard]] constexpr iterator end() const noexcept { return {m_str, m_len, m_len}; } [[nodiscard]] constexpr iterator cbegin() const noexcept { return {m_str, 0, m_len}; } [[nodiscard]] constexpr iterator cend() const noexcept { return {m_str, m_len, m_len}; } [[nodiscard]] constexpr iterator crbegin() const noexcept { return {m_str, m_len - 1, m_len}; } [[nodiscard]] constexpr iterator crend() const noexcept { return {m_str, MaxValue, m_len}; } [[nodiscard]] constexpr iterator rbegin() const noexcept { return {m_str, m_len - 1, m_len}; } [[nodiscard]] constexpr iterator rend() const noexcept { return {m_str, MaxValue, m_len}; } [[nodiscard]] constexpr auto bytes() const noexcept { return m_len; } [[nodiscard]] constexpr auto len() const noexcept { return m_len; } [[nodiscard]] constexpr auto *data() const noexcept { return &m_str[0]; } [[nodiscard]] constexpr auto &front() const noexcept { return m_str[0]; } [[nodiscard]] constexpr auto &back() const noexcept { return m_str[m_len - 1]; } [[nodiscard]] constexpr auto operator[](std::size_t i) const noexcept { return m_str[i]; } protected: constexpr void set(const char *str, std::size_t len) noexcept { m_str = str; m_len = len; } }; }