Skip to content

Commit d0cd719

Browse files
committed
Make more CTL fixes
1 parent 6137098 commit d0cd719

File tree

4 files changed

+120
-13
lines changed

4 files changed

+120
-13
lines changed

ctl/allocator_traits.h

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,23 +11,26 @@ struct allocator_traits
1111
{
1212
using allocator_type = Alloc;
1313
using value_type = typename Alloc::value_type;
14-
using pointer = typename Alloc::pointer;
15-
using const_pointer = typename Alloc::const_pointer;
14+
using pointer = typename Alloc::value_type*;
15+
using const_pointer = const typename Alloc::value_type*;
1616
using void_pointer = void*;
1717
using const_void_pointer = const void*;
18-
using difference_type = typename Alloc::difference_type;
19-
using size_type = typename Alloc::size_type;
18+
using difference_type = ptrdiff_t;
19+
using size_type = size_t;
2020

2121
using propagate_on_container_copy_assignment = ctl::false_type;
2222
using propagate_on_container_move_assignment = ctl::true_type;
2323
using propagate_on_container_swap = ctl::false_type;
2424
using is_always_equal = ctl::true_type;
2525

2626
template<typename T>
27-
using rebind_alloc = typename Alloc::template rebind<T>::other;
27+
struct rebind_alloc
28+
{
29+
using other = typename Alloc::template rebind<T>::other;
30+
};
2831

2932
template<typename T>
30-
using rebind_traits = allocator_traits<rebind_alloc<T>>;
33+
using rebind_traits = allocator_traits<typename rebind_alloc<T>::other>;
3134

3235
static pointer allocate(Alloc& a, size_type n)
3336
{
@@ -53,7 +56,7 @@ struct allocator_traits
5356

5457
static size_type max_size(const Alloc& a) noexcept
5558
{
56-
return __PTRDIFF_MAX__ / sizeof(value_type);
59+
return a.max_size();
5760
}
5861

5962
static Alloc select_on_container_copy_construction(const Alloc& a)

ctl/string.h

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,18 @@ class string
332332
return *this;
333333
}
334334

335+
string& operator+=(const char* s) noexcept
336+
{
337+
append(s);
338+
return *this;
339+
}
340+
341+
string& operator+=(const ctl::string s) noexcept
342+
{
343+
append(s);
344+
return *this;
345+
}
346+
335347
string& operator+=(const ctl::string_view s) noexcept
336348
{
337349
append(s);
@@ -344,17 +356,17 @@ class string
344356
return strcat(*this, s);
345357
}
346358

347-
string operator+(const string& s) const noexcept
359+
string operator+(const char* s) const noexcept
348360
{
349361
return strcat(*this, s);
350362
}
351363

352-
string operator+(const ctl::string_view s) const noexcept
364+
string operator+(const string& s) const noexcept
353365
{
354366
return strcat(*this, s);
355367
}
356368

357-
string operator+(const char* s) const noexcept
369+
string operator+(const ctl::string_view s) const noexcept
358370
{
359371
return strcat(*this, s);
360372
}

ctl/vector.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -411,16 +411,17 @@ class vector
411411
return erase(pos, pos + 1);
412412
}
413413

414-
iterator erase(const_iterator first, const_iterator last)
414+
constexpr iterator erase(const_iterator first, const_iterator last)
415415
{
416416
difference_type index = first - begin();
417417
difference_type count = last - first;
418418
iterator it = begin() + index;
419-
ctl::move(it + count, end(), it);
419+
for (iterator move_it = it + count; move_it != end(); ++move_it, ++it)
420+
*it = ctl::move(*move_it);
420421
for (difference_type i = 0; i < count; ++i)
421422
ctl::allocator_traits<Allocator>::destroy(alloc_, end() - i - 1);
422423
size_ -= count;
423-
return it;
424+
return begin() + index;
424425
}
425426

426427
void push_back(const T& value)

test/ctl/vector_test.cc

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,46 @@
2424
// #include <vector>
2525
// #define ctl std
2626

27+
static int counter;
28+
29+
// Test with non-trivial type
30+
struct NonTrivial
31+
{
32+
int value;
33+
34+
NonTrivial(int v) : value(v)
35+
{
36+
++counter;
37+
}
38+
39+
NonTrivial(const NonTrivial& other) : value(other.value)
40+
{
41+
++counter;
42+
}
43+
44+
NonTrivial(NonTrivial&& other) noexcept : value(other.value)
45+
{
46+
++counter;
47+
}
48+
49+
~NonTrivial()
50+
{
51+
--counter;
52+
}
53+
54+
NonTrivial& operator=(const NonTrivial& other)
55+
{
56+
value = other.value;
57+
return *this;
58+
}
59+
60+
NonTrivial& operator=(NonTrivial&& other) noexcept
61+
{
62+
value = other.value;
63+
return *this;
64+
}
65+
};
66+
2767
int
2868
main()
2969
{
@@ -360,5 +400,56 @@ main()
360400
return 82;
361401
}
362402

403+
// Test erase(const_iterator first, const_iterator last)
404+
{
405+
ctl::vector<int> v = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
406+
407+
// Test erasing from the middle
408+
auto it = v.erase(v.begin() + 3, v.begin() + 7);
409+
if (v.size() != 6 || v != ctl::vector<int>{ 1, 2, 3, 8, 9, 10 } ||
410+
it != v.begin() + 3)
411+
return 83;
412+
413+
// Test erasing from the beginning
414+
it = v.erase(v.begin(), v.begin() + 2);
415+
if (v.size() != 4 || v != ctl::vector<int>{ 3, 8, 9, 10 } ||
416+
it != v.begin())
417+
return 84;
418+
419+
// Test erasing to the end
420+
it = v.erase(v.begin() + 2, v.end());
421+
if (v.size() != 2 || v != ctl::vector<int>{ 3, 8 } || it != v.end())
422+
return 85;
423+
424+
// Test erasing all elements
425+
it = v.erase(v.begin(), v.end());
426+
if (!v.empty() || it != v.end())
427+
return 86;
428+
429+
// Test erasing empty range
430+
v = { 1, 2, 3, 4, 5 };
431+
it = v.erase(v.begin() + 2, v.begin() + 2);
432+
if (v.size() != 5 || v != ctl::vector<int>{ 1, 2, 3, 4, 5 } ||
433+
it != v.begin() + 2)
434+
return 87;
435+
436+
counter = 0;
437+
438+
{
439+
ctl::vector<NonTrivial> v2;
440+
for (int i = 0; i < 10; ++i)
441+
v2.emplace_back(i);
442+
v2.erase(v2.begin() + 3, v2.begin() + 7);
443+
if (v2.size() != 6 || counter != 6)
444+
return 89;
445+
for (int i = 0; i < (int)v2.size(); ++i)
446+
if (v2[i].value != (i < 3 ? i : i + 4))
447+
return 90;
448+
}
449+
450+
if (counter != 0)
451+
return 91;
452+
}
453+
363454
CheckForMemoryLeaks();
364455
}

0 commit comments

Comments
 (0)