Skip to content

Commit

Permalink
Introduce more CTL content
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
jart committed Jun 28, 2024
1 parent 054da02 commit 38921dc
Show file tree
Hide file tree
Showing 52 changed files with 2,976 additions and 189 deletions.
1 change: 1 addition & 0 deletions ctl/BUILD.mk
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ $(CTL_A_OBJS): private \
-Walloca-larger-than=4096 \
-ffunction-sections \
-fdata-sections \
-fexceptions \

CTL_LIBS = $(foreach x,$(CTL_ARTIFACTS),$($(x)))
CTL_SRCS = $(foreach x,$(CTL_ARTIFACTS),$($(x)_SRCS))
Expand Down
28 changes: 28 additions & 0 deletions ctl/accumulate.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*-
// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi
#ifndef CTL_ACCUMULATE_H_
#define CTL_ACCUMULATE_H_

namespace ctl {

template<class InputIt, class T>
constexpr T
accumulate(InputIt first, InputIt last, T init)
{
for (; first != last; ++first)
init = init + *first;
return init;
}

template<class InputIt, class T, class BinaryOperation>
constexpr T
accumulate(InputIt first, InputIt last, T init, BinaryOperation op)
{
for (; first != last; ++first)
init = op(init, *first);
return init;
}

} // namespace ctl

#endif // CTL_ACCUMULATE_H_
29 changes: 29 additions & 0 deletions ctl/addressof.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*-
// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi
#ifndef CTL_ADDRESSOF_H_
#define CTL_ADDRESSOF_H_

namespace ctl {

template<typename T>
T*
addressof(T& arg) noexcept
{
return reinterpret_cast<T*>(
&const_cast<char&>(reinterpret_cast<const volatile char&>(arg)));
}

template<typename R, typename... Args>
R (*addressof(R (*&arg)(Args...)) noexcept)
(Args...)
{
return arg;
}

template<typename T>
T*
addressof(T&&) = delete;

} // namespace ctl

#endif // CTL_ADDRESSOF_H_
24 changes: 24 additions & 0 deletions ctl/advance.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*-
// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi
#ifndef CTL_ADVANCE_H_
#define CTL_ADVANCE_H_

namespace ctl {

template<class InputIt, class Distance>
constexpr void
advance(InputIt& it, Distance n)
{
while (n > 0) {
--n;
++it;
}
while (n < 0) {
++n;
--it;
}
}

} // namespace ctl

#endif // CTL_ADVANCE_H_
22 changes: 22 additions & 0 deletions ctl/all_of.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*-
// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi
#ifndef CTL_ALL_OF_H_
#define CTL_ALL_OF_H_

namespace ctl {

template<class InputIt, class UnaryPredicate>
constexpr bool
all_of(InputIt first, InputIt last, UnaryPredicate p)
{
for (; first != last; ++first) {
if (!p(*first)) {
return false;
}
}
return true;
}

} // namespace ctl

#endif // CTL_ALL_OF_H_
94 changes: 94 additions & 0 deletions ctl/allocator.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*-
// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi
#ifndef CTL_ALLOCATOR_H_
#define CTL_ALLOCATOR_H_
#include "bad_alloc.h"
#include "new.h"
#include "type_traits.h"
#include "utility.h"

namespace ctl {

template<typename T>
class allocator
{
public:
using value_type = T;
using size_type = size_t;
using difference_type = ptrdiff_t;
using propagate_on_container_move_assignment = ctl::true_type;
using is_always_equal = ctl::true_type;
using pointer = T*;
using const_pointer = const T*;
using reference = T&;
using const_reference = const T&;

constexpr allocator() noexcept = default;

constexpr allocator(const allocator&) noexcept = default;

template<class U>
constexpr allocator(const allocator<U>&) noexcept
{
}

constexpr ~allocator() = default;

[[nodiscard]] T* allocate(size_type n)
{
if (n > __SIZE_MAX__ / sizeof(T))
throw ctl::bad_alloc();
if (auto p = static_cast<T*>(::operator new(
n * sizeof(T), ctl::align_val_t(alignof(T)), ctl::nothrow)))
return p;
throw ctl::bad_alloc();
}

void deallocate(T* p, size_type n) noexcept
{
::operator delete(p, n * sizeof(T), ctl::align_val_t(alignof(T)));
}

template<typename U, typename... Args>
void construct(U* p, Args&&... args)
{
::new (static_cast<void*>(p)) U(ctl::forward<Args>(args)...);
}

template<typename U>
void destroy(U* p)
{
p->~U();
}

size_type max_size() const noexcept
{
return __SIZE_MAX__ / sizeof(T);
}

allocator& operator=(const allocator&) = default;

template<typename U>
struct rebind
{
using other = allocator<U>;
};
};

template<class T, class U>
bool
operator==(const allocator<T>&, const allocator<U>&) noexcept
{
return true;
}

template<class T, class U>
bool
operator!=(const allocator<T>&, const allocator<U>&) noexcept
{
return false;
}

} // namespace ctl

#endif // CTL_ALLOCATOR_H_
72 changes: 72 additions & 0 deletions ctl/allocator_traits.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#ifndef CTL_ALLOCATOR_TRAITS_H_
#define CTL_ALLOCATOR_TRAITS_H_
#include "type_traits.h"

namespace ctl {

template<typename Alloc>
struct allocator_traits
{
using allocator_type = Alloc;
using value_type = typename Alloc::value_type;
using pointer = typename Alloc::pointer;
using const_pointer = typename Alloc::const_pointer;
using void_pointer = void*;
using const_void_pointer = const void*;
using difference_type = typename Alloc::difference_type;
using size_type = typename Alloc::size_type;

using propagate_on_container_copy_assignment = false_type;
using propagate_on_container_move_assignment = true_type;
using propagate_on_container_swap = false_type;
using is_always_equal = true_type;

template<typename T>
using rebind_alloc = typename Alloc::template rebind<T>::other;

template<typename T>
using rebind_traits = allocator_traits<rebind_alloc<T>>;

__attribute__((__always_inline__)) static pointer allocate(Alloc& a,
size_type n)
{
return a.allocate(n);
}

__attribute__((__always_inline__)) static void deallocate(Alloc& a,
pointer p,
size_type n)
{
a.deallocate(p, n);
}

template<typename T, typename... Args>
__attribute__((__always_inline__)) static void construct(Alloc& a,
T* p,
Args&&... args)
{
::new ((void*)p) T(static_cast<Args&&>(args)...);
}

template<typename T>
__attribute__((__always_inline__)) static void destroy(Alloc& a, T* p)
{
p->~T();
}

__attribute__((__always_inline__)) static size_type max_size(
const Alloc& a) noexcept
{
return __PTRDIFF_MAX__ / sizeof(value_type);
}

__attribute__((__always_inline__)) static Alloc
select_on_container_copy_construction(const Alloc& a)
{
return a;
}
};

} // namespace ctl

#endif // CTL_ALLOCATOR_TRAITS_H_
22 changes: 22 additions & 0 deletions ctl/any_of.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*-
// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi
#ifndef CTL_ANY_OF_H_
#define CTL_ANY_OF_H_

namespace ctl {

template<class InputIt, class UnaryPredicate>
constexpr bool
any_of(InputIt first, InputIt last, UnaryPredicate p)
{
for (; first != last; ++first) {
if (p(*first)) {
return true;
}
}
return false;
}

} // namespace ctl

#endif // CTL_ANY_OF_H_
Loading

0 comments on commit 38921dc

Please sign in to comment.