1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218
|
// -*-c++-*-
// vim: set ft=cpp:
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file LICENSE.rst or https://cmake.org/licensing for details. */
#pragma once
#if __cplusplus >= 201703L || defined(_MSVC_LANG) && _MSVC_LANG >= 201703L
# define CMake_HAVE_CXX_STRING_VIEW
#endif
#include <cm/bits/container_helpers.hxx> // IWYU pragma: export
#ifdef CMake_HAVE_CXX_STRING_VIEW
# include <string_view> // IWYU pragma: export
namespace cm {
using std::string_view;
}
#else
# include <cstddef>
# include <functional>
# include <iosfwd>
# include <iterator>
# include <string>
namespace cm {
class string_view
{
public:
using traits_type = std::string::traits_type;
using value_type = char;
using pointer = char*;
using const_pointer = char const*;
using reference = char&;
using const_reference = char const&;
using const_iterator = char const*;
using iterator = const_iterator;
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
using reverse_iterator = const_reverse_iterator;
using size_type = std::string::size_type;
using difference_type = std::string::difference_type;
static size_type const npos = static_cast<size_type>(-1);
string_view() noexcept = default;
string_view(string_view const&) noexcept = default;
string_view(char const* s, size_t count) noexcept
: data_(s)
, size_(count)
{
}
string_view(char const* s) noexcept
: data_(s)
, size_(traits_type::length(s))
{
}
// C++17 does not define this constructor. Instead it defines
// a conversion operator on std::string to create a string_view.
// Since this implementation is used in C++11, std::string does
// not have that conversion.
string_view(std::string const& s) noexcept
: data_(s.data())
, size_(s.size())
{
}
// C++17 does not define this conversion. Instead it defines
// a constructor on std::string that can take a string_view.
// Since this implementation is used in C++11, std::string does
// not have that constructor.
explicit operator std::string() const { return std::string(data_, size_); }
string_view& operator=(string_view const&) = default;
const_iterator begin() const noexcept { return data_; }
const_iterator end() const noexcept { return data_ + size_; }
const_iterator cbegin() const noexcept { return begin(); }
const_iterator cend() const noexcept { return end(); }
const_reverse_iterator rbegin() const noexcept
{
return const_reverse_iterator(end());
}
const_reverse_iterator rend() const noexcept
{
return const_reverse_iterator(begin());
}
const_reverse_iterator crbegin() const noexcept { return rbegin(); }
const_reverse_iterator crend() const noexcept { return rend(); }
const_reference operator[](size_type pos) const noexcept
{
return data_[pos];
}
const_reference at(size_type pos) const;
const_reference front() const noexcept { return data_[0]; }
const_reference back() const noexcept { return data_[size_ - 1]; }
const_pointer data() const noexcept { return data_; }
size_type size() const noexcept { return size_; }
size_type length() const noexcept { return size_; }
size_type max_size() const noexcept { return npos - 1; }
bool empty() const noexcept { return size_ == 0; }
void remove_prefix(size_type n) noexcept
{
data_ += n;
size_ -= n;
}
void remove_suffix(size_type n) noexcept { size_ -= n; }
void swap(string_view& v) noexcept
{
string_view tmp = v;
v = *this;
*this = tmp;
}
size_type copy(char* dest, size_type count, size_type pos = 0) const;
string_view substr(size_type pos = 0, size_type count = npos) const;
int compare(string_view v) const noexcept;
int compare(size_type pos1, size_type count1, string_view v) const;
int compare(size_type pos1, size_type count1, string_view v, size_type pos2,
size_type count2) const;
int compare(char const* s) const;
int compare(size_type pos1, size_type count1, char const* s) const;
int compare(size_type pos1, size_type count1, char const* s,
size_type count2) const;
size_type find(string_view v, size_type pos = 0) const noexcept;
size_type find(char c, size_type pos = 0) const noexcept;
size_type find(char const* s, size_type pos, size_type count) const;
size_type find(char const* s, size_type pos = 0) const;
size_type rfind(string_view v, size_type pos = npos) const noexcept;
size_type rfind(char c, size_type pos = npos) const noexcept;
size_type rfind(char const* s, size_type pos, size_type count) const;
size_type rfind(char const* s, size_type pos = npos) const;
size_type find_first_of(string_view v, size_type pos = 0) const noexcept;
size_type find_first_of(char c, size_type pos = 0) const noexcept;
size_type find_first_of(char const* s, size_type pos, size_type count) const;
size_type find_first_of(char const* s, size_type pos = 0) const;
size_type find_last_of(string_view v, size_type pos = npos) const noexcept;
size_type find_last_of(char c, size_type pos = npos) const noexcept;
size_type find_last_of(char const* s, size_type pos, size_type count) const;
size_type find_last_of(char const* s, size_type pos = npos) const;
size_type find_first_not_of(string_view v, size_type pos = 0) const noexcept;
size_type find_first_not_of(char c, size_type pos = 0) const noexcept;
size_type find_first_not_of(char const* s, size_type pos,
size_type count) const;
size_type find_first_not_of(char const* s, size_type pos = 0) const;
size_type find_last_not_of(string_view v,
size_type pos = npos) const noexcept;
size_type find_last_not_of(char c, size_type pos = npos) const noexcept;
size_type find_last_not_of(char const* s, size_type pos,
size_type count) const;
size_type find_last_not_of(char const* s, size_type pos = npos) const;
private:
char const* data_ = nullptr;
size_type size_ = 0;
};
std::ostream& operator<<(std::ostream& o, string_view v);
std::string& operator+=(std::string& s, string_view v);
inline bool operator==(string_view l, string_view r) noexcept
{
return l.compare(r) == 0;
}
inline bool operator!=(string_view l, string_view r) noexcept
{
return l.compare(r) != 0;
}
inline bool operator<(string_view l, string_view r) noexcept
{
return l.compare(r) < 0;
}
inline bool operator<=(string_view l, string_view r) noexcept
{
return l.compare(r) <= 0;
}
inline bool operator>(string_view l, string_view r) noexcept
{
return l.compare(r) > 0;
}
inline bool operator>=(string_view l, string_view r) noexcept
{
return l.compare(r) >= 0;
}
}
namespace std {
template <>
struct hash<cm::string_view>
{
using argument_type = cm::string_view;
using result_type = size_t;
result_type operator()(argument_type const& s) const noexcept;
};
}
#endif
|