Skip to content

Commit f39922d

Browse files
author
John Wellbelove
committed
Merge branch 'feature/#1100-Optimise-string-class-initialisation-from-C-data' into development
# Conflicts: # include/etl/basic_string.h
2 parents 896baaa + 155050b commit f39922d

13 files changed

+215
-13
lines changed

include/etl/basic_string.h

Lines changed: 50 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2667,6 +2667,7 @@ namespace etl
26672667
/// Returns a pointer to the character after the last copied.
26682668
//*********************************************************************
26692669
template <typename TIterator1, typename TIterator2>
2670+
static
26702671
typename etl::enable_if<etl::is_pointer<TIterator1>::value && etl::is_pointer<TIterator2>::value, TIterator2>::type
26712672
copy_characters(TIterator1 from, size_t n, TIterator2 to)
26722673
{
@@ -2680,6 +2681,7 @@ namespace etl
26802681
/// Returns an iterator to the character after the last copied.
26812682
//*********************************************************************
26822683
template <typename TIterator1, typename TIterator2>
2684+
static
26832685
typename etl::enable_if<!etl::is_pointer<TIterator1>::value || !etl::is_pointer<TIterator2>::value, TIterator2>::type
26842686
copy_characters(TIterator1 from, size_t n, TIterator2 to)
26852687
{
@@ -2694,6 +2696,39 @@ namespace etl
26942696
return to;
26952697
}
26962698

2699+
//*********************************************************************
2700+
/// get_string_length, optimised for sizeof(U) == sizeof(char).
2701+
//*********************************************************************
2702+
template <typename U>
2703+
static
2704+
typename etl::enable_if<sizeof(U) == sizeof(char), size_t>::type
2705+
get_string_length(const U* src)
2706+
{
2707+
return ::strlen(reinterpret_cast<const char*>(src));
2708+
}
2709+
2710+
//*********************************************************************
2711+
/// get_string_length, optimised for sizeof(U) == sizeof(wchar_t).
2712+
//*********************************************************************
2713+
template <typename U>
2714+
static
2715+
typename etl::enable_if<sizeof(U) == sizeof(wchar_t), size_t>::type
2716+
get_string_length(const U* src)
2717+
{
2718+
return ::wcslen(reinterpret_cast<const wchar_t*>(src));
2719+
}
2720+
2721+
//*********************************************************************
2722+
/// get_string_length, optimised for anything else.
2723+
//*********************************************************************
2724+
template <typename U>
2725+
static
2726+
typename etl::enable_if<(sizeof(U) != sizeof(char)) && (sizeof(U) != sizeof(wchar_t)), size_t>::type
2727+
get_string_length(const U* src)
2728+
{
2729+
return etl::strlen(src);
2730+
}
2731+
26972732
//*********************************************************************
26982733
/// Common implementation for 'assign' and 'append' for iterators.
26992734
//*********************************************************************
@@ -2733,20 +2768,30 @@ namespace etl
27332768
}
27342769

27352770
//*********************************************************************
2736-
/// Common implementation for 'assign' and 'append' for single pointer.
2771+
/// Common implementation for 'assign' and 'append' for C string pointer.
27372772
//*********************************************************************
2738-
void append_impl(iterator position, const_pointer first, bool truncated, bool secure)
2773+
void append_impl(iterator position, const_pointer src, bool truncated, bool secure)
27392774
{
2775+
if (src == ETL_NULLPTR)
2776+
{
2777+
clear();
2778+
return;
2779+
}
2780+
27402781
difference_type start = etl::distance(p_buffer, position);
27412782
difference_type free_space = etl::distance(position, p_buffer + CAPACITY);
27422783

2743-
etl::str_n_copy_result result = etl::str_n_copy(first, size_t(free_space), position);
2784+
pointer dst = position;
2785+
size_t length = get_string_length(src);
2786+
size_t count = (length < size_t(free_space)) ? length : size_t(free_space);
2787+
etl::mem_copy(src, count, dst);
27442788

2745-
current_size = size_t(start) + result.count;
2789+
truncated |= (src[count] != 0);
2790+
current_size = size_t(start) + count;
27462791
p_buffer[current_size] = 0;
27472792

27482793
#if ETL_HAS_STRING_TRUNCATION_CHECKS
2749-
set_truncated(result.truncated || truncated);
2794+
set_truncated(truncated);
27502795
#if ETL_HAS_ERROR_ON_STRING_TRUNCATION
27512796
ETL_ASSERT(is_truncated == false, ETL_ERROR(string_truncation));
27522797
#endif

include/etl/char_traits.h

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -137,19 +137,21 @@ namespace etl
137137
}
138138

139139
//*************************************************************************
140-
static ETL_CONSTEXPR14 size_t length(const char_type* str)
140+
static ETL_CONSTEXPR14 size_t length(const char_type* begin)
141141
{
142-
size_t count = 0UL;
142+
if (begin == ETL_NULLPTR)
143+
{
144+
return 0;
145+
}
143146

144-
if (str != 0)
147+
const char_type* end = begin;
148+
149+
while (*end++ != 0)
145150
{
146-
while (*str++ != 0)
147-
{
148-
++count;
149-
}
151+
// Do nothing.
150152
}
151153

152-
return count;
154+
return size_t(end - begin) - 1;
153155
}
154156

155157
//*************************************************************************

test/test_char_traits.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,16 @@ namespace
5555
//*************************************************************************
5656
TEST(test_strlen)
5757
{
58+
CHECK_EQUAL(0U, etl::strlen((const char*)0));
59+
CHECK_EQUAL(0U, etl::strlen((const wchar_t*)0));
60+
CHECK_EQUAL(0U, etl::strlen((const char16_t*)0));
61+
CHECK_EQUAL(0U, etl::strlen((const char32_t*)0));
62+
63+
CHECK_EQUAL(0U, etl::strlen(""));
64+
CHECK_EQUAL(0U, etl::strlen(L""));
65+
CHECK_EQUAL(0U, etl::strlen(u""));
66+
CHECK_EQUAL(0U, etl::strlen(U""));
67+
5868
CHECK_EQUAL(6U, etl::strlen("qwerty"));
5969
CHECK_EQUAL(6U, etl::strlen(L"qwerty"));
6070
CHECK_EQUAL(6U, etl::strlen(u"qwerty"));

test/test_string_char.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,20 @@ namespace
165165
CHECK_FALSE(text.is_truncated());
166166
}
167167

168+
//*************************************************************************
169+
TEST_FIXTURE(SetupFixture, test_constructor_char_pointer_shorter_string)
170+
{
171+
TextSTD compare_text(shorter_text.c_str());
172+
173+
Text text(shorter_text.c_str());
174+
175+
CHECK(!text.empty());
176+
177+
bool is_equal = Equal(compare_text, text);
178+
CHECK(is_equal);
179+
CHECK_FALSE(text.is_truncated());
180+
}
181+
168182
//*************************************************************************
169183
TEST_FIXTURE(SetupFixture, test_constructor_char_pointer_excess)
170184
{

test/test_string_char_external_buffer.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,21 @@ namespace
219219
#endif
220220
}
221221

222+
//*************************************************************************
223+
TEST_FIXTURE(SetupFixture, test_constructor_char_pointer_shorter_string)
224+
{
225+
TextBuffer buffer{0};
226+
TextSTD compare_text(shorter_text.c_str());
227+
228+
Text text(shorter_text.c_str(), buffer.data(), buffer.size());
229+
230+
CHECK(!text.empty());
231+
232+
bool is_equal = Equal(compare_text, text);
233+
CHECK(is_equal);
234+
CHECK_FALSE(text.is_truncated());
235+
}
236+
222237
//*************************************************************************
223238
TEST_FIXTURE(SetupFixture, test_constructor_char_pointer)
224239
{

test/test_string_u16.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,20 @@ namespace
179179
CHECK_FALSE(text.is_truncated());
180180
}
181181

182+
//*************************************************************************
183+
TEST_FIXTURE(SetupFixture, test_constructor_char_pointer_shorter_string)
184+
{
185+
TextSTD compare_text(shorter_text.c_str());
186+
187+
Text text(shorter_text.c_str());
188+
189+
CHECK(!text.empty());
190+
191+
bool is_equal = Equal(compare_text, text);
192+
CHECK(is_equal);
193+
CHECK_FALSE(text.is_truncated());
194+
}
195+
182196
//*************************************************************************
183197
TEST_FIXTURE(SetupFixture, test_constructor_char_pointer_excess)
184198
{

test/test_string_u16_external_buffer.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,21 @@ namespace
248248
CHECK_FALSE(text.is_truncated());
249249
}
250250

251+
//*************************************************************************
252+
TEST_FIXTURE(SetupFixture, test_constructor_char_pointer_shorter_string)
253+
{
254+
TextSTD compare_text(shorter_text.c_str());
255+
256+
TextBuffer buffer{0};
257+
Text text(shorter_text.c_str(), buffer.data(), buffer.size());
258+
259+
CHECK(!text.empty());
260+
261+
bool is_equal = Equal(compare_text, text);
262+
CHECK(is_equal);
263+
CHECK_FALSE(text.is_truncated());
264+
}
265+
251266
//*************************************************************************
252267
TEST_FIXTURE(SetupFixture, test_constructor_char_pointer_excess)
253268
{

test/test_string_u32.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,20 @@ namespace
179179
CHECK_FALSE(text.is_truncated());
180180
}
181181

182+
//*************************************************************************
183+
TEST_FIXTURE(SetupFixture, test_constructor_char_pointer_shorter_string)
184+
{
185+
TextSTD compare_text(shorter_text.c_str());
186+
187+
Text text(shorter_text.c_str());
188+
189+
CHECK(!text.empty());
190+
191+
bool is_equal = Equal(compare_text, text);
192+
CHECK(is_equal);
193+
CHECK_FALSE(text.is_truncated());
194+
}
195+
182196
//*************************************************************************
183197
TEST_FIXTURE(SetupFixture, test_constructor_char_pointer_excess)
184198
{

test/test_string_u32_external_buffer.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,21 @@ namespace
248248
CHECK_FALSE(text.is_truncated());
249249
}
250250

251+
//*************************************************************************
252+
TEST_FIXTURE(SetupFixture, test_constructor_char_pointer_shorter_string)
253+
{
254+
TextSTD compare_text(shorter_text.c_str());
255+
256+
TextBuffer buffer{0};
257+
Text text(shorter_text.c_str(), buffer.data(), buffer.size());
258+
259+
CHECK(!text.empty());
260+
261+
bool is_equal = Equal(compare_text, text);
262+
CHECK(is_equal);
263+
CHECK_FALSE(text.is_truncated());
264+
}
265+
251266
//*************************************************************************
252267
TEST_FIXTURE(SetupFixture, test_constructor_char_pointer_excess)
253268
{

test/test_string_u8.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,20 @@ namespace
182182
CHECK_FALSE(text.is_truncated());
183183
}
184184

185+
//*************************************************************************
186+
TEST_FIXTURE(SetupFixture, test_constructor_char_pointer_shorter_string)
187+
{
188+
TextSTD compare_text(shorter_text.c_str());
189+
190+
Text text(shorter_text.c_str());
191+
192+
CHECK(!text.empty());
193+
194+
bool is_equal = Equal(compare_text, text);
195+
CHECK(is_equal);
196+
CHECK_FALSE(text.is_truncated());
197+
}
198+
185199
//*************************************************************************
186200
TEST_FIXTURE(SetupFixture, test_constructor_char_pointer_excess)
187201
{

0 commit comments

Comments
 (0)