From a092fda3883c1a131cad6a9d0f19513d2b0fd6a3 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Fri, 7 Jul 2023 19:25:13 -0700 Subject: [PATCH] Make some fixes for libcxx This change figures out some of the build configuration issues we've been having with libcxx. The c++ span header is added. Per a Discord discussion we're now turning off `-g` for the default build mode, so consider using `make MODE=dbg` or `make MODE=zero` for GDB debugging which works much better than `MODE=` ever has. Note that the default build mode has always had very good function call / system call logs plus you can still use ShowCrashReports() for backtrace. Making this change ensures cosmocc will better conform to FOSS norms. Lastly the LoadZipArgs() API has been added to cosmopolitan.a and . --- Makefile | 2 + build/config.mk | 8 +- examples/nesemu1.cc | 1 + libc/isystem/cosmo.h | 1 + libc/isystem/span | 4 + libc/isystem/stdlib.h | 1 - libc/isystem/unistd.h | 1 - third_party/libcxx/__config | 8 +- third_party/libcxx/atomic | 12 +- third_party/libcxx/ctime | 6 +- third_party/libcxx/ctype.h | 2 +- third_party/libcxx/errno.h | 2 +- third_party/libcxx/libcxx.mk | 1 + third_party/libcxx/locale.h | 3 +- third_party/libcxx/math.h | 2 +- third_party/libcxx/span | 591 +++++++++++++++++++++++++++++++++++ third_party/libcxx/stdio.h | 8 +- third_party/libcxx/stdlib.h | 12 +- 18 files changed, 636 insertions(+), 29 deletions(-) create mode 100644 libc/isystem/span create mode 100644 third_party/libcxx/span diff --git a/Makefile b/Makefile index 71fd7282e..bdd2f8e1f 100644 --- a/Makefile +++ b/Makefile @@ -307,6 +307,7 @@ loc: o/$(MODE)/tool/build/summy.com # PLEASE: MAINTAIN TOPOLOGICAL ORDER # FROM HIGHEST LEVEL TO LOWEST LEVEL COSMOPOLITAN_OBJECTS = \ + TOOL_ARGS \ NET_HTTP \ LIBC_DNS \ LIBC_SOCK \ @@ -379,6 +380,7 @@ COSMOPOLITAN_HEADERS = \ LIBC_ZIPOS \ LIBC_VGA \ NET_HTTP \ + TOOL_ARGS \ THIRD_PARTY_DLMALLOC \ THIRD_PARTY_GDTOA \ THIRD_PARTY_GETOPT \ diff --git a/build/config.mk b/build/config.mk index 18514b967..17b6f1231 100644 --- a/build/config.mk +++ b/build/config.mk @@ -6,21 +6,18 @@ # - `make` # - Optimized # - Backtraces -# - Debuggable # - Syscall tracing # - Function tracing -# - Reasonably small +# - No GDB debugging # ifeq ($(MODE),) ENABLE_FTRACE = 1 -CONFIG_OFLAGS ?= -g -CONFIG_CCFLAGS += $(BACKTRACES) -O2 +CONFIG_CCFLAGS += -O2 $(BACKTRACES) CONFIG_CPPFLAGS += -DSYSDEBUG TARGET_ARCH ?= -msse3 endif ifeq ($(MODE), aarch64) ENABLE_FTRACE = 1 -CONFIG_OFLAGS ?= -g CONFIG_CCFLAGS += -O2 $(BACKTRACES) CONFIG_CPPFLAGS += -DSYSDEBUG endif @@ -54,7 +51,6 @@ endif # - Function tracing # - Some optimizations # - Limited Backtraces -# - Compiles 28% faster # ifeq ($(MODE), fastbuild) ENABLE_FTRACE = 1 diff --git a/examples/nesemu1.cc b/examples/nesemu1.cc index d83b7666d..8c79aed9b 100644 --- a/examples/nesemu1.cc +++ b/examples/nesemu1.cc @@ -44,6 +44,7 @@ #include "libc/x/xsigaction.h" #include "libc/zip.internal.h" #include "libc/zipos/zipos.internal.h" +#include "third_party/getopt/getopt.internal.h" #include "third_party/libcxx/vector" #include "tool/viz/lib/knobs.h" diff --git a/libc/isystem/cosmo.h b/libc/isystem/cosmo.h index bb0691e9e..5bf582d7d 100644 --- a/libc/isystem/cosmo.h +++ b/libc/isystem/cosmo.h @@ -12,6 +12,7 @@ * * Users of the `cosmocc` toolchain can say, for example: * +#include "tool/args/args.h" * #include * * int main(int argc, char *argv[]) { diff --git a/libc/isystem/span b/libc/isystem/span new file mode 100644 index 000000000..5cb819c6e --- /dev/null +++ b/libc/isystem/span @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_SPAN_ +#define COSMOPOLITAN_LIBC_ISYSTEM_SPAN_ +#include "third_party/libcxx/span" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_SPAN_ */ diff --git a/libc/isystem/stdlib.h b/libc/isystem/stdlib.h index 7365e7bb9..c42e7a2eb 100644 --- a/libc/isystem/stdlib.h +++ b/libc/isystem/stdlib.h @@ -13,7 +13,6 @@ #include "libc/stdio/temp.h" #include "libc/str/str.h" #include "libc/sysv/consts/exit.h" -#include "third_party/getopt/long.h" #include "third_party/musl/crypt.h" #include "third_party/musl/rand48.h" #endif /* _STDLIB_H */ diff --git a/libc/isystem/unistd.h b/libc/isystem/unistd.h index 0e991910b..245f777ba 100644 --- a/libc/isystem/unistd.h +++ b/libc/isystem/unistd.h @@ -10,7 +10,6 @@ #include "libc/sysv/consts/o.h" #include "libc/sysv/consts/ok.h" #include "libc/time/time.h" -#include "third_party/getopt/long.h" #include "third_party/musl/crypt.h" #include "third_party/musl/lockf.h" #endif /* _UNISTD_H */ diff --git a/third_party/libcxx/__config b/third_party/libcxx/__config index eb8dce163..7e41bed6e 100644 --- a/third_party/libcxx/__config +++ b/third_party/libcxx/__config @@ -17,6 +17,7 @@ #define _LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS #define _LIBCPP_HAS_TRIVIAL_MUTEX_DESTRUCTION #define _LIBCPP_ENABLE_CXX17_REMOVED_RANDOM_SHUFFLE +#define _LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR #if defined(_MSC_VER) && !defined(__clang__) # if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -268,7 +269,7 @@ #endif #if !defined(_LIBCPP_LITTLE_ENDIAN) && !defined(_LIBCPP_BIG_ENDIAN) -#include "libc/isystem/endian.h" +#include "libc/sysv/consts/endian.h" # if __BYTE_ORDER == __LITTLE_ENDIAN # define _LIBCPP_LITTLE_ENDIAN # elif __BYTE_ORDER == __BIG_ENDIAN @@ -662,10 +663,13 @@ typedef __char32_t char32_t; #if __has_attribute(exclude_from_explicit_instantiation) # define _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION __attribute__ ((__exclude_from_explicit_instantiation__)) #else + // TODO(jart): Why is this so horrible broken with GCC? + // Many definitions end up with always_inline but not inline. + // // Try to approximate the effect of exclude_from_explicit_instantiation // (which is that entities are not assumed to be provided by explicit // template instantiations in the dylib) by always inlining those entities. -# define _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION _LIBCPP_ALWAYS_INLINE +# define _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION // _LIBCPP_ALWAYS_INLINE #endif #ifndef _LIBCPP_HIDE_FROM_ABI_PER_TU diff --git a/third_party/libcxx/atomic b/third_party/libcxx/atomic index 2d7ef1b9b..98744bed7 100644 --- a/third_party/libcxx/atomic +++ b/third_party/libcxx/atomic @@ -715,7 +715,7 @@ void __cxx_atomic_signal_fence(memory_order __order) { } template -_LIBCPP_INLINE_VISIBILITY inline +_LIBCPP_INLINE_VISIBILITY void __cxx_atomic_store(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __val, memory_order __order) { __atomic_store(&__a->__a_value, &__val, @@ -723,7 +723,7 @@ void __cxx_atomic_store(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __val, } template -_LIBCPP_INLINE_VISIBILITY inline +_LIBCPP_INLINE_VISIBILITY void __cxx_atomic_store(__cxx_atomic_base_impl<_Tp>* __a, _Tp __val, memory_order __order) { __atomic_store(&__a->__a_value, &__val, @@ -731,7 +731,7 @@ void __cxx_atomic_store(__cxx_atomic_base_impl<_Tp>* __a, _Tp __val, } template -_LIBCPP_INLINE_VISIBILITY inline +_LIBCPP_INLINE_VISIBILITY _Tp __cxx_atomic_load(const volatile __cxx_atomic_base_impl<_Tp>* __a, memory_order __order) { _Tp __ret; @@ -741,7 +741,7 @@ _Tp __cxx_atomic_load(const volatile __cxx_atomic_base_impl<_Tp>* __a, } template -_LIBCPP_INLINE_VISIBILITY inline +_LIBCPP_INLINE_VISIBILITY _Tp __cxx_atomic_load(const __cxx_atomic_base_impl<_Tp>* __a, memory_order __order) { _Tp __ret; __atomic_load(&__a->__a_value, &__ret, @@ -750,7 +750,7 @@ _Tp __cxx_atomic_load(const __cxx_atomic_base_impl<_Tp>* __a, memory_order __ord } template -_LIBCPP_INLINE_VISIBILITY inline +_LIBCPP_INLINE_VISIBILITY _Tp __cxx_atomic_exchange(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __value, memory_order __order) { _Tp __ret; @@ -760,7 +760,7 @@ _Tp __cxx_atomic_exchange(volatile __cxx_atomic_base_impl<_Tp>* __a, } template -_LIBCPP_INLINE_VISIBILITY inline +_LIBCPP_INLINE_VISIBILITY _Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp>* __a, _Tp __value, memory_order __order) { _Tp __ret; diff --git a/third_party/libcxx/ctime b/third_party/libcxx/ctime index 31df2a5af..7dfbae790 100644 --- a/third_party/libcxx/ctime +++ b/third_party/libcxx/ctime @@ -11,9 +11,11 @@ #define _LIBCPP_CTIME #include "third_party/libcxx/__config" -#include "libc/calls/weirdtypes.h" #include "libc/calls/calls.h" -#include "libc/isystem/time.h" +#include "libc/calls/struct/timespec.h" +#include "libc/calls/weirdtypes.h" +#include "libc/time/struct/tm.h" +#include "libc/time/time.h" #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/third_party/libcxx/ctype.h b/third_party/libcxx/ctype.h index b89d403ec..e6a95b2ca 100644 --- a/third_party/libcxx/ctype.h +++ b/third_party/libcxx/ctype.h @@ -35,7 +35,7 @@ int toupper(int c); #pragma GCC system_header #endif -#include "libc/isystem/ctype.h" +#include "libc/str/str.h" #ifdef __cplusplus diff --git a/third_party/libcxx/errno.h b/third_party/libcxx/errno.h index 1dfe334b6..c1210f888 100644 --- a/third_party/libcxx/errno.h +++ b/third_party/libcxx/errno.h @@ -28,7 +28,7 @@ Macros: #pragma GCC system_header #endif -#include "libc/isystem/errno.h" +#include "libc/errno.h" #ifdef __cplusplus diff --git a/third_party/libcxx/libcxx.mk b/third_party/libcxx/libcxx.mk index 1347c9c39..092fd2d98 100644 --- a/third_party/libcxx/libcxx.mk +++ b/third_party/libcxx/libcxx.mk @@ -110,6 +110,7 @@ THIRD_PARTY_LIBCXX_A_HDRS = \ third_party/libcxx/regex \ third_party/libcxx/scoped_allocator \ third_party/libcxx/set \ + third_party/libcxx/span \ third_party/libcxx/sstream \ third_party/libcxx/stack \ third_party/libcxx/stdexcept \ diff --git a/third_party/libcxx/locale.h b/third_party/libcxx/locale.h index dd61d9df2..bcf7c1a3f 100644 --- a/third_party/libcxx/locale.h +++ b/third_party/libcxx/locale.h @@ -39,6 +39,7 @@ Functions: #pragma GCC system_header #endif -#include "libc/isystem/locale.h" +#include "libc/str/locale.h" +#include "libc/str/unicode.h" #endif // _LIBCPP_LOCALE_H diff --git a/third_party/libcxx/math.h b/third_party/libcxx/math.h index 9171afc7c..6bb8d562c 100644 --- a/third_party/libcxx/math.h +++ b/third_party/libcxx/math.h @@ -19,7 +19,7 @@ #define _LIBCPP_STDLIB_INCLUDE_NEXT #include "third_party/libcxx/stdlib.h" -#include "libc/isystem/math.h" +#include "libc/math.h" #ifdef __cplusplus diff --git a/third_party/libcxx/span b/third_party/libcxx/span new file mode 100644 index 000000000..c56bed57e --- /dev/null +++ b/third_party/libcxx/span @@ -0,0 +1,591 @@ +// -*- C++ -*- +// clang-format off +//===------------------------------ span ---------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===---------------------------------------------------------------------===// + +#ifndef _LIBCPP_SPAN +#define _LIBCPP_SPAN + +/* + span synopsis + +namespace std { + +// constants +inline constexpr size_t dynamic_extent = numeric_limits::max(); + +// [views.span], class template span +template + class span; + +// [span.objectrep], views of object representation +template + span as_bytes(span s) noexcept; + +template + span< byte, ((Extent == dynamic_extent) ? dynamic_extent : + (sizeof(ElementType) * Extent))> as_writable_bytes(span s) noexcept; + + +namespace std { +template +class span { +public: + // constants and types + using element_type = ElementType; + using value_type = remove_cv_t; + using index_type = size_t; + using difference_type = ptrdiff_t; + using pointer = element_type*; + using const_pointer = const element_type*; + using reference = element_type&; + using const_reference = const element_type&; + using iterator = implementation-defined; + using const_iterator = implementation-defined; + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; + static constexpr index_type extent = Extent; + + // [span.cons], span constructors, copy, assignment, and destructor + constexpr span() noexcept; + constexpr span(pointer ptr, index_type count); + constexpr span(pointer firstElem, pointer lastElem); + template + constexpr span(element_type (&arr)[N]) noexcept; + template + constexpr span(array& arr) noexcept; + template + constexpr span(const array& arr) noexcept; + template + constexpr span(Container& cont); + template + constexpr span(const Container& cont); + constexpr span(const span& other) noexcept = default; + template + constexpr span(const span& s) noexcept; + ~span() noexcept = default; + constexpr span& operator=(const span& other) noexcept = default; + + // [span.sub], span subviews + template + constexpr span first() const; + template + constexpr span last() const; + template + constexpr span subspan() const; + + constexpr span first(index_type count) const; + constexpr span last(index_type count) const; + constexpr span subspan(index_type offset, index_type count = dynamic_extent) const; + + // [span.obs], span observers + constexpr index_type size() const noexcept; + constexpr index_type size_bytes() const noexcept; + constexpr bool empty() const noexcept; + + // [span.elem], span element access + constexpr reference operator[](index_type idx) const; + constexpr reference front() const; + constexpr reference back() const; + constexpr pointer data() const noexcept; + + // [span.iterators], span iterator support + constexpr iterator begin() const noexcept; + constexpr iterator end() const noexcept; + constexpr const_iterator cbegin() const noexcept; + constexpr const_iterator cend() const noexcept; + constexpr reverse_iterator rbegin() const noexcept; + constexpr reverse_iterator rend() const noexcept; + constexpr const_reverse_iterator crbegin() const noexcept; + constexpr const_reverse_iterator crend() const noexcept; + +private: + pointer data_; // exposition only + index_type size_; // exposition only +}; + +template + span(T (&)[N]) -> span; + +template + span(array&) -> span; + +template + span(const array&) -> span; + +template + span(Container&) -> span; + +template + span(const Container&) -> span; + +} // namespace std + +*/ + +#include "third_party/libcxx/__config" +#include "third_party/libcxx/iterator" // for iterators +#include "third_party/libcxx/array" // for array +#include "third_party/libcxx/type_traits" // for remove_cv, etc +#include "third_party/libcxx/cstddef" // for byte + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +inline constexpr size_t dynamic_extent = numeric_limits::max(); +template class span; + + +template +struct __is_span_impl : public false_type {}; + +template +struct __is_span_impl> : public true_type {}; + +template +struct __is_span : public __is_span_impl> {}; + +template +struct __is_std_array_impl : public false_type {}; + +template +struct __is_std_array_impl> : public true_type {}; + +template +struct __is_std_array : public __is_std_array_impl> {}; + +template +struct __is_span_compatible_container : public false_type {}; + +template +struct __is_span_compatible_container<_Tp, _ElementType, + void_t< + // is not a specialization of span + typename enable_if::value, nullptr_t>::type, + // is not a specialization of array + typename enable_if::value, nullptr_t>::type, + // is_array_v is false, + typename enable_if, nullptr_t>::type, + // data(cont) and size(cont) are well formed + decltype(data(declval<_Tp>())), + decltype(size(declval<_Tp>())), + // remove_pointer_t(*)[] is convertible to ElementType(*)[] + typename enable_if< + is_convertible_v()))>(*)[], + _ElementType(*)[]>, + nullptr_t>::type + >> + : public true_type {}; + + +template +class _LIBCPP_TEMPLATE_VIS span { +public: +// constants and types + using element_type = _Tp; + using value_type = remove_cv_t<_Tp>; + using index_type = size_t; + using difference_type = ptrdiff_t; + using pointer = _Tp *; + using const_pointer = const _Tp *; + using reference = _Tp &; + using const_reference = const _Tp &; + using iterator = __wrap_iter; + using const_iterator = __wrap_iter; + using reverse_iterator = _VSTD::reverse_iterator; + using const_reverse_iterator = _VSTD::reverse_iterator; + + static constexpr index_type extent = _Extent; + +// [span.cons], span constructors, copy, assignment, and destructor + _LIBCPP_INLINE_VISIBILITY constexpr span() noexcept : __data{nullptr} + { static_assert(_Extent == 0, "Can't default construct a statically sized span with size > 0"); } + + constexpr span (const span&) noexcept = default; + constexpr span& operator=(const span&) noexcept = default; + + _LIBCPP_INLINE_VISIBILITY constexpr span(pointer __ptr, index_type __count) : __data{__ptr} + { (void)__count; _LIBCPP_ASSERT(_Extent == __count, "size mismatch in span's constructor (ptr, len)"); } + _LIBCPP_INLINE_VISIBILITY constexpr span(pointer __f, pointer __l) : __data{__f} + { (void)__l; _LIBCPP_ASSERT(_Extent == distance(__f, __l), "size mismatch in span's constructor (ptr, ptr)"); } + + _LIBCPP_INLINE_VISIBILITY constexpr span(element_type (&__arr)[_Extent]) noexcept : __data{__arr} {} + _LIBCPP_INLINE_VISIBILITY constexpr span( array& __arr) noexcept : __data{__arr.data()} {} + _LIBCPP_INLINE_VISIBILITY constexpr span(const array& __arr) noexcept : __data{__arr.data()} {} + + template + _LIBCPP_INLINE_VISIBILITY + constexpr span(const span<_OtherElementType, _Extent>& __other, + enable_if_t< + is_convertible_v<_OtherElementType(*)[], element_type (*)[]>, + nullptr_t> = nullptr) + : __data{__other.data()} {} + + template + _LIBCPP_INLINE_VISIBILITY + constexpr span(const span<_OtherElementType, dynamic_extent>& __other, + enable_if_t< + is_convertible_v<_OtherElementType(*)[], element_type (*)[]>, + nullptr_t> = nullptr) noexcept + : __data{__other.data()} { _LIBCPP_ASSERT(_Extent == __other.size(), "size mismatch in span's constructor (other span)"); } + + +// ~span() noexcept = default; + + template + _LIBCPP_INLINE_VISIBILITY + constexpr span first() const noexcept + { + static_assert(_Count <= _Extent, "Count out of range in span::first()"); + return {data(), _Count}; + } + + template + _LIBCPP_INLINE_VISIBILITY + constexpr span last() const noexcept + { + static_assert(_Count <= _Extent, "Count out of range in span::last()"); + return {data() + size() - _Count, _Count}; + } + + _LIBCPP_INLINE_VISIBILITY + constexpr span first(index_type __count) const noexcept + { + _LIBCPP_ASSERT(__count <= size(), "Count out of range in span::first(count)"); + return {data(), __count}; + } + + _LIBCPP_INLINE_VISIBILITY + constexpr span last(index_type __count) const noexcept + { + _LIBCPP_ASSERT(__count <= size(), "Count out of range in span::last(count)"); + return {data() + size() - __count, __count}; + } + + template + _LIBCPP_INLINE_VISIBILITY + constexpr auto subspan() const noexcept + -> span + { + static_assert(_Offset <= _Extent, "Offset out of range in span::subspan()"); + return {data() + _Offset, _Count == dynamic_extent ? size() - _Offset : _Count}; + } + + + _LIBCPP_INLINE_VISIBILITY + constexpr span + subspan(index_type __offset, index_type __count = dynamic_extent) const noexcept + { + _LIBCPP_ASSERT(__offset <= size(), "Offset out of range in span::subspan(offset, count)"); + _LIBCPP_ASSERT(__count <= size() || __count == dynamic_extent, "Count out of range in span::subspan(offset, count)"); + if (__count == dynamic_extent) + return {data() + __offset, size() - __offset}; + _LIBCPP_ASSERT(__offset <= size() - __count, "count + offset out of range in span::subspan(offset, count)"); + return {data() + __offset, __count}; + } + + _LIBCPP_INLINE_VISIBILITY constexpr index_type size() const noexcept { return _Extent; } + _LIBCPP_INLINE_VISIBILITY constexpr index_type size_bytes() const noexcept { return _Extent * sizeof(element_type); } + _LIBCPP_INLINE_VISIBILITY constexpr bool empty() const noexcept { return _Extent == 0; } + + _LIBCPP_INLINE_VISIBILITY constexpr reference operator[](index_type __idx) const noexcept + { + _LIBCPP_ASSERT(__idx >= 0 && __idx < size(), "span[] index out of bounds"); + return __data[__idx]; + } + + _LIBCPP_INLINE_VISIBILITY constexpr reference front() const noexcept + { + static_assert(_Extent > 0, "span[].front() on empty span"); + return __data[0]; + } + + _LIBCPP_INLINE_VISIBILITY constexpr reference back() const noexcept + { + static_assert(_Extent > 0, "span[].back() on empty span"); + return __data[size()-1]; + } + + _LIBCPP_INLINE_VISIBILITY constexpr pointer data() const noexcept { return __data; } + +// [span.iter], span iterator support + _LIBCPP_INLINE_VISIBILITY constexpr iterator begin() const noexcept { return iterator(data()); } + _LIBCPP_INLINE_VISIBILITY constexpr iterator end() const noexcept { return iterator(data() + size()); } + _LIBCPP_INLINE_VISIBILITY constexpr const_iterator cbegin() const noexcept { return const_iterator(data()); } + _LIBCPP_INLINE_VISIBILITY constexpr const_iterator cend() const noexcept { return const_iterator(data() + size()); } + _LIBCPP_INLINE_VISIBILITY constexpr reverse_iterator rbegin() const noexcept { return reverse_iterator(end()); } + _LIBCPP_INLINE_VISIBILITY constexpr reverse_iterator rend() const noexcept { return reverse_iterator(begin()); } + _LIBCPP_INLINE_VISIBILITY constexpr const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(cend()); } + _LIBCPP_INLINE_VISIBILITY constexpr const_reverse_iterator crend() const noexcept { return const_reverse_iterator(cbegin()); } + + _LIBCPP_INLINE_VISIBILITY constexpr void swap(span &__other) noexcept + { + pointer __p = __data; + __data = __other.__data; + __other.__data = __p; + } + + _LIBCPP_INLINE_VISIBILITY span __as_bytes() const noexcept + { return {reinterpret_cast(data()), size_bytes()}; } + + _LIBCPP_INLINE_VISIBILITY span __as_writable_bytes() const noexcept + { return {reinterpret_cast(data()), size_bytes()}; } + +private: + pointer __data; + +}; + + +template +class _LIBCPP_TEMPLATE_VIS span<_Tp, dynamic_extent> { +private: + +public: +// constants and types + using element_type = _Tp; + using value_type = remove_cv_t<_Tp>; + using index_type = size_t; + using difference_type = ptrdiff_t; + using pointer = _Tp *; + using const_pointer = const _Tp *; + using reference = _Tp &; + using const_reference = const _Tp &; + using iterator = __wrap_iter; + using const_iterator = __wrap_iter; + using reverse_iterator = _VSTD::reverse_iterator; + using const_reverse_iterator = _VSTD::reverse_iterator; + + static constexpr index_type extent = dynamic_extent; + +// [span.cons], span constructors, copy, assignment, and destructor + _LIBCPP_INLINE_VISIBILITY constexpr span() noexcept : __data{nullptr}, __size{0} {} + + constexpr span (const span&) noexcept = default; + constexpr span& operator=(const span&) noexcept = default; + + _LIBCPP_INLINE_VISIBILITY constexpr span(pointer __ptr, index_type __count) : __data{__ptr}, __size{__count} {} + _LIBCPP_INLINE_VISIBILITY constexpr span(pointer __f, pointer __l) : __data{__f}, __size{static_cast(distance(__f, __l))} {} + + template + _LIBCPP_INLINE_VISIBILITY + constexpr span(element_type (&__arr)[_Sz]) noexcept : __data{__arr}, __size{_Sz} {} + + template + _LIBCPP_INLINE_VISIBILITY + constexpr span(array& __arr) noexcept : __data{__arr.data()}, __size{_Sz} {} + + template + _LIBCPP_INLINE_VISIBILITY + constexpr span(const array& __arr) noexcept : __data{__arr.data()}, __size{_Sz} {} + + template + _LIBCPP_INLINE_VISIBILITY + constexpr span( _Container& __c, + enable_if_t<__is_span_compatible_container<_Container, _Tp>::value, nullptr_t> = nullptr) + : __data{_VSTD::data(__c)}, __size{(index_type) _VSTD::size(__c)} {} + + template + _LIBCPP_INLINE_VISIBILITY + constexpr span(const _Container& __c, + enable_if_t<__is_span_compatible_container::value, nullptr_t> = nullptr) + : __data{_VSTD::data(__c)}, __size{(index_type) _VSTD::size(__c)} {} + + + template + _LIBCPP_INLINE_VISIBILITY + constexpr span(const span<_OtherElementType, _OtherExtent>& __other, + enable_if_t< + is_convertible_v<_OtherElementType(*)[], element_type (*)[]>, + nullptr_t> = nullptr) noexcept + : __data{__other.data()}, __size{__other.size()} {} + +// ~span() noexcept = default; + + template + _LIBCPP_INLINE_VISIBILITY + constexpr span first() const noexcept + { + _LIBCPP_ASSERT(_Count <= size(), "Count out of range in span::first()"); + return {data(), _Count}; + } + + template + _LIBCPP_INLINE_VISIBILITY + constexpr span last() const noexcept + { + _LIBCPP_ASSERT(_Count <= size(), "Count out of range in span::last()"); + return {data() + size() - _Count, _Count}; + } + + _LIBCPP_INLINE_VISIBILITY + constexpr span first(index_type __count) const noexcept + { + _LIBCPP_ASSERT(__count <= size(), "Count out of range in span::first(count)"); + return {data(), __count}; + } + + _LIBCPP_INLINE_VISIBILITY + constexpr span last (index_type __count) const noexcept + { + _LIBCPP_ASSERT(__count <= size(), "Count out of range in span::last(count)"); + return {data() + size() - __count, __count}; + } + + template + _LIBCPP_INLINE_VISIBILITY + constexpr span<_Tp, dynamic_extent> subspan() const noexcept + { + _LIBCPP_ASSERT(_Offset <= size(), "Offset out of range in span::subspan()"); + _LIBCPP_ASSERT(_Count == dynamic_extent || _Offset + _Count <= size(), "Count out of range in span::subspan()"); + return {data() + _Offset, _Count == dynamic_extent ? size() - _Offset : _Count}; + } + + constexpr span + _LIBCPP_INLINE_VISIBILITY + subspan(index_type __offset, index_type __count = dynamic_extent) const noexcept + { + _LIBCPP_ASSERT(__offset <= size(), "Offset out of range in span::subspan(offset, count)"); + _LIBCPP_ASSERT(__count <= size() || __count == dynamic_extent, "count out of range in span::subspan(offset, count)"); + if (__count == dynamic_extent) + return {data() + __offset, size() - __offset}; + _LIBCPP_ASSERT(__offset <= size() - __count, "Offset + count out of range in span::subspan(offset, count)"); + return {data() + __offset, __count}; + } + + _LIBCPP_INLINE_VISIBILITY constexpr index_type size() const noexcept { return __size; } + _LIBCPP_INLINE_VISIBILITY constexpr index_type size_bytes() const noexcept { return __size * sizeof(element_type); } + _LIBCPP_INLINE_VISIBILITY constexpr bool empty() const noexcept { return __size == 0; } + + _LIBCPP_INLINE_VISIBILITY constexpr reference operator[](index_type __idx) const noexcept + { + _LIBCPP_ASSERT(__idx >= 0 && __idx < size(), "span[] index out of bounds"); + return __data[__idx]; + } + + _LIBCPP_INLINE_VISIBILITY constexpr reference front() const noexcept + { + _LIBCPP_ASSERT(!empty(), "span[].front() on empty span"); + return __data[0]; + } + + _LIBCPP_INLINE_VISIBILITY constexpr reference back() const noexcept + { + _LIBCPP_ASSERT(!empty(), "span[].back() on empty span"); + return __data[size()-1]; + } + + + _LIBCPP_INLINE_VISIBILITY constexpr pointer data() const noexcept { return __data; } + +// [span.iter], span iterator support + _LIBCPP_INLINE_VISIBILITY constexpr iterator begin() const noexcept { return iterator(data()); } + _LIBCPP_INLINE_VISIBILITY constexpr iterator end() const noexcept { return iterator(data() + size()); } + _LIBCPP_INLINE_VISIBILITY constexpr const_iterator cbegin() const noexcept { return const_iterator(data()); } + _LIBCPP_INLINE_VISIBILITY constexpr const_iterator cend() const noexcept { return const_iterator(data() + size()); } + _LIBCPP_INLINE_VISIBILITY constexpr reverse_iterator rbegin() const noexcept { return reverse_iterator(end()); } + _LIBCPP_INLINE_VISIBILITY constexpr reverse_iterator rend() const noexcept { return reverse_iterator(begin()); } + _LIBCPP_INLINE_VISIBILITY constexpr const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(cend()); } + _LIBCPP_INLINE_VISIBILITY constexpr const_reverse_iterator crend() const noexcept { return const_reverse_iterator(cbegin()); } + + _LIBCPP_INLINE_VISIBILITY constexpr void swap(span &__other) noexcept + { + pointer __p = __data; + __data = __other.__data; + __other.__data = __p; + + index_type __sz = __size; + __size = __other.__size; + __other.__size = __sz; + } + + _LIBCPP_INLINE_VISIBILITY span __as_bytes() const noexcept + { return {reinterpret_cast(data()), size_bytes()}; } + + _LIBCPP_INLINE_VISIBILITY span __as_writable_bytes() const noexcept + { return {reinterpret_cast(data()), size_bytes()}; } + +private: + pointer __data; + index_type __size; +}; + +// tuple interface +template +struct _LIBCPP_TEMPLATE_VIS tuple_size> + : public integral_constant {}; + +template +struct _LIBCPP_TEMPLATE_VIS tuple_size>; // declared but not defined + + +template +struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, span<_Tp, _Size>> +{ + static_assert( dynamic_extent != _Size, "std::tuple_element<> not supported for std::span"); + static_assert(_Ip < _Size, "Index out of bounds in std::tuple_element<> (std::span)"); + typedef _Tp type; +}; + +template +_LIBCPP_INLINE_VISIBILITY constexpr +_Tp& +get(span<_Tp, _Size> __s) noexcept +{ + static_assert( dynamic_extent != _Size, "std::get<> not supported for std::span"); + static_assert(_Ip < _Size, "Index out of bounds in std::get<> (std::span)"); + return __s[_Ip]; +} + + +// as_bytes & as_writable_bytes +template +_LIBCPP_INLINE_VISIBILITY +auto as_bytes(span<_Tp, _Extent> __s) noexcept +-> decltype(__s.__as_bytes()) +{ return __s.__as_bytes(); } + +template +_LIBCPP_INLINE_VISIBILITY +auto as_writable_bytes(span<_Tp, _Extent> __s) noexcept +-> enable_if_t, decltype(__s.__as_writable_bytes())> +{ return __s.__as_writable_bytes(); } + +template +_LIBCPP_INLINE_VISIBILITY +constexpr void swap(span<_Tp, _Extent> &__lhs, span<_Tp, _Extent> &__rhs) noexcept +{ __lhs.swap(__rhs); } + + +// Deduction guides +template + span(_Tp (&)[_Sz]) -> span<_Tp, _Sz>; + +template + span(array<_Tp, _Sz>&) -> span<_Tp, _Sz>; + +template + span(const array<_Tp, _Sz>&) -> span; + +template + span(_Container&) -> span; + +template + span(const _Container&) -> span; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_SPAN diff --git a/third_party/libcxx/stdio.h b/third_party/libcxx/stdio.h index d8a22deac..d8e99b90e 100644 --- a/third_party/libcxx/stdio.h +++ b/third_party/libcxx/stdio.h @@ -13,8 +13,6 @@ #pragma GCC system_header #endif -#include "libc/isystem/stdio.h" - #elif !defined(_LIBCPP_STDIO_H) #define _LIBCPP_STDIO_H @@ -104,7 +102,11 @@ void perror(const char* s); #pragma GCC system_header #endif -#include "libc/isystem/stdio.h" +#include "libc/fmt/fmt.h" +#include "libc/calls/calls.h" +#include "libc/stdio/temp.h" +#include "libc/fmt/fmt.h" +#include "libc/stdio/stdio.h" #ifdef __cplusplus diff --git a/third_party/libcxx/stdlib.h b/third_party/libcxx/stdlib.h index cda86e9ac..a561dc78f 100644 --- a/third_party/libcxx/stdlib.h +++ b/third_party/libcxx/stdlib.h @@ -9,6 +9,14 @@ #if defined(__need_malloc_and_calloc) || defined(_LIBCPP_STDLIB_INCLUDE_NEXT) +#include "libc/stdio/rand.h" +#include "libc/mem/mem.h" +#include "libc/runtime/runtime.h" +#include "libc/runtime/runtime.h" +#include "libc/mem/alg.h" +#include "libc/stdio/stdio.h" +#include "libc/fmt/conv.h" + #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header #endif @@ -17,8 +25,6 @@ #undef _LIBCPP_STDLIB_INCLUDE_NEXT #endif -#include "libc/isystem/stdlib.h" - #elif !defined(_LIBCPP_STDLIB_H) #define _LIBCPP_STDLIB_H @@ -28,8 +34,6 @@ #pragma GCC system_header #endif -#include "libc/isystem/stdlib.h" - #ifdef __cplusplus #include "third_party/libcxx/math.h" #endif // __cplusplus