Skip to content

Commit c601afa

Browse files
feat: several improvements and functions
1 parent eddf503 commit c601afa

File tree

5 files changed

+300
-250
lines changed

5 files changed

+300
-250
lines changed

CMakeLists.txt

+4-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ set(CMAKE_CXX_STANDARD 20)
44
include(GNUInstallDirs)
55

66
add_library(${PROJECT_NAME} INTERFACE)
7-
target_sources(${PROJECT_NAME} INTERFACE "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include/cstringpp.hpp>")
7+
target_sources(${PROJECT_NAME} INTERFACE
8+
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include/cstringpp/core.hpp>"
9+
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include/cstringpp/helpers.hpp>"
10+
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include/cstringpp.hpp>")
811
target_include_directories(${PROJECT_NAME} SYSTEM INTERFACE $<INSTALL_INTERFACE:$<INSTALL_PREFIX>/include>)
912

1013
option(CSTRINGPP_BUILD_TESTS "Build test program for CStringPP" OFF)

include/cstringpp.hpp

+2-226
Original file line numberDiff line numberDiff line change
@@ -1,228 +1,4 @@
11
#pragma once
22

3-
#include <cstddef>
4-
#include <cstring>
5-
#include <array>
6-
#include <compare>
7-
#include <utility>
8-
9-
namespace cstringpp {
10-
11-
template<size_t Length>
12-
class String {
13-
public:
14-
/// Strings are assumed to be null-terminated
15-
constexpr explicit String(const char(&str)[Length]) {
16-
for (size_t i = 0; i < Length; i++) {
17-
m_str[i] = str[i];
18-
}
19-
}
20-
21-
/// Strings are assumed to be null-terminated
22-
constexpr explicit String(const std::array<char, Length>& ary) {
23-
std::copy(ary.begin(), ary.end(), m_str.begin());
24-
}
25-
26-
constexpr String(const String<Length>& other) {
27-
std::copy(other.m_str.begin(), other.m_str.end(), m_str.begin());
28-
}
29-
30-
constexpr String& operator=(const String<Length> other) {
31-
std::copy(other.m_str.begin(), other.m_str.end(), m_str.begin());
32-
return *this;
33-
}
34-
35-
constexpr String(String<Length>&& other) noexcept {
36-
std::move(other.m_str.begin(), other.m_str.end(), m_str.begin());
37-
}
38-
39-
constexpr String& operator=(String<Length>&& other) noexcept {
40-
std::move(other.m_str.begin(), other.m_str.end(), m_str.begin());
41-
return *this;
42-
}
43-
44-
~String() = default;
45-
46-
[[nodiscard]] constexpr const char* toCString() const {
47-
return m_str.data();
48-
}
49-
50-
[[nodiscard]] constexpr char operator[](size_t index) const {
51-
return m_str.at(index);
52-
}
53-
54-
template<int Start, int End = -1>
55-
[[nodiscard]] constexpr auto slice() const {
56-
// A necessity to wrap this in a function sadly
57-
constexpr auto getPositiveIndex = [](int index) -> int {
58-
while (index < 0) {
59-
index += Length;
60-
}
61-
while (index >= Length) {
62-
index -= Length;
63-
}
64-
return index;
65-
};
66-
constexpr int startIndex = getPositiveIndex(Start);
67-
constexpr int endIndex = getPositiveIndex(End);
68-
constexpr int newLength = endIndex - startIndex;
69-
70-
if constexpr (endIndex <= startIndex) {
71-
return String<1>{""};
72-
} else {
73-
std::array<char, newLength + 1> result;
74-
std::copy(m_str.begin() + startIndex, m_str.begin() + endIndex, result.begin());
75-
result[newLength] = 0;
76-
return String<newLength + 1>{result};
77-
}
78-
}
79-
80-
[[nodiscard]] constexpr auto operator<=>(const String& other) const = default;
81-
82-
[[nodiscard]] constexpr bool operator==(const String& other) const = default;
83-
84-
[[nodiscard]] constexpr size_t size() const noexcept {
85-
return Length;
86-
}
87-
88-
[[nodiscard]] constexpr size_t length() const noexcept {
89-
return Length;
90-
}
91-
92-
[[nodiscard]] constexpr auto begin() const noexcept {
93-
return m_str.begin();
94-
}
95-
96-
[[nodiscard]] constexpr auto end() const noexcept {
97-
return m_str.end();
98-
}
99-
100-
protected:
101-
std::array<char, Length> m_str{};
102-
};
103-
104-
[[nodiscard]] constexpr int toLower(char in) {
105-
if (in >= 'A' && in <= 'Z') {
106-
return in + 32;
107-
}
108-
return in;
109-
}
110-
111-
[[nodiscard]] constexpr int toUpper(char in) {
112-
if (in >= 'a' && in <= 'z') {
113-
return in - 32;
114-
}
115-
return in;
116-
}
117-
118-
template<size_t... Lengths>
119-
[[nodiscard]] constexpr auto strcat(const String<Lengths>&... strings) {
120-
// We need to strip null terminators from every string except the last
121-
// Also resize the result array so it doesn't have extra chars at the end
122-
constexpr int NumArgsMinus1 = (Lengths + ...) + 1 - [] {
123-
int numArgs = 0;
124-
((Lengths, numArgs++), ...);
125-
return numArgs;
126-
}();
127-
std::array<char, NumArgsMinus1> result;
128-
size_t index = 0;
129-
((std::copy_n(strings.begin(), Lengths, result.begin() + index), index += Lengths - 1), ...);
130-
return String<NumArgsMinus1>{result};
131-
}
132-
133-
template<size_t Length1, size_t Length2>
134-
[[nodiscard]] constexpr int strcmp(const String<Length1>& str1, const String<Length2>& str2) {
135-
for (int i = 0; i < Length1 && i < Length2; i++) {
136-
char c1 = str1[i], c2 = str2[i];
137-
if (c1 != c2) {
138-
return c1 - c2;
139-
}
140-
}
141-
return 0;
142-
}
143-
144-
template<size_t Length1, size_t Length2>
145-
[[nodiscard]] constexpr int stricmp(const String<Length1>& str1, const String<Length2>& str2) {
146-
for (int i = 0; i < Length1 && i < Length2; i++) {
147-
char c1 = toLower(str1[i]), c2 = toLower(str2[i]);
148-
if (c1 != c2) {
149-
return c1 - c2;
150-
}
151-
}
152-
return 0;
153-
}
154-
155-
template<size_t Length>
156-
[[nodiscard]] constexpr int strchr(const String<Length>& str, char needle, int occurence = 0) {
157-
int seen = 0;
158-
for (int i = 0; i < Length; i++) {
159-
if (str[i] == needle && seen++ == occurence ) {
160-
return i;
161-
}
162-
}
163-
return -1;
164-
}
165-
166-
template<size_t Length>
167-
[[nodiscard]] constexpr int strrchr(const String<Length>& str, char needle, int occurence = 0) {
168-
int seen = 0;
169-
for (int i = Length - 1; i >= 0; i--) {
170-
if (str[i] == needle && seen++ == occurence ) {
171-
return i;
172-
}
173-
}
174-
return -1;
175-
}
176-
177-
template<size_t Length1, size_t Length2>
178-
[[nodiscard]] constexpr int strstr(const String<Length1>& str, const String<Length2>& find) {
179-
if ((Length1 < Length2) || (Length1 == Length2 && str != find))
180-
return -1;
181-
//todo
182-
}
183-
184-
template<size_t Length1, size_t Length2>
185-
[[nodiscard]] constexpr int strrstr(const String<Length1>& str, const String<Length2>& find) {
186-
if ((Length1 < Length2) || (Length1 == Length2 && str != find))
187-
return -1;
188-
//todo
189-
}
190-
191-
template<size_t Length>
192-
[[nodiscard]] constexpr inline auto strdup(const String<Length>& str) {
193-
return String{str};
194-
}
195-
196-
template<size_t Length>
197-
[[nodiscard]] constexpr auto strlwr(const String<Length>& str) {
198-
std::array<char, Length> result;
199-
for (int i = 0; i < Length; i++) {
200-
result[i] = toLower(str[i]);
201-
}
202-
return String<Length>{result};
203-
}
204-
205-
template<size_t Length>
206-
[[nodiscard]] constexpr auto strupr(const String<Length>& str) {
207-
std::array<char, Length> result;
208-
for (int i = 0; i < Length; i++) {
209-
result[i] = toUpper(str[i]);
210-
}
211-
return String<Length>{result};
212-
}
213-
214-
template<size_t Length>
215-
[[nodiscard]] constexpr auto strrev(const String<Length>& str) {
216-
std::array<char, Length> result;
217-
for (int i = 1; i < Length; i++) {
218-
result[i - 1] = str[Length - i - 1];
219-
}
220-
result[Length - 1] = 0;
221-
return String<Length>{result};
222-
}
223-
224-
// need strset and strnset
225-
226-
// also a tokenizer would be nice
227-
228-
} // namespace cstringpp
3+
#include "cstringpp/core.hpp"
4+
#include "cstringpp/helpers.hpp"

0 commit comments

Comments
 (0)