Created
May 11, 2022 03:03
-
-
Save klemens-morgenstern/fc02dab8b37fc77ac80efbca30f297cf to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// boost/utility/cstring_view.hpp | |
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
// | |
// Copyright (c) 2022 Klemens D. Morgenstern | |
// (klemens dot morgenstern at gmx dot net) | |
// | |
// Distributed under the Boost Software License, Version 1.0. (See accompanying | |
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
// | |
#ifndef BOOST_UTILITY_CSTRING_VIEW_HPP | |
#define BOOST_UTILITY_CSTRING_VIEW_HPP | |
#include <boost/core/detail/string_view.hpp> | |
#include <type_traits> | |
#include <limits> | |
namespace boost | |
{ | |
//based on http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1402r0.pdf | |
///cstring_view is simply a forwarding adapter around string_view. | |
/** Operations are delegated to a private member string_view, with some minor modifications | |
to the interface to maintain the null-terminated class invariant. */ | |
template<typename CharT, typename Traits = std::char_traits<CharT>> | |
struct basic_cstring_view | |
{ | |
using value_type = CharT; | |
using traits_type = Traits; | |
BOOST_CONSTEXPR basic_cstring_view() : view_(null_char_(value_type{})) {}; | |
BOOST_CONSTEXPR basic_cstring_view(std::nullptr_t) = delete; | |
BOOST_CONSTEXPR basic_cstring_view( const value_type* s ) : view_(s) {} | |
template<typename Source, | |
typename = | |
typename std::enable_if< | |
std::is_same<const value_type, | |
typename std::remove_pointer<decltype(std::declval<Source>().c_str())>::type | |
>::value>::type> | |
BOOST_CONSTEXPR basic_cstring_view(Source && src) : view_(src.c_str()) {} | |
BOOST_CONSTEXPR typename std::basic_string_view<value_type, Traits>::const_pointer c_str() const BOOST_NOEXCEPT | |
{ | |
return this->data(); | |
} | |
using string_view_type = basic_string_view<value_type, Traits>; | |
operator string_view_type() const {return view_;} | |
using pointer = CharT *; | |
using const_pointer = const CharT *; | |
using reference = CharT &; | |
using const_reference = const CharT &; | |
using const_iterator = const_pointer; | |
using iterator = const_iterator; | |
using const_reverse_iterator = typename std::reverse_iterator<const_iterator>; | |
using reverse_iterator = typename std::reverse_iterator<iterator>; | |
using size_type = std::size_t; | |
using difference_type = std::ptrdiff_t; | |
static BOOST_CONSTEXPR size_type npos = -1; | |
BOOST_CONSTEXPR const_iterator begin() const BOOST_NOEXCEPT {return view_;}; | |
BOOST_CONSTEXPR const_iterator end() const BOOST_NOEXCEPT {return view_ + length();}; | |
BOOST_CONSTEXPR const_iterator cbegin() const BOOST_NOEXCEPT {return view_;}; | |
BOOST_CONSTEXPR const_iterator cend() const BOOST_NOEXCEPT {return view_ + length();}; | |
BOOST_CONSTEXPR const_reverse_iterator rbegin() const BOOST_NOEXCEPT {return std::make_reverse_iterator(view_ + length());}; | |
BOOST_CONSTEXPR const_reverse_iterator rend() const BOOST_NOEXCEPT {return std::make_reverse_iterator(view_);}; | |
BOOST_CONSTEXPR const_reverse_iterator crbegin() const BOOST_NOEXCEPT {return std::make_reverse_iterator(view_ + length());}; | |
BOOST_CONSTEXPR const_reverse_iterator crend() const BOOST_NOEXCEPT {return std::make_reverse_iterator(view_);}; | |
BOOST_CONSTEXPR size_type size() const BOOST_NOEXCEPT {return length(); } | |
BOOST_CONSTEXPR size_type length() const BOOST_NOEXCEPT {return traits_type::length(view_); } | |
BOOST_CONSTEXPR size_type max_size() const BOOST_NOEXCEPT {return std::numeric_limits<int64_t>::max() / sizeof(CharT); } | |
BOOST_ATTRIBUTE_NODISCARD BOOST_CONSTEXPR bool empty() const BOOST_NOEXCEPT {return *view_ == *null_char_(CharT{}); } | |
BOOST_CONSTEXPR const_reference operator[](size_type pos) const {return view_[pos] ;} | |
BOOST_CONSTEXPR const_reference at(size_type pos) const | |
{ | |
if (pos >= size()) | |
throw std::out_of_range("cstring-view out of range"); | |
return view_[pos]; | |
} | |
BOOST_CONSTEXPR const_reference front() const {return *view_;} | |
BOOST_CONSTEXPR const_reference back() const {return view_[length() - 1];} | |
BOOST_CONSTEXPR const_pointer data() const BOOST_NOEXCEPT {return view_;} | |
BOOST_CONSTEXPR void remove_prefix(size_type n) {view_ = view_ + n;} | |
BOOST_CONSTEXPR void swap(basic_cstring_view& s) BOOST_NOEXCEPT {std::swap(view_, s.view_);} | |
BOOST_CONSTEXPR size_type copy(value_type* s, size_type n, size_type pos = 0) const | |
{ | |
return traits_type::copy(s, view_ + pos, n) - view_; | |
} | |
BOOST_CONSTEXPR basic_cstring_view substr(size_type pos = 0) const | |
{ | |
return basic_cstring_view(view_ + pos); | |
} | |
BOOST_CONSTEXPR string_view_type substr(size_type pos , size_type n) const {return string_view_type(view_+ pos, n);} | |
BOOST_CONSTEXPR int compare(string_view_type s) const BOOST_NOEXCEPT | |
{ | |
return traits_type::compare(view_, s.data(), std::min(length(), s.length())); | |
} | |
BOOST_CONSTEXPR int compare(size_type pos1, size_type n1, string_view_type s) const | |
{ | |
return traits_type::compare(view_ + pos1, s.data(), std::min(n1, s.length())); | |
} | |
BOOST_CONSTEXPR int compare(size_type pos1, size_type n1, string_view_type s, size_type pos2, size_type n2) const | |
{ | |
return traits_type::compare(view_ + pos1, s.data() + pos2, std::min(n1, n2)); | |
} | |
#if (__cplusplus >= 202002) | |
BOOST_CONSTEXPR bool starts_with(string_view_type x) const BOOST_NOEXCEPT | |
{ | |
return std::equal(view_, view_ + x.size(), x.begin(), x.end(), &traits_type::eq); | |
} | |
BOOST_CONSTEXPR bool starts_with(value_type x) const BOOST_NOEXCEPT | |
{ | |
return traits_type::eq(view_[0], x); | |
} | |
BOOST_CONSTEXPR bool ends_with(string_view_type x) const BOOST_NOEXCEPT | |
{ | |
return std::equal(view_ + x.size() - length(), view_ + length(), x.begin(), x.end(), &traits_type::eq); | |
} | |
BOOST_CONSTEXPR bool ends_with(value_type x) const BOOST_NOEXCEPT | |
{ | |
return !empty() && traits_type::eq(view_[length() - 1], x); | |
} | |
#endif | |
BOOST_CONSTEXPR size_type find(basic_cstring_view s, size_type pos = 0) const BOOST_NOEXCEPT | |
{ | |
const auto e = end(); | |
const auto itr = std::search(begin(), e, s.begin(), s.end(), &traits_type::eq); | |
return (itr != e) ? (itr - begin()) : npos; | |
} | |
BOOST_CONSTEXPR size_type find(value_type c, size_type pos = 0) const BOOST_NOEXCEPT | |
{ | |
const auto e = end(); | |
const auto itr = std::find_if(begin(), e, [c](value_type cc) {return traits_type::eq(c, cc);}); | |
return (itr != e) ? (itr - begin()) : npos; | |
} | |
BOOST_CONSTEXPR size_type rfind(basic_cstring_view s, size_type pos = npos) const BOOST_NOEXCEPT | |
{ | |
const auto b = rbegin(); | |
const auto itr = std::search(b, rend(), s.rbegin(), s.rend(), &traits_type::eq); | |
return (itr != rend()) ? (itr - b) : npos; | |
} | |
BOOST_CONSTEXPR size_type rfind(value_type c, size_type pos = npos) const BOOST_NOEXCEPT | |
{ | |
const auto b = rbegin(); | |
const auto itr = std::find_if(b, rend(), [c](value_type cc) {return traits_type::eq(c, cc);}); | |
return (itr != rend()) ? (itr - b) : npos; | |
} | |
friend BOOST_CONSTEXPR bool operator==(basic_cstring_view x, basic_cstring_view y) BOOST_NOEXCEPT {return x.compare(y) == 0;} | |
friend BOOST_CONSTEXPR bool operator!=(basic_cstring_view x, basic_cstring_view y) BOOST_NOEXCEPT {return x.compare(y) != 0;} | |
friend BOOST_CONSTEXPR bool operator< (basic_cstring_view x, basic_cstring_view y) BOOST_NOEXCEPT {return x.compare(y) < 0;} | |
friend BOOST_CONSTEXPR bool operator> (basic_cstring_view x, basic_cstring_view y) BOOST_NOEXCEPT {return x.compare(y) > 0;} | |
friend BOOST_CONSTEXPR bool operator<=(basic_cstring_view x, basic_cstring_view y) BOOST_NOEXCEPT {return x.compare(y) <= 0;} | |
friend BOOST_CONSTEXPR bool operator>=(basic_cstring_view x, basic_cstring_view y) BOOST_NOEXCEPT {return x.compare(y) >= 0;} | |
private: | |
friend struct std::hash<basic_cstring_view>; | |
BOOST_CONSTEXPR static const_pointer null_char_() {return null_char_(CharT{});} | |
BOOST_CONSTEXPR static const char* null_char_(char) {return "\0";} | |
BOOST_CONSTEXPR static const wchar_t* null_char_(wchar_t) {return L"\0";} | |
BOOST_CONSTEXPR static const char16_t* null_char_(char16_t) {return u"\0";} | |
BOOST_CONSTEXPR static const char32_t* null_char_(char32_t) {return U"\0";} | |
#if ASIO_HAS_CHAR8_T | |
BOOST_CONSTEXPR static const char8_t* null_char_(char8_t) {return u8"\0";} | |
#endif | |
const_pointer view_; | |
}; | |
using cstring_view = basic_cstring_view<char>; | |
using wcstring_view = basic_cstring_view<wchar_t>; | |
#if !defined(BOOST_NO_CXX11_CHAR16_T) | |
using u16cstring_view = basic_cstring_view<char16_t>; | |
#endif | |
#if !defined(BOOST_NO_CXX11_CHAR32_T) | |
using u32cstring_view = basic_cstring_view<char32_t>; | |
#endif | |
#if defined(__cpp_char8_t) && __cpp_char8_t >= 201811L | |
using u8cstring_view = basic_cstring_view<char8_t>; | |
#endif | |
} | |
#endif //BOOST_UTILITY_CSTRING_VIEW_HPP |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment