summaryrefslogtreecommitdiff
path: root/src/string.hh
blob: fb80d4253c630441822b4387528afb09b2aa5fdd (plain)
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
#ifndef string_hh_INCLUDED
#define string_hh_INCLUDED

#include "memoryview.hh"
#include "units.hh"
#include "utf8.hh"

#include <string>
#include <boost/regex.hpp>

namespace Kakoune
{

typedef boost::regex Regex;

class String : public std::string
{
public:
   String() {}
   String(const char* content) : std::string(content) {}
   String(std::string content) : std::string(std::move(content)) {}
   explicit String(char content, CharCount count = 1) : std::string((size_t)(int)count, content) {}
   explicit String(Codepoint cp, CharCount count = 1)
   {
       while (count-- > 0)
           utf8::dump(back_inserter(*this), cp);
   }
   template<typename Iterator>
   String(Iterator begin, Iterator end) : std::string(begin, end) {}

   std::string& stdstr() { return *this; }
   const std::string& stdstr() const { return *this; }

   char      operator[](ByteCount pos) const { return std::string::operator[]((int)pos); }
   char&     operator[](ByteCount pos) { return std::string::operator[]((int)pos); }
   ByteCount length() const { return ByteCount{(int)std::string::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); }

   String  operator+(const String& other) const { return String{stdstr() + other.stdstr()}; }
   String& operator+=(const String& other) { std::string::operator+=(other); return *this; }
   String  operator+(const char* other) const { return String{stdstr() + other}; }
   String& operator+=(const char* other) { std::string::operator+=(other); return *this; }
   String  operator+(char other) const { return String{stdstr() + other}; }
   String& operator+=(char other) { std::string::operator+=(other); return *this; }
   String  operator+(Codepoint cp) const { String res = *this; utf8::dump(back_inserter(res), cp); return res; }
   String& operator+=(Codepoint cp) { utf8::dump(back_inserter(*this), cp); return *this; }

   memoryview<char> data()  const { return memoryview<char>(std::string::data(), size()); }

   String substr(ByteCount pos, ByteCount length = -1) const { return String{std::string::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);
   }
   String replace(const Regex& expression, const String& replacement) const;
};

inline String operator+(const char* lhs, const String& rhs)
{
    return String(lhs) + rhs;
}

inline String operator+(const std::string& lhs, const String& rhs)
{
    return String(lhs) + rhs;
}

inline String operator+(const String& lhs, const std::string& rhs)
{
    return lhs + String(rhs);
}

inline String operator+(char lhs, const String& rhs)
{
    return String(lhs) + rhs;
}

inline String operator+(Codepoint lhs, const String& rhs)
{
    return String(lhs) + rhs;
}

std::vector<String> split(const String& str, char separator);

inline String operator"" _str(const char* str, size_t)
{
    return String(str);
}

inline String codepoint_to_str(Codepoint cp)
{
    std::string str;
    utf8::dump(back_inserter(str), cp);
    return String(str);
}

String option_to_string(const Regex& re);
void option_from_string(const String& str, Regex& re);

int str_to_int(const String& str);

using std::to_string;

template<typename RealType, typename ValueType>
std::string to_string(const StronglyTypedNumber<RealType, ValueType>& val)
{
    return to_string((ValueType)val);
}

}

namespace std
{
    template<>
    struct hash<Kakoune::String> : hash<std::string>
    {
        size_t operator()(const Kakoune::String& str) const
        {
            return hash<std::string>::operator()(str);
        }
    };
}

#endif // string_hh_INCLUDED