2012-04-14 03:17:09 +02:00
|
|
|
#ifndef string_hh_INCLUDED
|
|
|
|
#define string_hh_INCLUDED
|
|
|
|
|
|
|
|
#include <string>
|
2012-04-14 03:23:20 +02:00
|
|
|
#include <iosfwd>
|
2012-10-11 00:41:48 +02:00
|
|
|
#include <climits>
|
2012-08-29 21:49:36 +02:00
|
|
|
#include <boost/regex.hpp>
|
2012-04-14 03:23:20 +02:00
|
|
|
|
|
|
|
#include "memoryview.hh"
|
2012-08-23 23:56:35 +02:00
|
|
|
#include "units.hh"
|
2012-10-11 00:41:48 +02:00
|
|
|
#include "utf8.hh"
|
2012-04-14 03:17:09 +02:00
|
|
|
|
|
|
|
namespace Kakoune
|
|
|
|
{
|
|
|
|
|
2012-10-01 20:20:08 +02:00
|
|
|
typedef boost::regex Regex;
|
2012-04-14 03:23:20 +02:00
|
|
|
|
|
|
|
class String
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
String() {}
|
|
|
|
String(const char* content) : m_content(content) {}
|
2012-06-27 14:26:29 +02:00
|
|
|
String(std::string content) : m_content(std::move(content)) {}
|
|
|
|
String(const String& string) = default;
|
|
|
|
String(String&& string) = default;
|
2013-02-25 19:25:32 +01:00
|
|
|
explicit String(char content, CharCount count = 1) : m_content((size_t)(int)count, content) {}
|
2013-02-26 14:28:20 +01:00
|
|
|
explicit String(Codepoint cp, CharCount count = 1)
|
|
|
|
{
|
|
|
|
std::string str;
|
|
|
|
auto it = back_inserter(str);
|
|
|
|
utf8::dump(it, cp);
|
|
|
|
for (CharCount i = 0; i < count; ++i)
|
|
|
|
m_content += str;
|
|
|
|
}
|
2012-04-14 03:23:20 +02:00
|
|
|
template<typename Iterator>
|
|
|
|
String(Iterator begin, Iterator end) : m_content(begin, end) {}
|
|
|
|
|
2012-10-11 00:41:48 +02:00
|
|
|
char operator[](ByteCount pos) const { return m_content[(int)pos]; }
|
|
|
|
ByteCount length() const { return m_content.length(); }
|
|
|
|
CharCount char_length() const { return utf8::distance(begin(), end()); }
|
|
|
|
ByteCount byte_count_to(CharCount count) const { return utf8::advance(begin(), end(), (int)count) - begin(); }
|
|
|
|
CharCount char_count_to(ByteCount count) const { return utf8::distance(begin(), begin() + (int)count); }
|
2012-04-14 03:23:20 +02:00
|
|
|
bool empty() const { return m_content.empty(); }
|
|
|
|
|
|
|
|
bool operator== (const String& other) const { return m_content == other.m_content; }
|
|
|
|
bool operator!= (const String& other) const { return m_content != other.m_content; }
|
|
|
|
bool operator< (const String& other) const { return m_content < other.m_content; }
|
|
|
|
|
|
|
|
String& operator= (const String& other) { m_content = other.m_content; return *this; }
|
2012-06-27 14:26:29 +02:00
|
|
|
String& operator= (String&& other) { m_content = std::move(other.m_content); return *this; }
|
2012-04-14 03:23:20 +02:00
|
|
|
|
|
|
|
String operator+ (const String& other) const { return String(m_content + other.m_content); }
|
|
|
|
String& operator+= (const String& other) { m_content += other.m_content; return *this; }
|
|
|
|
|
2012-10-01 20:20:08 +02:00
|
|
|
String operator+ (char c) const { return String(m_content + c); }
|
|
|
|
String& operator+= (char c) { m_content += c; return *this; }
|
2012-04-14 03:23:20 +02:00
|
|
|
|
|
|
|
memoryview<char> data() const { return memoryview<char>(m_content.data(), m_content.size()); }
|
|
|
|
const char* c_str() const { return m_content.c_str(); }
|
|
|
|
|
2012-10-11 00:41:48 +02:00
|
|
|
String substr(ByteCount pos, ByteCount length = -1) const { return String(m_content.substr((int)pos, (int)length)); }
|
|
|
|
String substr(CharCount pos, CharCount length = INT_MAX) const
|
|
|
|
{
|
|
|
|
auto b = utf8::advance(begin(), end(), (int)pos);
|
|
|
|
auto e = utf8::advance(b, end(), (int)length);
|
|
|
|
return String(b,e);
|
|
|
|
}
|
2012-08-29 21:50:48 +02:00
|
|
|
String replace(const String& expression, const String& replacement) const;
|
2012-04-14 03:23:20 +02:00
|
|
|
|
2012-10-01 20:20:08 +02:00
|
|
|
using iterator = std::string::const_iterator;
|
2012-04-14 03:23:20 +02:00
|
|
|
|
2012-10-01 20:20:08 +02:00
|
|
|
iterator begin() const { return m_content.begin(); }
|
|
|
|
iterator end() const { return m_content.end(); }
|
2012-04-14 03:23:20 +02:00
|
|
|
|
2012-10-01 20:20:08 +02:00
|
|
|
char front() const { return m_content.front(); }
|
|
|
|
char back() const { return m_content.back(); }
|
2012-11-23 18:41:33 +01:00
|
|
|
char& front() { return m_content.front(); }
|
|
|
|
char& back() { return m_content.back(); }
|
2012-04-14 03:23:20 +02:00
|
|
|
|
2012-10-01 20:20:08 +02:00
|
|
|
size_t hash() const { return std::hash<std::string>()(m_content); }
|
2012-04-14 03:23:20 +02:00
|
|
|
|
|
|
|
inline friend std::ostream& operator<<(std::ostream& os, const String& str)
|
|
|
|
{
|
|
|
|
return os << str.m_content;
|
|
|
|
}
|
|
|
|
|
|
|
|
enum { npos = -1 };
|
|
|
|
|
|
|
|
private:
|
|
|
|
std::string m_content;
|
|
|
|
};
|
|
|
|
|
|
|
|
inline String operator+(const char* lhs, const String& rhs)
|
|
|
|
{
|
|
|
|
return String(lhs) + rhs;
|
|
|
|
}
|
|
|
|
|
2012-10-01 20:20:08 +02:00
|
|
|
inline String operator+(char lhs, const String& rhs)
|
2012-04-14 03:23:20 +02:00
|
|
|
{
|
|
|
|
return String(lhs) + rhs;
|
|
|
|
}
|
2012-04-14 03:17:09 +02:00
|
|
|
|
2012-05-29 07:19:50 +02:00
|
|
|
String int_to_str(int value);
|
2012-06-27 14:26:29 +02:00
|
|
|
int str_to_int(const String& str);
|
2012-10-01 20:20:08 +02:00
|
|
|
std::vector<String> split(const String& str, char separator);
|
2012-05-29 07:19:50 +02:00
|
|
|
|
2012-10-16 15:11:22 +02:00
|
|
|
inline String operator"" _str(const char* str, size_t)
|
|
|
|
{
|
|
|
|
return String(str);
|
|
|
|
}
|
|
|
|
|
2013-01-17 18:47:53 +01:00
|
|
|
inline String codepoint_to_str(Codepoint cp)
|
|
|
|
{
|
|
|
|
std::string str;
|
|
|
|
auto it = back_inserter(str);
|
|
|
|
utf8::dump(it, cp);
|
|
|
|
return String(str);
|
|
|
|
}
|
|
|
|
|
2012-04-14 03:17:09 +02:00
|
|
|
}
|
|
|
|
|
2012-04-14 03:23:20 +02:00
|
|
|
namespace std
|
|
|
|
{
|
2012-05-30 14:20:21 +02:00
|
|
|
template<>
|
|
|
|
struct hash<Kakoune::String>
|
|
|
|
{
|
|
|
|
size_t operator()(const Kakoune::String& str) const
|
|
|
|
{
|
|
|
|
return str.hash();
|
|
|
|
}
|
|
|
|
};
|
2012-04-14 03:23:20 +02:00
|
|
|
}
|
2012-04-14 03:17:09 +02:00
|
|
|
|
|
|
|
#endif // string_hh_INCLUDED
|
|
|
|
|