From 46a4c759bb75716b0b664cbe9028175db436bffb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C5=8Dshin?= Date: Sat, 8 Jun 2024 14:30:58 -0700 Subject: [PATCH] Provide a minimal new.h for CTL This replaces the STL header. Mainly, it defines a global operator new and operator delete, as well as the placement versions of these. The placement versions are required to not get compile errors when trying to write a placement new statement. Each of these operators is defined with many, many different variants. A glance at new.cc is recommended followed by a chaser of the Alexandrescu talk "std::allocator is to Allocation as std::vector is to Vexation". We must provide a global-namespace source-level definition of each operator and it is illegal for any of them to be marked inline, so here we are. The upshot is that we no longer need to include , and our optional/ vector headers are self-contained. --- ctl/new.cc | 116 ++++++++++++++++++++++++++++++++++++++ ctl/new.h | 30 ++++++++++ ctl/optional.h | 4 +- ctl/vector.h | 1 + test/ctl/optional_test.cc | 4 +- test/ctl/vector_test.cc | 1 - 6 files changed, 152 insertions(+), 4 deletions(-) create mode 100644 ctl/new.cc create mode 100644 ctl/new.h diff --git a/ctl/new.cc b/ctl/new.cc new file mode 100644 index 000000000..0ee5a461b --- /dev/null +++ b/ctl/new.cc @@ -0,0 +1,116 @@ +// -*- mode:c++; indent-tabs-mode:nil; c-basic-offset:4; coding:utf-8 -*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +// +// Copyright 2024 Justine Alexandra Roberts Tunney +// +// Permission to use, copy, modify, and/or distribute this software for +// any purpose with or without fee is hereby granted, provided that the +// above copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +// WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +// AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL +// DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR +// PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +// PERFORMANCE OF THIS SOFTWARE. + +#include "new.h" + +#include "libc/mem/mem.h" + +using ctl::align_val_t; + +namespace { + +constexpr auto a1 = align_val_t(1); + +} // namespace + +void* +operator new(size_t n, align_val_t a) +{ + void* p; + if (!(p = memalign(static_cast(a), n))) { + __builtin_trap(); + } + return p; +} + +void* +operator new[](size_t n, ctl::align_val_t a) +{ + return operator new(n, a); +} +void* +operator new(size_t n) +{ + return operator new(n, a1); +} +void* +operator new[](size_t n) +{ + return operator new(n, a1); +} + +void* +operator new(size_t, void* p) +{ + return p; +} +void* +operator new[](size_t, void* p) +{ + return p; +} + +void +operator delete(void* p) noexcept +{ + free(p); +} +void +operator delete[](void* p) noexcept +{ + free(p); +} +void +operator delete(void* p, ctl::align_val_t) noexcept +{ + free(p); +} +void +operator delete[](void* p, ctl::align_val_t) noexcept +{ + free(p); +} +void +operator delete(void* p, size_t) noexcept +{ + free(p); +} +void +operator delete[](void* p, size_t) noexcept +{ + free(p); +} +void +operator delete(void* p, size_t, ctl::align_val_t) noexcept +{ + free(p); +} +void +operator delete[](void* p, size_t, ctl::align_val_t) noexcept +{ + free(p); +} + +void +operator delete(void*, void*) noexcept +{ +} +void +operator delete[](void*, void*) noexcept +{ +} diff --git a/ctl/new.h b/ctl/new.h new file mode 100644 index 000000000..15b84488e --- /dev/null +++ b/ctl/new.h @@ -0,0 +1,30 @@ +// -*-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 COSMOPOLITAN_CTL_NEW_H_ +#define COSMOPOLITAN_CTL_NEW_H_ + +// clang-format off + +namespace ctl { + +enum class align_val_t : size_t {}; + +} // namespace ctl + +void* operator new(size_t); +void* operator new[](size_t); +void* operator new(size_t, ctl::align_val_t); +void* operator new[](size_t, ctl::align_val_t); +void* operator new(size_t, void*); +void* operator new[](size_t, void*); + +void operator delete(void*) noexcept; +void operator delete[](void*) noexcept; +void operator delete(void*, ctl::align_val_t) noexcept; +void operator delete[](void*, ctl::align_val_t) noexcept; +void operator delete(void*, size_t) noexcept; +void operator delete[](void*, size_t) noexcept; +void operator delete(void*, size_t, ctl::align_val_t) noexcept; +void operator delete[](void*, size_t, ctl::align_val_t) noexcept; + +#endif // COSMOPOLITAN_CTL_NEW_H_ diff --git a/ctl/optional.h b/ctl/optional.h index e3214da31..110bd5eec 100644 --- a/ctl/optional.h +++ b/ctl/optional.h @@ -2,6 +2,7 @@ // vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi #ifndef COSMOPOLITAN_CTL_OPTIONAL_H_ #define COSMOPOLITAN_CTL_OPTIONAL_H_ +#include "new.h" #include <__utility/forward.h> #include <__utility/move.h> #include <__utility/swap.h> @@ -129,7 +130,8 @@ class optional } private: - union { + union + { T value_; }; bool present_; diff --git a/ctl/vector.h b/ctl/vector.h index 0b77b08fc..8c9660909 100644 --- a/ctl/vector.h +++ b/ctl/vector.h @@ -2,6 +2,7 @@ // vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi #ifndef COSMOPOLITAN_CTL_OPTIONAL_H_ #define COSMOPOLITAN_CTL_OPTIONAL_H_ +#include "new.h" #include <__utility/forward.h> #include <__utility/move.h> #include <__utility/swap.h> diff --git a/test/ctl/optional_test.cc b/test/ctl/optional_test.cc index 49133e7d9..c00f30d5b 100644 --- a/test/ctl/optional_test.cc +++ b/test/ctl/optional_test.cc @@ -18,10 +18,10 @@ #include "ctl/optional.h" -#include - #include "ctl/string.h" +#include "libc/runtime/runtime.h" + // #include // #include // #define ctl std diff --git a/test/ctl/vector_test.cc b/test/ctl/vector_test.cc index 01d2301f7..214eef454 100644 --- a/test/ctl/vector_test.cc +++ b/test/ctl/vector_test.cc @@ -19,7 +19,6 @@ #include "ctl/vector.h" #include -#include #include "ctl/string.h"