Skip to content

Commit 38921dc

Browse files
committed
Introduce more CTL content
This change introduces accumulate, addressof, advance, all_of, distance, array, enable_if, allocator_traits, back_inserter, bad_alloc, is_signed, any_of, copy, exception, fill, fill_n, is_same, is_same_v, out_of_range, lexicographical_compare, is_integral, uninitialized_fill_n, is_unsigned, numeric_limits, uninitialized_fill, iterator_traits, move_backward, min, max, iterator_tag, move_iterator, reverse_iterator, uninitialized_move_n This change experiments with rewriting the ctl::vector class to make the CTL design more similar to the STL. So far it has not slowed things down to have 42 #include lines rather than 2, since it's still almost nothing compared to LLVM's code. In fact the closer we can flirt with being just like libcxx, the better chance we might have of discovering exactly what makes it so slow to compile. It would be an enormous discovery if we can find one simple trick to solving the issue there instead. This also fixes a bug in `ctl::string(const string &s)` when `s` is big.
1 parent 054da02 commit 38921dc

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+2976
-189
lines changed

ctl/BUILD.mk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ $(CTL_A_OBJS): private \
3636
-Walloca-larger-than=4096 \
3737
-ffunction-sections \
3838
-fdata-sections \
39+
-fexceptions \
3940

4041
CTL_LIBS = $(foreach x,$(CTL_ARTIFACTS),$($(x)))
4142
CTL_SRCS = $(foreach x,$(CTL_ARTIFACTS),$($(x)_SRCS))

ctl/accumulate.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*-
2+
// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi
3+
#ifndef CTL_ACCUMULATE_H_
4+
#define CTL_ACCUMULATE_H_
5+
6+
namespace ctl {
7+
8+
template<class InputIt, class T>
9+
constexpr T
10+
accumulate(InputIt first, InputIt last, T init)
11+
{
12+
for (; first != last; ++first)
13+
init = init + *first;
14+
return init;
15+
}
16+
17+
template<class InputIt, class T, class BinaryOperation>
18+
constexpr T
19+
accumulate(InputIt first, InputIt last, T init, BinaryOperation op)
20+
{
21+
for (; first != last; ++first)
22+
init = op(init, *first);
23+
return init;
24+
}
25+
26+
} // namespace ctl
27+
28+
#endif // CTL_ACCUMULATE_H_

ctl/addressof.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*-
2+
// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi
3+
#ifndef CTL_ADDRESSOF_H_
4+
#define CTL_ADDRESSOF_H_
5+
6+
namespace ctl {
7+
8+
template<typename T>
9+
T*
10+
addressof(T& arg) noexcept
11+
{
12+
return reinterpret_cast<T*>(
13+
&const_cast<char&>(reinterpret_cast<const volatile char&>(arg)));
14+
}
15+
16+
template<typename R, typename... Args>
17+
R (*addressof(R (*&arg)(Args...)) noexcept)
18+
(Args...)
19+
{
20+
return arg;
21+
}
22+
23+
template<typename T>
24+
T*
25+
addressof(T&&) = delete;
26+
27+
} // namespace ctl
28+
29+
#endif // CTL_ADDRESSOF_H_

ctl/advance.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*-
2+
// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi
3+
#ifndef CTL_ADVANCE_H_
4+
#define CTL_ADVANCE_H_
5+
6+
namespace ctl {
7+
8+
template<class InputIt, class Distance>
9+
constexpr void
10+
advance(InputIt& it, Distance n)
11+
{
12+
while (n > 0) {
13+
--n;
14+
++it;
15+
}
16+
while (n < 0) {
17+
++n;
18+
--it;
19+
}
20+
}
21+
22+
} // namespace ctl
23+
24+
#endif // CTL_ADVANCE_H_

ctl/all_of.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*-
2+
// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi
3+
#ifndef CTL_ALL_OF_H_
4+
#define CTL_ALL_OF_H_
5+
6+
namespace ctl {
7+
8+
template<class InputIt, class UnaryPredicate>
9+
constexpr bool
10+
all_of(InputIt first, InputIt last, UnaryPredicate p)
11+
{
12+
for (; first != last; ++first) {
13+
if (!p(*first)) {
14+
return false;
15+
}
16+
}
17+
return true;
18+
}
19+
20+
} // namespace ctl
21+
22+
#endif // CTL_ALL_OF_H_

