1#ifndef MARISA_STRING_H_
2#define MARISA_STRING_H_
3
4#include "base.h"
5
6namespace marisa {
7
8class String {
9 public:
10  String() : ptr_(NULL), length_(0) {}
11  explicit String(const char *str) : ptr_(str), length_(0) {
12    while (str[length_] != '\0') {
13      ++length_;
14    }
15  }
16  String(const char *ptr, std::size_t length)
17      : ptr_(ptr), length_(length) {}
18  String(const String &str) : ptr_(str.ptr_), length_(str.length_) {}
19
20  String substr(std::size_t pos, std::size_t length) const {
21    MARISA_DEBUG_IF(pos + length > length_, MARISA_PARAM_ERROR);
22    return String(ptr_ + pos, length);
23  }
24
25  String &operator=(const String &str) {
26    ptr_ = str.ptr_;
27    length_ = str.length_;
28    return *this;
29  }
30
31  UInt8 operator[](std::size_t i) const {
32    MARISA_DEBUG_IF(i >= length_, MARISA_PARAM_ERROR);
33    return ptr_[i];
34  }
35
36  const char *ptr() const {
37    return ptr_;
38  }
39  std::size_t length() const {
40    return length_;
41  }
42
43 private:
44  const char *ptr_;
45  std::size_t length_;
46};
47
48inline bool operator==(const String &lhs, const String &rhs) {
49  if (lhs.length() != rhs.length()) {
50    return false;
51  }
52  for (std::size_t i = 0; i < lhs.length(); ++i) {
53    if (lhs[i] != rhs[i]) {
54      return false;
55    }
56  }
57  return true;
58}
59
60inline bool operator!=(const String &lhs, const String &rhs) {
61  return !(lhs == rhs);
62}
63
64inline bool operator<(const String &lhs, const String &rhs) {
65  for (std::size_t i = 0; i < lhs.length(); ++i) {
66    if (i == rhs.length()) {
67      return false;
68    }
69    if (lhs[i] != rhs[i]) {
70      return lhs[i] < rhs[i];
71    }
72  }
73  return lhs.length() < rhs.length();
74}
75
76inline bool operator>(const String &lhs, const String &rhs) {
77  return rhs < lhs;
78}
79
80class RString {
81 public:
82  RString()
83      : ptr_(static_cast<const char *>(NULL) - 1), length_(0) {}
84  explicit RString(const String &str)
85      : ptr_(str.ptr() + str.length() - 1), length_(str.length()) {}
86  RString(const RString &str)
87      : ptr_(str.ptr_), length_(str.length_) {}
88
89  RString substr(std::size_t pos, std::size_t length) const {
90    MARISA_DEBUG_IF(pos + length > length_, MARISA_PARAM_ERROR);
91    RString str(*this);
92    str.ptr_ -= pos;
93    str.length_ = length;
94    return str;
95  }
96
97  RString &operator=(const RString &str) {
98    ptr_ = str.ptr_;
99    length_ = str.length_;
100    return *this;
101  }
102
103  UInt8 operator[](std::size_t i) const {
104    MARISA_DEBUG_IF(i >= length_, MARISA_PARAM_ERROR);
105    return *(ptr_ - i);
106  }
107
108  const char *ptr() const {
109    return ptr_ - length_ + 1;
110  }
111  std::size_t length() const {
112    return length_;
113  }
114
115 private:
116  const char *ptr_;
117  std::size_t length_;
118};
119
120inline bool operator==(const RString &lhs, const RString &rhs) {
121  if (lhs.length() != rhs.length()) {
122    return false;
123  }
124  for (std::size_t i = 0; i < lhs.length(); ++i) {
125    if (lhs[i] != rhs[i]) {
126      return false;
127    }
128  }
129  return true;
130}
131
132inline bool operator!=(const RString &lhs, const RString &rhs) {
133  return !(lhs == rhs);
134}
135
136inline bool operator<(const RString &lhs, const RString &rhs) {
137  for (std::size_t i = 0; i < lhs.length(); ++i) {
138    if (i == rhs.length()) {
139      return false;
140    }
141    if (lhs[i] != rhs[i]) {
142      return lhs[i] < rhs[i];
143    }
144  }
145  return lhs.length() < rhs.length();
146}
147
148inline bool operator>(const RString &lhs, const RString &rhs) {
149  return rhs < lhs;
150}
151
152}  // namespace marisa
153
154#endif  // MARISA_STRING_H_
155