aboutsummaryrefslogtreecommitdiff
path: root/include/cru/common/String.hpp
blob: c8defd13cc3c25aa2a2341b5c1cae9ea7d18af3a (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
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
#pragma once

#include <vcruntime.h>
#include "Base.hpp"

#include <cstdint>
#include <iterator>

namespace cru {
class CRU_BASE_API String {
 public:
  static String FromUtf8(std::string_view str) {
    return FromUtf8(str.data(), str.size());
  }
  static String FromUtf8(const char* str, Index size);

  static String FromUtf16(const std::uint16_t* str) { return String(str); }
  static String FromUtf16(const std::uint16_t* str, Index size) {
    return String(str, size);
  }

  static String FromUtf16(const char16_t* str) { return String(str); }
  static String FromUtf16(const char16_t* str, Index size) {
    return String(str, size);
  }

#ifdef CRU_PLATFORM_WINDOWS
  static String FromUtf16(wchar_t* str) { return String(str); }
  static String FromUtf16(wchar_t* str, Index size) {
    return String(str, size);
  }
#endif

 public:
  using value_type = std::uint16_t;
  using size_type = Index;
  using difference_type = Index;
  using reference = std::uint16_t&;
  using const_reference = const std::uint16_t&;
  using pointer = std::uint16_t*;
  using const_pointer = const std::uint16_t*;
  using iterator = std::uint16_t*;
  using const_iterator = const std::uint16_t*;
  using reverse_iterator = std::reverse_iterator<iterator>;
  using const_reverse_iterator = std::reverse_iterator<const_iterator>;

 public:
  String() = default;

  String(const std::uint16_t* str);
  String(const std::uint16_t* str, Index size);

  String(const char16_t* str);
  String(const char16_t* str, Index size);
  String(const std::u16string& str) : String(str.data(), str.size()) {}

#ifdef CRU_PLATFORM_WINDOWS
  String(const wchar_t* str);
  String(const wchar_t* str, Index size);
  String(const std::wstring& str) : String(str.data(), str.size()) {}
#endif

  String(const String& other);
  String(String&& other) noexcept;

  String& operator=(const String& other);
  String& operator=(String&& other) noexcept;

  ~String();

 public:
  bool empty() const { return this->size_ == 0; }
  Index size() const { return this->size_; }
  Index length() const { return this->size(); }
  Index capacity() const { return this->capacity_; }
  std::uint16_t* data() { return this->buffer_; }

  void reserve(Index new_capacity);

  std::uint16_t& front() { return this->operator[](0); }
  const std::uint16_t& front() const { return this->operator[](0); }

  std::uint16_t& back() { return this->operator[](size_ - 1); }
  const std::uint16_t& back() const { return this->operator[](size_ - 1); }

  const std::uint16_t* c_str() const { return buffer_; }

  std::uint16_t& operator[](Index index) { return buffer_[index]; }
  const std::uint16_t& operator[](Index index) const { return buffer_[index]; }

 public:
  iterator begin() { return this->buffer_; }
  const_iterator begin() const { return this->buffer_; }
  const_iterator cbegin() const { return this->buffer_; }

  iterator end() { return this->buffer_ + this->size_; }
  const_iterator end() const { return this->buffer_ + this->size_; }
  const_iterator cend() const { return this->buffer_ + this->size_; }

  reverse_iterator rbegin() { return reverse_iterator{begin()}; }
  const_reverse_iterator rbegin() const {
    return const_reverse_iterator{begin()};
  }
  const_reverse_iterator crbegin() const {
    return const_reverse_iterator{cbegin()};
  }

  reverse_iterator rend() { return reverse_iterator{end()}; }
  const_reverse_iterator rend() const { return const_reverse_iterator{end()}; }
  const_reverse_iterator crend() const {
    return const_reverse_iterator{cend()};
  }

 public:
  void clear();
  iterator insert(const_iterator pos, std::uint16_t value) {
    return this->insert(pos, &value, 1);
  }
  iterator insert(const_iterator pos, std::uint16_t* str, Index size);
  iterator erase(const_iterator pos) { return this->erase(pos, pos + 1); }
  iterator erase(const_iterator start, const_iterator end);
  void push_back(std::uint16_t value) { this->append(value); }
  void pop_back() { this->erase(cend() - 1); }
  void append(std::uint16_t value) { this->insert(cend(), value); }
  void append(std::uint16_t* str, Index size) {
    this->insert(cend(), str, size);
  }

 public:
  const char16_t* Char16CStr() const {
    return reinterpret_cast<const char16_t*>(c_str());
  }

#ifdef CRU_PLATFORM_WINDOWS
  const wchar_t* WinCStr() const {
    return reinterpret_cast<const wchar_t*>(c_str());
  }
#endif

  std::string ToUtf8() const;

  int Compare(const String& other) const;

 private:
  static std::uint16_t kEmptyBuffer[1];

 private:
  std::uint16_t* buffer_ = kEmptyBuffer;
  Index size_ = 0;      // not including trailing '\0'
  Index capacity_ = 0;  // always 1 smaller than real buffer size
};

CRU_DEFINE_COMPARE_OPERATORS(String)

}  // namespace cru