ctl/allocator.h

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*-
2+
// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi
3+
#ifndef CTL_ALLOCATOR_H_
4+
#define CTL_ALLOCATOR_H_
5+
#include "bad_alloc.h"
6+
#include "new.h"
7+
#include "type_traits.h"
8+
#include "utility.h"
9+
10+
namespace ctl {
11+
12+
template<typename T>
13+
class allocator
14+
{
15+
public:
16+
using value_type = T;
17+
using size_type = size_t;
18+
using difference_type = ptrdiff_t;
19+
using propagate_on_container_move_assignment = ctl::true_type;
20+
using is_always_equal = ctl::true_type;
21+
using pointer = T*;
22+
using const_pointer = const T*;
23+
using reference = T&;
24+
using const_reference = const T&;
25+
26+
constexpr allocator() noexcept = default;
27+
28+
constexpr allocator(const allocator&) noexcept = default;
29+
30+
template<class U>
31+
constexpr allocator(const allocator<U>&) noexcept
32+
{
33+
}
34+
35+
constexpr ~allocator() = default;
36+
37+
[[nodiscard]] T* allocate(size_type n)
38+
{
39+
if (n > __SIZE_MAX__ / sizeof(T))
40+
throw ctl::bad_alloc();
41+
if (auto p = static_cast<T*>(::operator new(
42+
n * sizeof(T), ctl::align_val_t(alignof(T)), ctl::nothrow)))
43+
return p;
44+
throw ctl::bad_alloc();
45+
}
46+
47+
void deallocate(T* p, size_type n) noexcept
48+
{
49+
::operator delete(p, n * sizeof(T), ctl::align_val_t(alignof(T)));
50+
}
51+
52+
template<typename U, typename... Args>
53+
void construct(U* p, Args&&... args)
54+
{
55+
::new (static_cast<void*>(p)) U(ctl::forward<Args>(args)...);
56+
}
57+
58+
template<typename U>
59+
void destroy(U* p)
60+
{
61+
p->~U();
62+
}
63+
64+
size_type max_size() const noexcept
65+
{
66+
return __SIZE_MAX__ / sizeof(T);
67+
}
68+
69+
allocator& operator=(const allocator&) = default;
70+
71+
template<typename U>
72+
struct rebind
73+
{
74+
using other = allocator<U>;
75+
};
76+
};
77+
78+
template<class T, class U>
79+
bool
80+
operator==(const allocator<T>&, const allocator<U>&) noexcept
81+
{
82+
return true;
83+
}
84+
85+
template<class T, class U>
86+
bool
87+
operator!=(const allocator<T>&, const allocator<U>&) noexcept
88+
{
89+
return false;
90+
}
91+
92+
} // namespace ctl
93+
94+
#endif // CTL_ALLOCATOR_H_

ctl/allocator_traits.h

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
#ifndef CTL_ALLOCATOR_TRAITS_H_
2+
#define CTL_ALLOCATOR_TRAITS_H_
3+
#include "type_traits.h"
4+
5+
namespace ctl {
6+
7+
template<typename Alloc>
8+
struct allocator_traits
9+
{
10+
using allocator_type = Alloc;
11+
using value_type = typename Alloc::value_type;
12+
using pointer = typename Alloc::pointer;
13+
using const_pointer = typename Alloc::const_pointer;
14+
using void_pointer = void*;
15+
using const_void_pointer = const void*;
16+
using difference_type = typename Alloc::difference_type;
17+
using size_type = typename Alloc::size_type;
18+
19+
using propagate_on_container_copy_assignment = false_type;
20+
using propagate_on_container_move_assignment = true_type;
21+
using propagate_on_container_swap = false_type;
22+
using is_always_equal = true_type;
23+
24+
template<typename T>
25+
using rebind_alloc = typename Alloc::template rebind<T>::other;
26+
27+
template<typename T>
28+
using rebind_traits = allocator_traits<rebind_alloc<T>>;
29+
30+
__attribute__((__always_inline__)) static pointer allocate(Alloc& a,
31+
size_type n)
32+
{
33+
return a.allocate(n);
34+
}
35+
36+
__attribute__((__always_inline__)) static void deallocate(Alloc& a,
37+
pointer p,
38+
size_type n)
39+
{
40+
a.deallocate(p, n);
41+
}
42+
43+
template<typename T, typename... Args>
44+
__attribute__((__always_inline__)) static void construct(Alloc& a,
45+
T* p,
46+
Args&&... args)
47+
{
48+
::new ((void*)p) T(static_cast<Args&&>(args)...);
49+
}
50+
51+
template<typename T>
52+
__attribute__((__always_inline__)) static void destroy(Alloc& a, T* p)
53+
{
54+
p->~T();
55+
}
56+
57+
__attribute__((__always_inline__)) static size_type max_size(
58+
const Alloc& a) noexcept
59+
{
60+
return __PTRDIFF_MAX__ / sizeof(value_type);
61+
}
62+
63+
__attribute__((__always_inline__)) static Alloc
64+
select_on_container_copy_construction(const Alloc& a)
65+
{
66+
return a;
67+
}
68+
};
69+
70+
} // namespace ctl
71+
72+
#endif // CTL_ALLOCATOR_TRAITS_H_

ctl/any_of.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*-
2+
// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi
3+
#ifndef CTL_ANY_OF_H_
4+
#define CTL_ANY_OF_H_
5+
6+
namespace ctl {
7+
8+
template<class InputIt, class UnaryPredicate>
9+
constexpr bool
10+
any_of(InputIt first, InputIt last, UnaryPredicate p)
11+
{
12+
for (; first != last; ++first) {
13+
if (p(*first)) {
14+
return true;
15+
}
16+
}
17+
return false;
18+
}
19+
20+
} // namespace ctl
21+
22+
#endif // CTL_ANY_OF_H_

0 commit comments

Comments
 (0)