Skip to content

Commit af8eff6

Browse files
committed
New string concept
1 parent dc9135c commit af8eff6

File tree

10 files changed

+281
-121
lines changed

10 files changed

+281
-121
lines changed

CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ SET ( cppcore_src
7676
SET ( cppcore_common_src
7777
include/cppcore/Common/Hash.h
7878
include/cppcore/Common/TStringBase.h
79+
include/cppcore/Common/TStringView.h
7980
include/cppcore/Common/Variant.h
8081
include/cppcore/Common/Sort.h
8182
include/cppcore/Common/TBitField.h
@@ -137,6 +138,8 @@ IF( CPPCORE_BUILD_UNITTESTS )
137138
test/common/SortTest.cpp
138139
test/common/TBitFieldTest.cpp
139140
test/common/TOptionalTest.cpp
141+
test/common/TStringViewTest.cpp
142+
test/common/TStringBaseTest.cpp
140143
)
141144

142145
SET( cppcore_container_test_src

include/cppcore/CPPCoreCommon.h

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -45,19 +45,19 @@ namespace cppcore {
4545
#endif
4646

4747
#ifdef CPPCORE_WINDOWS
48-
# define CPPCORE_TAG_DLL_EXPORT __declspec(dllexport)
49-
# define CPPCORE_TAG_DLL_IMPORT __declspec(dllimport )
48+
# define CPPCORE_TAG_DLL_EXPORT __declspec(dllexport)
49+
# define CPPCORE_TAG_DLL_IMPORT __declspec(dllimport )
5050
# ifdef CPPCORE_BUILD
51-
# define DLL_CPPCORE_EXPORT CPPCORE_TAG_DLL_EXPORT
51+
# define DLL_CPPCORE_EXPORT CPPCORE_TAG_DLL_EXPORT
5252
# else
53-
# define DLL_CPPCORE_EXPORT CPPCORE_TAG_DLL_IMPORT
53+
# define DLL_CPPCORE_EXPORT CPPCORE_TAG_DLL_IMPORT
5454
# endif
5555
// All disabled warnings for windows
5656
# pragma warning( disable : 4251 ) // <class> needs to have dll-interface to be used by clients of class <class>
57-
# define CPPCORE_STACK_ALLOC(size) ::alloca(size)
57+
# define CPPCORE_STACK_ALLOC(size) ::alloca(size)
5858
#else
59-
# define DLL_CPPCORE_EXPORT __attribute__((visibility("default")))
60-
# define CPPCORE_STACK_ALLOC(size) __builtin_alloca(size)
59+
# define DLL_CPPCORE_EXPORT __attribute__((visibility("default")))
60+
# define CPPCORE_STACK_ALLOC(size) __builtin_alloca(size)
6161
#endif
6262

6363
//-------------------------------------------------------------------------------------------------
@@ -107,4 +107,6 @@ public: \
107107
//-------------------------------------------------------------------------------------------------
108108
#define CPPCORE_ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
109109

110+
using HashId = uint64_t;
111+
110112
} // Namespace cppcore

include/cppcore/Common/Sort.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ namespace cppcore {
177177
}
178178

179179
/// @brief Implements a binary search algorithm.
180-
/// @tparam T The type of the value
180+
/// @tparam T The type of the value
181181
/// @param key The key to search for
182182
/// @param array The data to search in
183183
/// @param num The number of elements to search

include/cppcore/Common/TStringBase.h

Lines changed: 70 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -23,30 +23,11 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2323
#pragma once
2424

2525
#include "string.h"
26+
#include <cppcore/Common/Hash.h>
2627
#include <cppcore/CPPCoreCommon.h>
27-
#include <malloc.h>
2828

2929
namespace cppcore {
3030

31-
template <class T>
32-
struct Allocator {
33-
inline T *alloc(size_t size, size_t alignment) {
34-
return (T*) _aligned_malloc(size, alignment);
35-
}
36-
37-
inline void dealloc(T *ptr) {
38-
_aligned_free(ptr);
39-
}
40-
41-
inline static size_t countChars(const T *ptr) {
42-
if (nullptr != ptr) {
43-
return 0;
44-
}
45-
46-
return (::strlen(ptr));
47-
}
48-
};
49-
5031
//-------------------------------------------------------------------------------------------------
5132
/// @class TStringBase
5233
/// @ingroup CPPCore
@@ -57,135 +38,122 @@ template <class T>
5738
class TStringBase {
5839
public:
5940
/// @brief The default class constructor.
60-
TStringBase() noexcept;
41+
TStringBase() noexcept = default;
6142

6243
/// @brief The class constructor with a pointer showing to the data buffer.
6344
/// @param pPtr [in] The data buffer.
64-
TStringBase(const T *pPtr);
45+
TStringBase(const T *pPtr, size_t size);
6546

6647
/// @brief The class destructor.
6748
~TStringBase();
6849

69-
void set(const T *ptr);
50+
void set(const T *ptr, size_t size);
51+
void clear();
52+
void reset();
53+
size_t size() const;
54+
size_t capacity() const;
55+
const T *c_str() const;
7056

7157
/// @brief Helper method to copy data into the string.
7258
/// @param base [inout] The string data to copy in.
7359
/// @param pPtr [in] The data source.
74-
static void copyFrom(TStringBase<T> &base, const T *pPtr);
60+
static void copyFrom(TStringBase<T> &base, const T *pPtr, size_t size);
7561

7662
bool operator == (const TStringBase<T> &rhs) const;
7763
bool operator != (const TStringBase<T> &rhs) const;
7864

79-
T *m_pStringBuffer;
80-
size_t m_size;
81-
size_t m_capacity;
82-
Allocator<T> mAllocator;
65+
private:
66+
static constexpr size_t InitSize = 256;
67+
T mBuffer[InitSize] = {'\0'};
68+
T *mStringBuffer{nullptr};
69+
size_t mSize{0};
70+
size_t mCapacity{256};
71+
HashId mHashId{0};
8372
};
8473

8574
template <class T>
86-
inline TStringBase<T>::TStringBase() noexcept :
87-
m_pStringBuffer(nullptr),
88-
m_size(0),
89-
m_capacity(0),
90-
mAllocator() {
91-
// empty
75+
inline TStringBase<T>::TStringBase(const T *pPtr, size_t size) {
76+
copyFrom(*this, pPtr, size);
77+
mHashId = THash<HashId>::toHash(pPtr, mSize);
9278
}
9379

9480
template <class T>
95-
inline TStringBase<T>::TStringBase(const T *pPtr) :
96-
m_pStringBuffer(nullptr),
97-
m_size(0),
98-
m_capacity(0),
99-
mAllocator() {
100-
copyFrom(*this, pPtr);
81+
inline TStringBase<T>::~TStringBase() {
82+
clear();
10183
}
10284

10385
template <class T>
104-
inline TStringBase<T>::~TStringBase() {
105-
if (m_pStringBuffer) {
106-
mAllocator.dealloc(m_pStringBuffer);
107-
m_pStringBuffer = nullptr;
86+
inline void TStringBase<T>::set(const T *ptr, size_t size) {
87+
void reset();
88+
if (nullptr != ptr) {
89+
copyFrom(*this, ptr, size);
10890
}
10991
}
11092

11193
template <class T>
112-
inline void TStringBase<T>::set(const T *ptr) {
113-
mAllocator.dealloc(m_pStringBuffer);
114-
if (nullptr != ptr) {
115-
copyFrom(*this, ptr);
116-
}
94+
inline void TStringBase<T>::reset() {
95+
mSize = 0u;
11796
}
11897

11998
template <class T>
120-
inline void TStringBase<T>::copyFrom(TStringBase<T> &base, const T *ptr) {
121-
if (nullptr != ptr) {
122-
base.m_size = Allocator<T>::countChars(ptr);
123-
if (base.m_size) {
124-
base.m_capacity = base.m_size + 1;
125-
base.m_pStringBuffer = base.mAllocator.alloc(base.m_capacity, 16);
126-
#ifdef CPPCORE_WINDOWS
127-
::strncpy_s(base.m_pStringBuffer, base.m_capacity, ptr, base.m_size);
128-
#else
129-
::strncpy(base.m_pStringBuffer, ptr, base.m_size);
130-
#endif
131-
base.m_pStringBuffer[base.m_size] = '\0';
132-
}
133-
}
99+
inline size_t TStringBase<T>::size() const {
100+
return mSize;
134101
}
135102

136103
template <class T>
137-
inline bool TStringBase<T>::operator==( const TStringBase<T> &rhs ) const {
138-
if (rhs.m_size != m_size) {
139-
return false;
140-
}
104+
inline size_t TStringBase<T>::capacity() const {
105+
return mCapacity;
106+
}
141107

142-
for (size_t i = 0; i < m_size; ++i) {
143-
if (rhs.m_pStringBuffer[i] != m_pStringBuffer[i]) {
144-
return false;
145-
}
108+
template <class T>
109+
inline const T *TStringBase<T>::c_str() const {
110+
if (mStringBuffer != nullptr) {
111+
return mStringBuffer;
146112
}
147113

148-
return true;
114+
return mBuffer;
149115
}
150116

151117
template <class T>
152-
inline bool TStringBase<T>::operator!=(const TStringBase<T> &rhs) const {
153-
return !(*this == rhs);
118+
inline void TStringBase<T>::clear() {
119+
if (mStringBuffer != nullptr) {
120+
delete [] mStringBuffer;
121+
mStringBuffer = nullptr;
122+
mCapacity = InitSize;
123+
}
124+
mSize = 0;
154125
}
155126

156-
template <class TCharType>
157-
class TStringView {
158-
public:
159-
TStringView(TCharType *ptr);
160-
~TStringView();
161-
size_t size() const;
162-
TCharType *data() const;
163-
164-
private:
165-
TCharType *mPtr;
166-
size_t mLen;
167-
};
168-
169-
template <class TCharType>
170-
inline TStringView<TCharType>::TStringView(TCharType *ptr) :
171-
mPtr(ptr),
172-
mLen(0) {
173-
if (nullptr != mPtr) {
174-
mLen = strlen(ptr);
127+
template <class T>
128+
inline void TStringBase<T>::copyFrom(TStringBase<T> &base, const T *ptr, size_t size) {
129+
if (ptr != nullptr) {
130+
T *targetPtr = base.mBuffer;
131+
132+
if (size > 0) {
133+
if (size > base.mCapacity) {
134+
base.mStringBuffer = new T[size];
135+
base.mCapacity = size;
136+
targetPtr = base.mStringBuffer;
137+
}
138+
memcpy(targetPtr, ptr, size);
139+
base.mSize = size;
140+
}
175141
}
176142
}
177143

178-
template <class TCharType>
179-
inline TStringView<TCharType>::~TStringView() {
180-
// empty
181-
}
144+
template <class T>
145+
inline bool TStringBase<T>::operator == (const TStringBase<T> &rhs) const {
146+
if (rhs.mSize != mSize) {
147+
return false;
148+
}
182149

183-
template <class TCharType>
184-
inline size_t TStringView<TCharType>::size() const {
185-
return mLen;
150+
151+
return mHashId == rhs.mHashId;
186152
}
187153

188-
template <class TCharType>
189-
inline TCharType *TStringView<TCharType>::data() const {
154+
template <class T>
155+
inline bool TStringBase<T>::operator != (const TStringBase<T> &rhs) const {
156+
return !(*this == rhs);
190157
}
191158

159+
} // namespace cppcore
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/*-----------------------------------------------------------------------------------------------
2+
The MIT License (MIT)
3+
4+
Copyright (c) 2014-2025 Kim Kulling
5+
6+
Permission is hereby granted, free of charge, to any person obtaining a copy of
7+
this software and associated documentation files (the "Software"), to deal in
8+
the Software without restriction, including without limitation the rights to
9+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
10+
the Software, and to permit persons to whom the Software is furnished to do so,
11+
subject to the following conditions:
12+
13+
The above copyright notice and this permission notice shall be included in all
14+
copies or substantial portions of the Software.
15+
16+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22+
-----------------------------------------------------------------------------------------------*/
23+
#pragma once
24+
25+
#include <cppcore/CPPCoreCommon.h>
26+
27+
namespace cppcore {
28+
29+
//-------------------------------------------------------------------------------------------------
30+
/// @class TStringView
31+
/// @ingroup CPPCore
32+
///
33+
/// @brief
34+
//-------------------------------------------------------------------------------------------------
35+
template <class T>
36+
class TStringView {
37+
public:
38+
using const_iterator = const T*;
39+
40+
TStringView(const T *ptr, size_t len);
41+
~TStringView() = default;
42+
size_t size() const;
43+
T *data() const;
44+
bool isEmpty() const;
45+
const_iterator begin() const;
46+
const_iterator end() const;
47+
48+
private:
49+
const T *mPtr;
50+
size_t mLen;
51+
};
52+
53+
template <class T>
54+
inline TStringView<T>::TStringView(const T *ptr, size_t len) :
55+
mPtr(ptr),
56+
mLen(len) {
57+
// empty
58+
}
59+
60+
template <class T>
61+
inline size_t TStringView<T>::size() const {
62+
return mLen;
63+
}
64+
65+
template <class T>
66+
inline T *TStringView<T>::data() const {
67+
return mPtr;
68+
}
69+
70+
template <class T>
71+
inline bool TStringView<T>::isEmpty() const {
72+
return mLen == 0;
73+
}
74+
75+
template <class T>
76+
inline typename TStringView<T>::const_iterator TStringView<T>::begin() const {
77+
if (isEmpty()) {
78+
return end();
79+
}
80+
return mPtr;
81+
}
82+
83+
template <class T>
84+
inline typename TStringView<T>::const_iterator TStringView<T>::end() const {
85+
return mPtr + mLen;
86+
}
87+
88+
} // namespace cppcore

include/cppcore/Memory/MemUtils.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2323
#pragma once
2424

2525
#include <cppcore/CPPCoreCommon.h>
26-
#include <string.h>
2726
#include <cinttypes>
2827

2928
namespace cppcore {

0 commit comments

Comments
 (0)