219 lines
		
	
	
		
			6.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			219 lines
		
	
	
		
			6.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
// -*-c++-*-
 | 
						|
// vim: set ft=cpp:
 | 
						|
 | 
						|
/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
 | 
						|
   file Copyright.txt 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 = const char*;
 | 
						|
  using reference = char&;
 | 
						|
  using const_reference = char const&;
 | 
						|
  using const_iterator = const char*;
 | 
						|
  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(const char* s, size_t count) noexcept
 | 
						|
    : data_(s)
 | 
						|
    , size_(count)
 | 
						|
  {
 | 
						|
  }
 | 
						|
 | 
						|
  string_view(const char* 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(const char* s) const;
 | 
						|
  int compare(size_type pos1, size_type count1, const char* s) const;
 | 
						|
  int compare(size_type pos1, size_type count1, const char* 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(const char* s, size_type pos, size_type count) const;
 | 
						|
  size_type find(const char* 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(const char* s, size_type pos, size_type count) const;
 | 
						|
  size_type rfind(const char* 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(const char* s, size_type pos, size_type count) const;
 | 
						|
  size_type find_first_of(const char* 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(const char* s, size_type pos, size_type count) const;
 | 
						|
  size_type find_last_of(const char* 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(const char* s, size_type pos,
 | 
						|
                              size_type count) const;
 | 
						|
  size_type find_first_not_of(const char* 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(const char* s, size_type pos,
 | 
						|
                             size_type count) const;
 | 
						|
  size_type find_last_not_of(const char* s, size_type pos = npos) const;
 | 
						|
 | 
						|
private:
 | 
						|
  const char* 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
 |