diff --git a/AK/AK/Array.h b/AK/AK/Array.h deleted file mode 100644 index abaad5b..0000000 --- a/AK/AK/Array.h +++ /dev/null @@ -1,61 +0,0 @@ -#pragma once - -#include -#include "./AK/Iterator.h" -#include "./AK/Span.h" - -namespace AK { - -template -struct Array { - using ValueType = T; - - constexpr T* data(); - - constexpr size_t size(); - - constexpr Span span(); - - constexpr T const& at(size_t index) const; - - constexpr T const& first() const; - constexpr T const& last() const requires(Size > 0); - - constexpr bool is_empty() const { return size() == 0; } - - constexpr T const& operator[](size_t index) const; - - template - constexpr bool operator==(Array const& other); - - using ConstIterator = SimpleIterator; - using Iterator = SimpleIterator; - - constexpr ConstIterator begin() const { return ConstIterator::begin(*this); } - constexpr Iterator begin() { return Iterator::begin(*this); } - - constexpr ConstIterator end() const { return ConstIterator::end(*this); } - constexpr Iterator end() { return Iterator::end(*this); } - - constexpr operator Span() const; - - T __data[Size]; -}; - -template -Array(T, Types...)->Array; - -namespace Detail { - -template -constexpr auto integer_sequence_generate_array([[maybe_unused]] T const offset, IntegerSequence)->Array; - -} - -template -constexpr static auto iota_array(T const offset = {}); - -} - -using AK::Array; -using AK::iota_array; diff --git a/AK/AK/Atomic.h b/AK/AK/Atomic.h deleted file mode 100644 index e12206c..0000000 --- a/AK/AK/Atomic.h +++ /dev/null @@ -1,51 +0,0 @@ -#pragma once - -#include "./AK/Concepts.h" -#include "./AK/Platform.h" -#include "./AK/Types.h" - -namespace AK { - -template -/*static*/ ALWAYS_INLINE T atomic_exchange(volatile T* var, T desired, MemoryOrder order = memory_order_seq_cst) noexcept; - -template> -/*static*/ ALWAYS_INLINE V* atomic_exchange(volatile T** var, V* desired, MemoryOrder order = memory_order_seq_cst) noexcept; - -template> -/*static*/ ALWAYS_INLINE V* atomic_exchange(volatile T** var, std::nullptr_t, MemoryOrder order = memory_order_seq_cst) noexcept; - -template -/*static*/ ALWAYS_INLINE bool atomic_compare_exchange_strong(volatile T* var, T& expected, T desired, MemoryOrder order = memory_order_seq_cst) noexcept; - -template> -/*static*/ ALWAYS_INLINE bool atomic_compare_exchange_strong(volatile T** var, V*& expected, V* desired, MemoryOrder order = memory_order_seq_cst) noexcept; - -template> -/*static*/ ALWAYS_INLINE bool atomic_compare_exchange_strong(volatile T** var, V*& expected, std::nullptr_t, MemoryOrder order = memory_order_seq_cst) noexcept; - -template -/*static*/ ALWAYS_INLINE T atomic_fetch_add(volatile T* var, T val, MemoryOrder order = memory_order_seq_cst) noexcept; - -template -/*static*/ ALWAYS_INLINE T atomic_fetch_sub(volatile T* var, T val, MemoryOrder order = memory_order_seq_cst) noexcept; - -template -/*static*/ ALWAYS_INLINE T atomic_fetch_and(volatile T* var, T val, MemoryOrder order = memory_order_seq_cst) noexcept; - -template -/*static*/ ALWAYS_INLINE T atomic_fetch_or(volatile T* var, T val, MemoryOrder order = memory_order_seq_cst) noexcept; - -template -/*static*/ ALWAYS_INLINE T atomic_fetch_xor(volatile T* var, T val, MemoryOrder order = memory_order_seq_cst) noexcept; - -template -/*static*/ ALWAYS_INLINE bool atomic_is_lock_free(volatile T* ptr = nullptr) noexcept; - -template -class Atomic { - - -}; - -} diff --git a/AK/AK/Format.cpp b/AK/AK/Format.cpp deleted file mode 100644 index 6db7813..0000000 --- a/AK/AK/Format.cpp +++ /dev/null @@ -1,2 +0,0 @@ -#include "pch.h" -#include "./AK/Format.h" diff --git a/AK/AK/IntrusiveList.cpp b/AK/AK/IntrusiveList.cpp deleted file mode 100644 index 36bff7d..0000000 --- a/AK/AK/IntrusiveList.cpp +++ /dev/null @@ -1,2 +0,0 @@ -#include "pch.h" -#include "./AK/IntrusiveList.h" diff --git a/AK/AK/String.h b/AK/AK/String.h deleted file mode 100644 index 292dccc..0000000 --- a/AK/AK/String.h +++ /dev/null @@ -1,168 +0,0 @@ -#pragma once - -#include "./AK/Format.h" -#include "./AK/Forward.h" -#include "./AK/RefPtr.h" -//#include "./AK/Stream.h" -#include "./AK/StringBuilder.h" -#include "./AK/StringImpl.h" -#include "./AK/StringUtils.h" -#include "./AK/Traits.h" - -namespace AK { - -class String { -public: - ~String() = default; - - String() = default; - - String(StringView view); - String(String const& other); - String(String&& other); - String(char const* cstring, ShouldChomp shouldChomp = NoChomp); - String(char const* cstring, size_t length, ShouldChomp shouldChomp = NoChomp); - explicit String(ReadonlyBytes bytes, ShouldChomp shouldChomp = NoChomp); - String(StringImpl const& impl); - String(StringImpl const* impl); - String(RefPtr&& impl); - String(NonnullRefPtr&& impl); - String(FlyString const&); - - static String repeated(char, size_t count); - static String repeated(StringView, size_t count); - - static String bijective_base_from(size_t value, unsigned base = 26, StringView map = {}); - static String roman_number_from(size_t value); - - template - static String join(SeparatorType const& separator, CollectionType const& collection, StringView fmtstr = "{}"sv) - { - StringBuilder builder; - builder.join(separator, collection, fmtstr); - return builder.build(); - } - - bool matches(StringView mask, CaseSensitivity = CaseSensitivity::CaseInsensitive) const; - bool matches(StringView mask, Vector&, CaseSensitivity = CaseSensitivity::CaseInsensitive) const; - - template - Optional to_int(TrimWhitespace = TrimWhitespace::Yes) const; - template - Optional to_uint(TrimWhitespace = TrimWhitespace::Yes) const; - - bool contains(StringView, CaseSensitivity = CaseSensitivity::CaseSensitive) const; - bool contains(char, CaseSensitivity = CaseSensitivity::CaseSensitive) const; - - Vector split_limit(char separator, size_t limit, bool keep_empty = false) const; - Vector split(char separator, bool keep_empty = false) const; - Vector split_view(char separator, bool keep_empty = false) const; - Vector split_view(Function separator, bool keep_empty = false) const; - - Optional find(char needle, size_t start = 0) const; - Optional find(StringView needle, size_t start = 0) const; - Optional find_last(char needle) const; - Vector find_all(StringView needle) const; - using SearchDirection = StringUtils::SearchDirection; - Optional find_any_of(StringView needles, SearchDirection direction) const; - - String substring(size_t start, size_t length) const; - String substring(size_t start) const; - StringView substring_view(size_t start, size_t length) const; - StringView substring_view(size_t start) const; - - ALWAYS_INLINE ReadonlyBytes bytes() const; - - ALWAYS_INLINE char const& operator[](size_t i) const; - - using ConstIterator = SimpleIterator; - - constexpr ConstIterator begin() const { return ConstIterator::begin(*this); } - constexpr ConstIterator end() const { return ConstIterator::end(*this); } - - bool starts_with(StringView, CaseSensitivity = CaseSensitivity::CaseSensitive) const; - bool ends_with(StringView, CaseSensitivity = CaseSensitivity::CaseSensitive) const; - bool starts_with(char) const; - bool ends_with(char) const; - - bool is_null() const { return !m_impl; } - ALWAYS_INLINE bool is_empty() const { return true; } - ALWAYS_INLINE size_t length() const { return m_impl ? m_impl->length() : 0; } - char* characters() const; - - u32 hash() const { return 0; } - - static String vformatted(StringView fmtstr, TypeErasedFormatParams&); - - template - static String formatted(CheckedFormatString&& fmtstr, Parameters const&... parameters); - - template - static String number(T value) requires IsArithmetic; - - static String empty(); - - bool operator==(String const&) const; - bool operator!=(String const& other) const; - - bool operator==(StringView) const; - bool operator!=(StringView other) const; - - bool operator==(FlyString const&) const; - bool operator!=(FlyString const& other) const; - - bool operator<(String const&) const; - bool operator<(char const*) const; - bool operator>=(String const& other) const; - bool operator>=(char const* other) const; - - bool operator>(String const&) const; - bool operator>(char const*) const; - bool operator<=(String const& other) const; - bool operator<=(char const* other) const; - - bool operator==(char const* cstring) const; - bool operator!=(char const* cstring) const; - - String& operator=(String&& other); - - String& operator=(String const& other); - - String& operator=(std::nullptr_t); - - String& operator=(ReadonlyBytes bytes); - - StringView view() const; - - String replace(StringView needle, StringView replacement, ReplaceMode replace_mode) const; - size_t count(StringView needle) const; - String reverse() const; - - template - ALWAYS_INLINE constexpr bool is_one_of(Ts&&... strings) const; - - template - ALWAYS_INLINE constexpr bool is_one_of_ignoring_case(Ts&&... strings) const; - -private: - RefPtr m_impl; -}; - -template<> -struct Traits : public GenericTraits { - static unsigned hash(String const& s); -}; - -struct CaseInsensitiveStringTraits : public Traits { - static unsigned hash(String const& s); - static bool equals(String const& a, String const& b); -}; - -String escape_html_entities(StringView html); - -//InputStream& operator>>(InputStream& stream, String& string); - -} - -using AK::escape_html_entities; -using AK::String; diff --git a/AK/AK/StringBuilder.h b/AK/AK/StringBuilder.h deleted file mode 100644 index 97cca0d..0000000 --- a/AK/AK/StringBuilder.h +++ /dev/null @@ -1,62 +0,0 @@ -#pragma once - -#include "./AK/ByteBuffer.h" -#include "./AK/Format.h" -#include "./AK/Forward.h" -#include "./AK/StringView.h" - -namespace AK { - -class StringBuilder { -public: - using OutputType = String; - - explicit StringBuilder(size_t initial_capacity = inline_capacity); - ~StringBuilder() = default; - - ErrorOr try_append(StringView); - ErrorOr try_append_code_point(u32); - ErrorOr try_append(char); - template - ErrorOr try_appendff(CheckedFormatString&& fmtstr, Parameters const&... parameters); - - void append(StringView) {} - void append(Utf16View const&); - void append(Utf32View const&); - void append(char) {} - void append_code_point(u32) {} - void append(char const*, size_t) {} - void appendvf(char const*, va_list) {} - - void append_as_lowercase(char) {} - void append_escaped_for_json(StringView) {} - - template - void appendff(CheckedFormatString&& fmtstr, Parameters const&... parameters) {} - - String build() const; - String to_string() const; - ByteBuffer to_byte_buffer() const; - - StringView string_view() const; - - void clear() {} - - size_t length() const { return 0; } - bool is_empty() const { return true; } - void trim(size_t count) { /*m_buffer.resize(m_buffer.size() - count);*/ } - - template - void join(SeparatorType const& separator, CollectionType const& collection, StringView fmtstr = "{}"sv) {} - -private: - ErrorOr will_append(size_t); - u8* data() { return m_buffer.data(); } - - static constexpr size_t inline_capacity = 256; - AK::Detail::ByteBuffer m_buffer; -}; - -} - -using AK::StringBuilder; \ No newline at end of file diff --git a/AK/AK/StringImpl.cpp b/AK/AK/StringImpl.cpp deleted file mode 100644 index 5365c2e..0000000 --- a/AK/AK/StringImpl.cpp +++ /dev/null @@ -1,9 +0,0 @@ -#include "pch.h" -#include "./AK/CharacterTypes.h" -#include "./AK/FlyString.h" -#include "./AK/HashTable.h" -#include "./AK/Memory.h" -#include "./AK/StdLibExtras.h" -#include "./AK/StringHash.h" -#include "./AK/StringImpl.h" -#include "./AK/kmalloc.h" diff --git a/AK/AK/StringUtils.cpp b/AK/AK/StringUtils.cpp deleted file mode 100644 index dea40c2..0000000 --- a/AK/AK/StringUtils.cpp +++ /dev/null @@ -1,2 +0,0 @@ -#include "pch.h" -#include "./AK/StringUtils.h" diff --git a/AK/AK/StringView.cpp b/AK/AK/StringView.cpp deleted file mode 100644 index 47b61ee..0000000 --- a/AK/AK/StringView.cpp +++ /dev/null @@ -1,18 +0,0 @@ -#include "pch.h" -#include "StringView.h" - -namespace AK { - -StringView::StringView(ByteBuffer const&) -{ -} - -StringView::StringView(String const&) -{ -} - -StringView::StringView(FlyString const&) -{ -} - -} \ No newline at end of file diff --git a/AK/AK/StringView.h b/AK/AK/StringView.h deleted file mode 100644 index 6fb7b7a..0000000 --- a/AK/AK/StringView.h +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright (c) 2018-2021, Andreas Kling - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once -#pragma warning(disable: 4455) - -#include "./AK/Assertions.h" -#include "./AK/Checked.h" -#include "./AK/Forward.h" -#include "./AK/Optional.h" -#include "./AK/Span.h" -#include "./AK/StdLibExtras.h" -#include "./AK/StringHash.h" -#include "./AK/StringUtils.h" - -namespace AK { - -class StringView { -public: - ALWAYS_INLINE constexpr StringView() = default; - ALWAYS_INLINE constexpr StringView(char const* characters, size_t length) - : m_characters(characters) - , m_length(length) - { - if (!is_constant_evaluated()) - VERIFY(!Checked::addition_would_overflow((uintptr_t)characters, length)); - } - ALWAYS_INLINE StringView(unsigned char const* characters, size_t length) - : m_characters((char const*)characters) - , m_length(length) - { - //VERIFY(!Checked::addition_would_overflow((uintptr_t)characters, length)); - } - ALWAYS_INLINE StringView(ReadonlyBytes bytes) - : m_characters(reinterpret_cast(bytes.data())) - , m_length(bytes.size()) - { - } - - StringView(ByteBuffer const&); - StringView(String const&); - StringView(FlyString const&); - - explicit StringView(ByteBuffer&&) = delete; - explicit StringView(String&&) = delete; - explicit StringView(FlyString&&) = delete; - - constexpr bool is_null() const; - constexpr bool is_empty() const { return m_length == 0; } - - constexpr char const* characters_without_null_termination() const { return m_characters; } - constexpr size_t length() const { return m_length; } - - ReadonlyBytes bytes() const; - constexpr char const& operator[](size_t index) const; - - constexpr StringView substring_view(size_t start, size_t length) const; - constexpr StringView substring_view(size_t start) const; - - StringView replace(StringView, StringView, ReplaceMode) const; - constexpr int compare() { return 0; } - - constexpr int* begin() const { return 0; } - constexpr int* end() const { return 0; } - - constexpr unsigned hash() const; - - bool starts_with(StringView, CaseSensitivity = CaseSensitivity::CaseSensitive) const; - bool ends_with(StringView, CaseSensitivity = CaseSensitivity::CaseSensitive) const; - bool starts_with(char) const; - bool ends_with(char) const; - bool matches(StringView mask, CaseSensitivity = CaseSensitivity::CaseInsensitive) const; - bool matches(StringView mask, Vector&, CaseSensitivity = CaseSensitivity::CaseInsensitive) const; - bool contains(char) const; - bool contains(StringView, CaseSensitivity = CaseSensitivity::CaseSensitive) const; - bool equals_ignoring_case(StringView other) const; - - StringView trim(StringView characters, TrimMode mode = TrimMode::Both) const; - StringView trim_whitespace(TrimMode mode = TrimMode::Both) const; - - String to_lowercase_string() const; - String to_uppercase_string() const; - String to_titlecase_string() const; - - Optional find(char needle, size_t start = 0) const; - Optional find(StringView needle, size_t start = 0) const; - Optional find_last(char needle) const; - - Vector find_all(StringView needle); - - using SearchDirection = StringUtils::SearchDirection; - Optional find_any_of(StringView needles, SearchDirection direction = SearchDirection::Forward) const; - - Vector lines(bool consider_cr = true) const; - - template - Optional to_int() const; - template - Optional to_uint() const; - - StringView substring_view_starting_from_substring(StringView substring) const; - StringView substring_view_starting_after_substring(StringView substring) const; - - bool copy_characters_to_buffer(char* buffer, size_t buffer_size) const; - - bool operator==(StringView other) const { return false; } - constexpr bool operator==(char const* cstring) const { return false; } - constexpr bool operator!=(StringView other) const { return false; } - bool operator<(StringView other) const { return false; } - bool operator<=(StringView other) const { return false; } - bool operator>(StringView other) const { return false; } - bool operator>=(StringView other) const { return false; } - - String to_string() const; - - template - ALWAYS_INLINE constexpr bool is_one_of(Ts&&... strings) const - { - return (... || this->operator==(forward(strings))); - } - - template - ALWAYS_INLINE constexpr bool is_one_of_ignoring_case(Ts&&... strings) const - { - return (... || - [this, &strings]() -> bool { - if constexpr (requires(Ts a) { a.view()->StringView; }) - return this->equals_ignoring_case(forward(strings.view())); - else - return this->equals_ignoring_case(forward(strings)); - }()); - } - -private: - friend class String; - char const* m_characters{ nullptr }; - size_t m_length{ 0 }; -}; - -} - -ALWAYS_INLINE constexpr AK::StringView operator"" sv(char const* cstring, size_t length) -{ - return AK::StringView(cstring, length); -} - -using AK::StringView; diff --git a/AK/AK/Time.cpp b/AK/AK/Time.cpp deleted file mode 100644 index 8aec5b1..0000000 --- a/AK/AK/Time.cpp +++ /dev/null @@ -1,12 +0,0 @@ -#include "pch.h" -#include "Time.h" - -unsigned AK::day_of_week(int year, unsigned month, int day) -{ - VERIFY(month >= 1 && month <= 12); - constexpr Array seek_table = { 0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4 }; - if (month < 3) - --year; - - return (year + year / 4 - year / 100 + year / 400 + seek_table[month - 1] + day) % 7; -} diff --git a/AK/AK/Vector.h b/AK/AK/Vector.h deleted file mode 100644 index 699a295..0000000 --- a/AK/AK/Vector.h +++ /dev/null @@ -1,297 +0,0 @@ -/* - * Copyright (c) 2018-2021, Andreas Kling - * Copyright (c) 2021, the SerenityOS developers. - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include "./AK/Assertions.h" -#include "./AK/Error.h" -#include "./AK/Find.h" -#include "./AK/Forward.h" -#include "./AK/Iterator.h" -#include "./AK/Optional.h" -#include "./AK/ReverseIterator.h" -#include "./AK/Span.h" -#include "./AK/StdLibExtras.h" -#include "./AK/Traits.h" -#include "./AK/TypedTransfer.h" -#include "./AK/kmalloc.h" -#include - -namespace AK { - -namespace Detail { - -template -struct CanBePlacedInsideVectorHelper; - -template -struct CanBePlacedInsideVectorHelper { - template - static constexpr bool value = requires(U && u) { StorageType{ &u }; }; -}; - -template -struct CanBePlacedInsideVectorHelper { - template - static constexpr bool value = requires(U && u) { StorageType(forward(u)); }; -}; - -} - -template -requires(!IsRvalueReference) class Vector { - private: - static constexpr bool contains_reference = IsLvalueReference; - using StorageType = Conditional>, T>; - - using VisibleType = RemoveReference; - - template - static constexpr bool CanBePlacedInsideVector = Detail::CanBePlacedInsideVectorHelper::template value; - - public: - using ValueType = T; - Vector() - : m_capacity(inline_capacity) - { - } - - Vector(std::initializer_list list) requires(!IsLvalueReference); - - Vector(Vector&& other) - : m_size(other.m_size) - , m_capacity(other.m_capacity) - , m_outline_buffer(other.m_outline_buffer) - { - } - - Vector(Vector const& other); - - explicit Vector(Span other) requires(!IsLvalueReference); - - template - Vector(Vector const& other); - - ~Vector() - { - clear(); - } - - Span span() { return { data(), size() }; } - Span span() const { return { data(), size() }; } - - operator Span() { return span(); } - operator Span() const { return span(); } - - bool is_empty() const { return size() == 0; } - ALWAYS_INLINE size_t size() const { return m_size; } - size_t capacity() const { return m_capacity; } - - ALWAYS_INLINE StorageType* data(); - - ALWAYS_INLINE StorageType const* data() const; - - ALWAYS_INLINE VisibleType const& at(size_t i) const; - - ALWAYS_INLINE VisibleType& at(size_t i); - - ALWAYS_INLINE VisibleType const& operator[](size_t i) const { return at(i); } - ALWAYS_INLINE VisibleType& operator[](size_t i) { return at(i); } - - VisibleType const& first() const { return at(0); } - VisibleType& first() { return at(0); } - - VisibleType const& last() const { return at(size() - 1); } - VisibleType& last() { return at(size() - 1); } - - template - Optional first_matching(TUnaryPredicate const& predicate) requires(!contains_reference); - - template - Optional first_matching(TUnaryPredicate const& predicate) const requires(!contains_reference); - - template - Optional last_matching(TUnaryPredicate const& predicate) requires(!contains_reference); - - template - bool operator==(V const& other) const; - - template - bool contains_slow(V const& value) const; - - bool contains_in_range(VisibleType const& value, size_t const start, size_t const end) const; - - template - void insert(size_t index, U&& value) requires(CanBePlacedInsideVector); - - template - void insert_before_matching(U&& value, TUnaryPredicate const& predicate, size_t first_index = 0, size_t* inserted_index = nullptr) requires(CanBePlacedInsideVector); - - void extend(Vector&& other); - - void extend(Vector const& other); - - ALWAYS_INLINE void append(T&& value); - - ALWAYS_INLINE void append(T const& value) requires(!contains_reference); - - void append(StorageType const* values, size_t count); - - template - ALWAYS_INLINE void unchecked_append(U&& value) requires(CanBePlacedInsideVector); - - ALWAYS_INLINE void unchecked_append(StorageType const* values, size_t count); - - template - void empend(Args&&... args)/* requires(!contains_reference)*/; - - template - void prepend(U&& value)/* requires(CanBePlacedInsideVector)*/; - - void prepend(Vector&& other); - - void prepend(StorageType const* values, size_t count); - - Vector& operator=(Vector&& other); - - Vector& operator=(Vector const& other); - - template - Vector& operator=(Vector const& other); - - void clear(); - - void clear_with_capacity(); - - void remove(size_t index); - - void remove(size_t index, size_t count); - - template - bool remove_first_matching(TUnaryPredicate const& predicate); - - template - bool remove_all_matching(TUnaryPredicate const& predicate); - - ALWAYS_INLINE T take_last(); - - T take_first(); - - T take(size_t index); - - T unstable_take(size_t index); - - template - ErrorOr try_insert(size_t index, U&& value) requires(CanBePlacedInsideVector); - - template - ErrorOr try_insert_before_matching(U&& value, TUnaryPredicate const& predicate, size_t first_index = 0, size_t* inserted_index = nullptr) requires(CanBePlacedInsideVector); - - ErrorOr try_extend(Vector&& other); - - ErrorOr try_extend(Vector const& other); - - ErrorOr try_append(T&& value); - - ErrorOr try_append(T const& value) requires(!contains_reference); - - ErrorOr try_append(StorageType const* values, size_t count); - - template - ErrorOr try_empend(Args&&... args) requires(!contains_reference); - - template - ErrorOr try_prepend(U&& value) requires(CanBePlacedInsideVector); - - ErrorOr try_prepend(Vector&& other); - - ErrorOr try_prepend(StorageType const* values, size_t count); - - ErrorOr try_grow_capacity(size_t needed_capacity); - - ErrorOr try_ensure_capacity(size_t needed_capacity); - - ErrorOr try_resize(size_t new_size, bool keep_capacity = false) requires(!contains_reference); - - ErrorOr try_resize_and_keep_capacity(size_t new_size) requires(!contains_reference); - - void grow_capacity(size_t needed_capacity); - - void ensure_capacity(size_t needed_capacity); - - void shrink(size_t new_size, bool keep_capacity = false); - - void resize(size_t new_size, bool keep_capacity = false) requires(!contains_reference); - - void resize_and_keep_capacity(size_t new_size) requires(!contains_reference); - - using ConstIterator = SimpleIterator; - using Iterator = SimpleIterator; - using ReverseIterator = SimpleReverseIterator; - using ReverseConstIterator = SimpleReverseIterator; - - ConstIterator begin() const { return ConstIterator::begin(*this); } - Iterator begin() { return Iterator::begin(*this); } - ReverseIterator rbegin() { return ReverseIterator::rbegin(*this); } - ReverseConstIterator rbegin() const { return ReverseConstIterator::rbegin(*this); } - - ConstIterator end() const { return ConstIterator::end(*this); } - Iterator end() { return Iterator::end(*this); } - ReverseIterator rend() { return ReverseIterator::rend(*this); } - ReverseConstIterator rend() const { return ReverseConstIterator::rend(*this); } - - ALWAYS_INLINE constexpr auto in_reverse() - { - return ReverseWrapper::in_reverse(*this); - } - - template - ConstIterator find_if(TUnaryPredicate&& finder) const; - - template - Iterator find_if(TUnaryPredicate&& finder); - - ConstIterator find(VisibleType const& value) const; - - Iterator find(VisibleType const& value); - - Optional find_first_index(VisibleType const& value) const; - - void reverse(); - - private: - void reset_capacity(); - - static size_t padded_capacity(size_t capacity); - - StorageType* slot(size_t i) { return &data()[i]; } - StorageType const* slot(size_t i) const { return &data()[i]; } - - StorageType* inline_buffer(); - StorageType const* inline_buffer() const; - - StorageType& raw_last() { return raw_at(size() - 1); } - StorageType& raw_first() { return raw_at(0); } - StorageType& raw_at(size_t index) { return *slot(index); } - - size_t m_size{ 0 }; - size_t m_capacity{ 0 }; - - static constexpr size_t storage_size(); - - static constexpr size_t storage_alignment(); - - //alignas(storage_alignment()) unsigned char m_inline_buffer_storage[storage_size()]; - StorageType* m_outline_buffer{ nullptr }; -}; - -template -Vector(Args... args)->Vector>; - -} - -using AK::Vector; diff --git a/AK/AK/kmalloc.cpp b/AK/AK/kmalloc.cpp deleted file mode 100644 index 8690946..0000000 --- a/AK/AK/kmalloc.cpp +++ /dev/null @@ -1,2 +0,0 @@ -#include "pch.h" -#include "./AK/kmalloc.h" diff --git a/AK/AK/kmalloc.h b/AK/AK/kmalloc.h deleted file mode 100644 index 610b47b..0000000 --- a/AK/AK/kmalloc.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once - -#include -#include -#include -#include "./AK/Checked.h" -#include "./AK/Types.h" - -using std::nothrow; \ No newline at end of file diff --git a/AK/pch.cpp b/AK/pch.cpp deleted file mode 100644 index 331e647..0000000 --- a/AK/pch.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "pch.h" \ No newline at end of file diff --git a/AK/AK/AllOf.h b/LibC-Shim/AK/AllOf.h similarity index 86% rename from AK/AK/AllOf.h rename to LibC-Shim/AK/AllOf.h index 7b0b87b..792d0d4 100644 --- a/AK/AK/AllOf.h +++ b/LibC-Shim/AK/AllOf.h @@ -1,35 +1,35 @@ -/* - * Copyright (c) 2020, the SerenityOS developers. - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include "./AK/Concepts.h" -#include "./AK/Find.h" -#include "./AK/Iterator.h" - -namespace AK { - -template TIterator> -constexpr bool all_of( - TIterator const& begin, - TEndIterator const& end, - auto const& predicate) -{ - constexpr auto negated_predicate = [](auto const& pred) { - return [&](auto const& elem) { return !pred(elem); }; - }; - return !(find_if(begin, end, negated_predicate(predicate)) != end); -} - -template -constexpr bool all_of(Container&& container, auto const& predicate) -{ - return all_of(container.begin(), container.end(), predicate); -} - -} - -using AK::all_of; +/* + * Copyright (c) 2020, the SerenityOS developers. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include "Concepts.h" +#include "Find.h" +#include "Iterator.h" + +namespace AK { + +template TIterator> +constexpr bool all_of( + TIterator const& begin, + TEndIterator const& end, + auto const& predicate) +{ + constexpr auto negated_predicate = [](auto const& pred) { + return [&](auto const& elem) { return !pred(elem); }; + }; + return !(find_if(begin, end, negated_predicate(predicate)) != end); +} + +template +constexpr bool all_of(Container&& container, auto const& predicate) +{ + return all_of(container.begin(), container.end(), predicate); +} + +} + +using AK::all_of; diff --git a/AK/AK/AnyOf.h b/LibC-Shim/AK/AnyOf.h similarity index 83% rename from AK/AK/AnyOf.h rename to LibC-Shim/AK/AnyOf.h index 95da69b..a9ed42d 100644 --- a/AK/AK/AnyOf.h +++ b/LibC-Shim/AK/AnyOf.h @@ -1,32 +1,32 @@ -/* - * Copyright (c) 2021, the SerenityOS developers. - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include "./AK/Concepts.h" -#include "./AK/Find.h" -#include "./AK/Iterator.h" - -namespace AK { - -template TIterator> -constexpr bool any_of( - TIterator const& begin, - TEndIterator const& end, - auto const& predicate) -{ - return find_if(begin, end, predicate) != end; -} - -template -constexpr bool any_of(Container&& container, auto const& predicate) -{ - return any_of(container.begin(), container.end(), predicate); -} - -} - -using AK::any_of; +/* + * Copyright (c) 2021, the SerenityOS developers. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include "Concepts.h" +#include "Find.h" +#include "Iterator.h" + +namespace AK { + +template TIterator> +constexpr bool any_of( + TIterator const& begin, + TEndIterator const& end, + auto const& predicate) +{ + return find_if(begin, end, predicate) != end; +} + +template +constexpr bool any_of(Container&& container, auto const& predicate) +{ + return any_of(container.begin(), container.end(), predicate); +} + +} + +using AK::any_of; diff --git a/LibC-Shim/AK/Array.h b/LibC-Shim/AK/Array.h new file mode 100644 index 0000000..ec5f084 --- /dev/null +++ b/LibC-Shim/AK/Array.h @@ -0,0 +1,110 @@ +#pragma once + +#include +#include "Iterator.h" +#include "Span.h" + +namespace AK { + +template +struct Array { + using ValueType = T; + + [[nodiscard]] constexpr T const* data() const { return __data; } + [[nodiscard]] constexpr T* data() { return __data; } + + [[nodiscard]] constexpr size_t size() const { return Size; } + + [[nodiscard]] constexpr Span span() const { return { __data, Size }; } + [[nodiscard]] constexpr Span span() { return { __data, Size }; } + + [[nodiscard]] constexpr T const& at(size_t index) const + { + VERIFY(index < size()); + return __data[index]; + } + [[nodiscard]] constexpr T& at(size_t index) + { + VERIFY(index < size()); + return __data[index]; + } + + [[nodiscard]] constexpr T const& first() const { return at(0); } + [[nodiscard]] constexpr T& first() { return at(0); } + + [[nodiscard]] constexpr T const& last() const requires(Size > 0) { return at(Size - 1); } + [[nodiscard]] constexpr T& last() requires(Size > 0) { return at(Size - 1); } + + [[nodiscard]] constexpr bool is_empty() const { return size() == 0; } + + [[nodiscard]] constexpr T const& operator[](size_t index) const { return at(index); } + [[nodiscard]] constexpr T& operator[](size_t index) { return at(index); } + + template + [[nodiscard]] constexpr bool operator==(Array const& other) const { return span() == other.span(); } + + using ConstIterator = SimpleIterator; + using Iterator = SimpleIterator; + + [[nodiscard]] constexpr ConstIterator begin() const { return ConstIterator::begin(*this); } + [[nodiscard]] constexpr Iterator begin() { return Iterator::begin(*this); } + + [[nodiscard]] constexpr ConstIterator end() const { return ConstIterator::end(*this); } + [[nodiscard]] constexpr Iterator end() { return Iterator::end(*this); } + + [[nodiscard]] constexpr operator Span() const { return span(); } + [[nodiscard]] constexpr operator Span() { return span(); } + + constexpr size_t fill(T const& value) + { + for (size_t idx = 0; idx < Size; ++idx) + __data[idx] = value; + + return Size; + } + + [[nodiscard]] constexpr T max() const requires(requires(T x, T y) { x < y; }) + { + static_assert(Size > 0, "No values to max() over"); + + T value = __data[0]; + for (size_t i = 1; i < Size; ++i) + value = AK::max(__data[i], value); + return value; + } + + [[nodiscard]] constexpr T min() const requires(requires(T x, T y) { x > y; }) + { + static_assert(Size > 0, "No values to min() over"); + + T value = __data[0]; + for (size_t i = 1; i < Size; ++i) + value = AK::min(__data[i], value); + return value; + } + + T __data[Size]; +}; + +template +Array(T, Types...) -> Array; + +namespace Detail { +template +constexpr auto integer_sequence_generate_array([[maybe_unused]] T const offset, IntegerSequence) -> Array +{ + return { { (offset + Is)... } }; +} +} + +template +constexpr static auto iota_array(T const offset = {}) +{ + static_assert(N >= T {}, "Negative sizes not allowed in iota_array()"); + return Detail::integer_sequence_generate_array(offset, MakeIntegerSequence()); +} + +} + +using AK::Array; +using AK::iota_array; diff --git a/AK/AK/Assertions.h b/LibC-Shim/AK/Assertions.h similarity index 95% rename from AK/AK/Assertions.h rename to LibC-Shim/AK/Assertions.h index cf4c90f..1137c0d 100644 --- a/AK/AK/Assertions.h +++ b/LibC-Shim/AK/Assertions.h @@ -1,12 +1,12 @@ -#pragma once - -#include -#include "./Platform.h" - -// FIXME: Actually verify -#define VERIFY(expression) -//#define VERIFY assert - -#define VERIFY_NOT_REACHED() VERIFY(false) -static constexpr bool TODO = false; -#define TODO() VERIFY(TODO) +#pragma once + +#include +#include "./Platform.h" + +// FIXME: Actually verify +#define VERIFY(expression) +//#define VERIFY assert + +#define VERIFY_NOT_REACHED() VERIFY(false) +static constexpr bool TODO = false; +#define TODO() VERIFY(TODO) diff --git a/LibC-Shim/AK/Atomic.cpp b/LibC-Shim/AK/Atomic.cpp new file mode 100644 index 0000000..10c9a56 --- /dev/null +++ b/LibC-Shim/AK/Atomic.cpp @@ -0,0 +1,2 @@ +#include "pch.h" +#include "Atomic.h" diff --git a/LibC-Shim/AK/Atomic.h b/LibC-Shim/AK/Atomic.h new file mode 100644 index 0000000..028c9ca --- /dev/null +++ b/LibC-Shim/AK/Atomic.h @@ -0,0 +1,163 @@ +#pragma once + +#include +#include "Concepts.h" +#include "Platform.h" +#include "Types.h" + +namespace AK { + +template +static ALWAYS_INLINE T atomic_exchange(volatile T* var, T desired, MemoryOrder order = memory_order_seq_cst) noexcept +{ + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return desired; +} + +/*template> +static ALWAYS_INLINE V* atomic_exchange(volatile T** var, V* desired, MemoryOrder order = memory_order_seq_cst) noexcept +{ + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return false; +} + +template> +static ALWAYS_INLINE V* atomic_exchange(volatile T** var, std::nullptr_t, MemoryOrder order = memory_order_seq_cst) noexcept +{ + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return false; +}*/ + +template +static ALWAYS_INLINE bool atomic_compare_exchange_strong(volatile T* var, T& expected, T desired, MemoryOrder order = memory_order_seq_cst) noexcept +{ + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return false; +} + +template> +static ALWAYS_INLINE bool atomic_compare_exchange_strong(volatile T** var, V*& expected, V* desired, MemoryOrder order = memory_order_seq_cst) noexcept +{ + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return false; +} + +template> +static ALWAYS_INLINE bool atomic_compare_exchange_strong(volatile T** var, V*& expected, std::nullptr_t, MemoryOrder order = memory_order_seq_cst) noexcept +{ + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return false; +} + +template +static ALWAYS_INLINE T atomic_fetch_add(volatile T* var, T val, MemoryOrder order = memory_order_seq_cst) noexcept +{ + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return val; +} + +template +static ALWAYS_INLINE T atomic_fetch_sub(volatile T* var, T val, MemoryOrder order = memory_order_seq_cst) noexcept +{ + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return val; +} + +template +static ALWAYS_INLINE T atomic_fetch_and(volatile T* var, T val, MemoryOrder order = memory_order_seq_cst) noexcept +{ + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return val; +} + +template +static ALWAYS_INLINE T atomic_fetch_or(volatile T* var, T val, MemoryOrder order = memory_order_seq_cst) noexcept +{ + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return val; +} + +template +static ALWAYS_INLINE T atomic_fetch_xor(volatile T* var, T val, MemoryOrder order = memory_order_seq_cst) noexcept +{ + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return val; +} + +template +static ALWAYS_INLINE bool atomic_is_lock_free(volatile T* ptr = nullptr) noexcept +{ + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return false; +} + +template +class Atomic { + T* m_value{ nullptr }; + +public: + Atomic() noexcept = default; + Atomic& operator=(Atomic const&) volatile = delete; + Atomic& operator=(Atomic&&) volatile = delete; + Atomic(Atomic const&) = delete; + Atomic(Atomic&&) = delete; + + constexpr Atomic(T* val) noexcept + : m_value(val) + { + } + + T* operator++() volatile noexcept + { + return fetch_add(1) + 1; + } + + T* operator++(int) volatile noexcept + { + return fetch_add(1); + } + + T* operator+=(ptrdiff_t val) volatile noexcept + { + return fetch_add(val) + val; + } + + T* fetch_add(ptrdiff_t val, MemoryOrder order = DefaultMemoryOrder) volatile noexcept + { + return atomic_fetch_add(&m_value, val * sizeof(*m_value), order); + } + + T* operator--() volatile noexcept + { + return fetch_sub(1) - 1; + } + + T* operator--(int) volatile noexcept + { + return fetch_sub(1); + } + + T* operator-=(ptrdiff_t val) volatile noexcept + { + return fetch_sub(val) - val; + } + + T* fetch_sub(ptrdiff_t val, MemoryOrder order = DefaultMemoryOrder) volatile noexcept + { + return fetch_sub(&m_value, val * sizeof(*m_value), order); + } +}; + +} diff --git a/AK/AK/Badge.h b/LibC-Shim/AK/Badge.h similarity index 93% rename from AK/AK/Badge.h rename to LibC-Shim/AK/Badge.h index 4a2c7e4..6b3fdb0 100644 --- a/AK/AK/Badge.h +++ b/LibC-Shim/AK/Badge.h @@ -1,29 +1,29 @@ -/* - * Copyright (c) 2018-2020, Andreas Kling - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -namespace AK { - -template -class Badge { -public: - using Type = T; - -private: - friend T; - constexpr Badge() = default; - - Badge(Badge const&) = delete; - Badge& operator=(Badge const&) = delete; - - Badge(Badge&&) = delete; - Badge& operator=(Badge&&) = delete; -}; - -} - -using AK::Badge; +/* + * Copyright (c) 2018-2020, Andreas Kling + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +namespace AK { + +template +class Badge { +public: + using Type = T; + +private: + friend T; + constexpr Badge() = default; + + Badge(Badge const&) = delete; + Badge& operator=(Badge const&) = delete; + + Badge(Badge&&) = delete; + Badge& operator=(Badge&&) = delete; +}; + +} + +using AK::Badge; diff --git a/AK/AK/BitCast.h b/LibC-Shim/AK/BitCast.h similarity index 92% rename from AK/AK/BitCast.h rename to LibC-Shim/AK/BitCast.h index f81f174..9061436 100644 --- a/AK/AK/BitCast.h +++ b/LibC-Shim/AK/BitCast.h @@ -1,21 +1,21 @@ -/* - * Copyright (c) 2021, the SerenityOS developers. - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include - -namespace AK { - -template -ALWAYS_INLINE T bit_cast(const U& a) -{ - return std::bit_cast(a); -} - -} - -using AK::bit_cast; +/* + * Copyright (c) 2021, the SerenityOS developers. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include + +namespace AK { + +template +ALWAYS_INLINE T bit_cast(const U& a) +{ + return std::bit_cast(a); +} + +} + +using AK::bit_cast; diff --git a/AK/AK/BuiltinWrappers.h b/LibC-Shim/AK/BuiltinWrappers.h similarity index 95% rename from AK/AK/BuiltinWrappers.h rename to LibC-Shim/AK/BuiltinWrappers.h index 739b2f4..69e14ed 100644 --- a/AK/AK/BuiltinWrappers.h +++ b/LibC-Shim/AK/BuiltinWrappers.h @@ -1,66 +1,66 @@ -#pragma once - -#include "./AK/Concepts.h" - -template -ALWAYS_INLINE constexpr int popcount(IntType value) -{ - // FIXME: - return 0; -} - -// The function will return the number of trailing zeroes in the type. If -// the given number if zero, this function may contain undefined -// behavior, or it may return the number of bits in the number. If -// this function can be called with zero, the use of -// count_trailing_zeroes_safe is preferred. -template -ALWAYS_INLINE constexpr int count_trailing_zeroes(IntType value) -{ - // FIXME: - return 0; -} - -// The function will return the number of trailing zeroes in the type. If -// the given number is zero, this function will return the number of bits -// bits in the IntType. -template -ALWAYS_INLINE constexpr int count_trailing_zeroes_safe(IntType value) -{ - // FIXME: - return 0 * sizeof(IntType); -} - -// The function will return the number of leading zeroes in the type. If -// the given number if zero, this function may contain undefined -// behavior, or it may return the number of bits in the number. If -// this function can be called with zero, the use of -// count_leading_zeroes_safe is preferred. -template -ALWAYS_INLINE constexpr int count_leading_zeroes(IntType value) -{ - // FIXME: - return 0 * sizeof(IntType); -} - -// The function will return the number of leading zeroes in the type. If -// the given number is zero, this function will return the number of bits -// in the IntType. -template -ALWAYS_INLINE constexpr int count_leading_zeroes_safe(IntType value) -{ - if (value == 0) - return 8 * sizeof(IntType); - return count_leading_zeroes(value); -} - -// The function will return the number of leading zeroes in the type. If -// the given number is zero, this function will return the number of bits -// in the IntType. -template -ALWAYS_INLINE constexpr int bit_scan_forward(IntType value) -{ - if (value == 0) - return 0; - return 1 + count_trailing_zeroes(static_cast>(value)); -} +#pragma once + +#include "Concepts.h" + +template +ALWAYS_INLINE constexpr int popcount(IntType value) +{ + // FIXME: + return 0; +} + +// The function will return the number of trailing zeroes in the type. If +// the given number if zero, this function may contain undefined +// behavior, or it may return the number of bits in the number. If +// this function can be called with zero, the use of +// count_trailing_zeroes_safe is preferred. +template +ALWAYS_INLINE constexpr int count_trailing_zeroes(IntType value) +{ + // FIXME: + return 0; +} + +// The function will return the number of trailing zeroes in the type. If +// the given number is zero, this function will return the number of bits +// bits in the IntType. +template +ALWAYS_INLINE constexpr int count_trailing_zeroes_safe(IntType value) +{ + // FIXME: + return 0 * sizeof(IntType); +} + +// The function will return the number of leading zeroes in the type. If +// the given number if zero, this function may contain undefined +// behavior, or it may return the number of bits in the number. If +// this function can be called with zero, the use of +// count_leading_zeroes_safe is preferred. +template +ALWAYS_INLINE constexpr int count_leading_zeroes(IntType value) +{ + // FIXME: + return 0 * sizeof(IntType); +} + +// The function will return the number of leading zeroes in the type. If +// the given number is zero, this function will return the number of bits +// in the IntType. +template +ALWAYS_INLINE constexpr int count_leading_zeroes_safe(IntType value) +{ + if (value == 0) + return 8 * sizeof(IntType); + return count_leading_zeroes(value); +} + +// The function will return the number of leading zeroes in the type. If +// the given number is zero, this function will return the number of bits +// in the IntType. +template +ALWAYS_INLINE constexpr int bit_scan_forward(IntType value) +{ + if (value == 0) + return 0; + return 1 + count_trailing_zeroes(static_cast>(value)); +} diff --git a/AK/AK/ByteBuffer.h b/LibC-Shim/AK/ByteBuffer.h similarity index 93% rename from AK/AK/ByteBuffer.h rename to LibC-Shim/AK/ByteBuffer.h index a7adc7e..b3870df 100644 --- a/AK/AK/ByteBuffer.h +++ b/LibC-Shim/AK/ByteBuffer.h @@ -1,137 +1,137 @@ -#pragma once - -#include "./AK/Assertions.h" -#include "./AK/Error.h" -#include "./AK/Span.h" -#include "./AK/Types.h" -#include "./AK/kmalloc.h" - -namespace AK { -namespace Detail { - -template -class ByteBuffer { -public: - ByteBuffer() = default; - - ~ByteBuffer() - { - clear(); - } - - ByteBuffer(ByteBuffer const& other); - - ByteBuffer(ByteBuffer&& other); - - ByteBuffer& operator=(ByteBuffer&& other); - - ByteBuffer& operator=(ByteBuffer const& other); - - static ErrorOr create_uninitialized(size_t size); - - static ErrorOr create_zeroed(size_t size); - - static ErrorOr copy(void const* data, size_t size); - - static ErrorOr copy(ReadonlyBytes bytes); - - template - bool operator==(ByteBuffer const& other) const; - - bool operator!=(ByteBuffer const& other) const { return !(*this == other); } - - u8& operator[](size_t i); - - u8 const& operator[](size_t i) const; - - bool is_empty() const { return m_size == 0; } - size_t size() const { return m_size; } - - u8* data() { return m_inline ? m_inline_buffer : m_outline_buffer; } - u8 const* data() const { return m_inline ? m_inline_buffer : m_outline_buffer; } - - Bytes bytes() { return { data(), size() }; } - ReadonlyBytes bytes() const { return { data(), size() }; } - - AK::Span span() { return { data(), size() }; } - AK::Span span() const { return { data(), size() }; } - - u8* offset_pointer(int offset) { return data() + offset; } - u8 const* offset_pointer(int offset) const { return data() + offset; } - - void* end_pointer() { return data() + m_size; } - void const* end_pointer() const { return data() + m_size; } - - ErrorOr slice(size_t offset, size_t size) const; - - void clear(); - - ALWAYS_INLINE void resize(size_t new_size); - - ALWAYS_INLINE void ensure_capacity(size_t new_capacity); - - ErrorOr try_resize(size_t new_size); - - ErrorOr try_ensure_capacity(size_t new_capacity); - - /// Return a span of bytes past the end of this ByteBuffer for writing. - /// Ensures that the required space is available. - ErrorOr get_bytes_for_writing(size_t length); - - /// Like get_bytes_for_writing, but crashes if allocation fails. - Bytes must_get_bytes_for_writing(size_t length); - - void append(u8 byte); - - void append(ReadonlyBytes bytes); - - void append(void const* data, size_t data_size) { append({ data, data_size }); } - - ErrorOr try_append(u8 byte); - - ErrorOr try_append(ReadonlyBytes bytes); - - ErrorOr try_append(void const* data, size_t data_size); - - void operator+=(ByteBuffer const& other); - - void overwrite(size_t offset, void const* data, size_t data_size); - - void zero_fill(); - - operator Bytes() { return bytes(); } - operator ReadonlyBytes() const { return bytes(); } - - ALWAYS_INLINE size_t capacity() const { return m_inline ? inline_capacity : m_outline_capacity; } - -private: - void move_from(ByteBuffer&& other); - - void trim(size_t size, bool may_discard_existing_data); - - NEVER_INLINE void shrink_into_inline_buffer(size_t size, bool may_discard_existing_data); - - NEVER_INLINE ErrorOr try_ensure_capacity_slowpath(size_t new_capacity); - - union { - u8 m_inline_buffer[inline_capacity]; - struct { - u8* m_outline_buffer; - size_t m_outline_capacity; - }; - }; - size_t m_size{ 0 }; - bool m_inline{ true }; -}; - -} - -/*template<> -struct Traits : public GenericTraits { -static unsigned hash(ByteBuffer const& byte_buffer) -{ - return Traits::hash(byte_buffer.span()); -} -};*/ - -} +#pragma once + +#include "Assertions.h" +#include "Error.h" +#include "Span.h" +#include "Types.h" +#include "kmalloc.h" + +namespace AK { +namespace Detail { + +template +class ByteBuffer { +public: + ByteBuffer() = default; + + ~ByteBuffer() + { + clear(); + } + + ByteBuffer(ByteBuffer const& other); + + ByteBuffer(ByteBuffer&& other); + + ByteBuffer& operator=(ByteBuffer&& other); + + ByteBuffer& operator=(ByteBuffer const& other); + + static ErrorOr create_uninitialized(size_t size); + + static ErrorOr create_zeroed(size_t size); + + static ErrorOr copy(void const* data, size_t size); + + static ErrorOr copy(ReadonlyBytes bytes); + + template + bool operator==(ByteBuffer const& other) const; + + bool operator!=(ByteBuffer const& other) const { return !(*this == other); } + + u8& operator[](size_t i); + + u8 const& operator[](size_t i) const; + + bool is_empty() const { return m_size == 0; } + size_t size() const { return m_size; } + + u8* data() { return m_inline ? m_inline_buffer : m_outline_buffer; } + u8 const* data() const { return m_inline ? m_inline_buffer : m_outline_buffer; } + + Bytes bytes() { return { data(), size() }; } + ReadonlyBytes bytes() const { return { data(), size() }; } + + AK::Span span() { return { data(), size() }; } + AK::Span span() const { return { data(), size() }; } + + u8* offset_pointer(int offset) { return data() + offset; } + u8 const* offset_pointer(int offset) const { return data() + offset; } + + void* end_pointer() { return data() + m_size; } + void const* end_pointer() const { return data() + m_size; } + + ErrorOr slice(size_t offset, size_t size) const; + + void clear(); + + ALWAYS_INLINE void resize(size_t new_size); + + ALWAYS_INLINE void ensure_capacity(size_t new_capacity); + + ErrorOr try_resize(size_t new_size); + + ErrorOr try_ensure_capacity(size_t new_capacity); + + /// Return a span of bytes past the end of this ByteBuffer for writing. + /// Ensures that the required space is available. + ErrorOr get_bytes_for_writing(size_t length); + + /// Like get_bytes_for_writing, but crashes if allocation fails. + Bytes must_get_bytes_for_writing(size_t length); + + void append(u8 byte); + + void append(ReadonlyBytes bytes); + + void append(void const* data, size_t data_size) { append({ data, data_size }); } + + ErrorOr try_append(u8 byte); + + ErrorOr try_append(ReadonlyBytes bytes); + + ErrorOr try_append(void const* data, size_t data_size); + + void operator+=(ByteBuffer const& other); + + void overwrite(size_t offset, void const* data, size_t data_size); + + void zero_fill(); + + operator Bytes() { return bytes(); } + operator ReadonlyBytes() const { return bytes(); } + + ALWAYS_INLINE size_t capacity() const { return m_inline ? inline_capacity : m_outline_capacity; } + +private: + void move_from(ByteBuffer&& other); + + void trim(size_t size, bool may_discard_existing_data); + + NEVER_INLINE void shrink_into_inline_buffer(size_t size, bool may_discard_existing_data); + + NEVER_INLINE ErrorOr try_ensure_capacity_slowpath(size_t new_capacity); + + union { + u8 m_inline_buffer[inline_capacity]; + struct { + u8* m_outline_buffer; + size_t m_outline_capacity; + }; + }; + size_t m_size{ 0 }; + bool m_inline{ true }; +}; + +} + +/*template<> +struct Traits : public GenericTraits { +static unsigned hash(ByteBuffer const& byte_buffer) +{ + return Traits::hash(byte_buffer.span()); +} +};*/ + +} diff --git a/AK/AK/CharacterTypes.h b/LibC-Shim/AK/CharacterTypes.h similarity index 96% rename from AK/AK/CharacterTypes.h rename to LibC-Shim/AK/CharacterTypes.h index 18735b4..14218e7 100644 --- a/AK/AK/CharacterTypes.h +++ b/LibC-Shim/AK/CharacterTypes.h @@ -1,193 +1,193 @@ -/* - * Copyright (c) 2021, Max Wipfli - * Copyright (c) 2022, the SerenityOS developers. - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include "Array.h" -#include "Types.h" - - // NOTE: For a quick reference for most of this, see https://www.cplusplus.com/reference/cctype/ and https://infra.spec.whatwg.org/#code-points. - // NOTE: To avoid ambiguity when including this header, all methods contains names should contain "ascii" or "unicode". - -namespace AK { - -constexpr bool is_ascii(u32 code_point) -{ - return code_point < 0x80; -} - -constexpr bool is_ascii_digit(u32 code_point) -{ - return code_point >= '0' && code_point <= '9'; -} - -constexpr bool is_ascii_upper_alpha(u32 code_point) -{ - return (code_point >= 'A' && code_point <= 'Z'); -} - -constexpr bool is_ascii_lower_alpha(u32 code_point) -{ - return (code_point >= 'a' && code_point <= 'z'); -} - -constexpr bool is_ascii_alpha(u32 code_point) -{ - return is_ascii_lower_alpha(code_point) || is_ascii_upper_alpha(code_point); -} - -constexpr bool is_ascii_alphanumeric(u32 code_point) -{ - return is_ascii_alpha(code_point) || is_ascii_digit(code_point); -} - -constexpr bool is_ascii_binary_digit(u32 code_point) -{ - return code_point == '0' || code_point == '1'; -} - -constexpr bool is_ascii_octal_digit(u32 code_point) -{ - return code_point >= '0' && code_point <= '7'; -} - -constexpr bool is_ascii_hex_digit(u32 code_point) -{ - return is_ascii_digit(code_point) || (code_point >= 'A' && code_point <= 'F') || (code_point >= 'a' && code_point <= 'f'); -} - -constexpr bool is_ascii_blank(u32 code_point) -{ - return code_point == '\t' || code_point == ' '; -} - -constexpr bool is_ascii_space(u32 code_point) -{ - return code_point == ' ' || code_point == '\t' || code_point == '\n' || code_point == '\v' || code_point == '\f' || code_point == '\r'; -} - -constexpr bool is_ascii_punctuation(u32 code_point) -{ - return (code_point >= 0x21 && code_point <= 0x2F) || (code_point >= 0x3A && code_point <= 0x40) || (code_point >= 0x5B && code_point <= 0x60) || (code_point >= 0x7B && code_point <= 0x7E); -} - -constexpr bool is_ascii_graphical(u32 code_point) -{ - return code_point >= 0x21 && code_point <= 0x7E; -} - -constexpr bool is_ascii_printable(u32 code_point) -{ - return code_point >= 0x20 && code_point <= 0x7E; -} - -constexpr bool is_ascii_c0_control(u32 code_point) -{ - return code_point < 0x20; -} - -constexpr bool is_ascii_control(u32 code_point) -{ - return is_ascii_c0_control(code_point) || code_point == 0x7F; -} - -constexpr bool is_unicode(u32 code_point) -{ - return code_point <= 0x10FFFF; -} - -constexpr bool is_unicode_control(u32 code_point) -{ - return is_ascii_c0_control(code_point) || (code_point >= 0x7E && code_point <= 0x9F); -} - -constexpr bool is_unicode_surrogate(u32 code_point) -{ - return code_point >= 0xD800 && code_point <= 0xDFFF; -} - -constexpr bool is_unicode_scalar_value(u32 code_point) -{ - return is_unicode(code_point) && !is_unicode_surrogate(code_point); -} - -constexpr bool is_unicode_noncharacter(u32 code_point) -{ - return is_unicode(code_point) && ((code_point >= 0xFDD0 && code_point <= 0xFDEF) || ((code_point & 0xFFFE) == 0xFFFE) || ((code_point & 0xFFFF) == 0xFFFF)); -} - -constexpr u32 to_ascii_lowercase(u32 code_point) -{ - if (is_ascii_upper_alpha(code_point)) - return code_point + 0x20; - return code_point; -} - -constexpr u32 to_ascii_uppercase(u32 code_point) -{ - if (is_ascii_lower_alpha(code_point)) - return code_point - 0x20; - return code_point; -} - -constexpr u32 parse_ascii_digit(u32 code_point) -{ - if (is_ascii_digit(code_point)) - return code_point - '0'; - VERIFY_NOT_REACHED(); -} - -constexpr u32 parse_ascii_hex_digit(u32 code_point) -{ - if (is_ascii_digit(code_point)) - return parse_ascii_digit(code_point); - if (code_point >= 'A' && code_point <= 'F') - return code_point - 'A' + 10; - if (code_point >= 'a' && code_point <= 'f') - return code_point - 'a' + 10; - VERIFY_NOT_REACHED(); -} - -constexpr u32 parse_ascii_base36_digit(u32 code_point) -{ - if (is_ascii_digit(code_point)) - return parse_ascii_digit(code_point); - if (code_point >= 'A' && code_point <= 'Z') - return code_point - 'A' + 10; - if (code_point >= 'a' && code_point <= 'z') - return code_point - 'a' + 10; - VERIFY_NOT_REACHED(); -} - -} - -using AK::is_ascii; -using AK::is_ascii_alpha; -using AK::is_ascii_alphanumeric; -using AK::is_ascii_binary_digit; -using AK::is_ascii_blank; -using AK::is_ascii_c0_control; -using AK::is_ascii_control; -using AK::is_ascii_digit; -using AK::is_ascii_graphical; -using AK::is_ascii_hex_digit; -using AK::is_ascii_lower_alpha; -using AK::is_ascii_octal_digit; -using AK::is_ascii_printable; -using AK::is_ascii_punctuation; -using AK::is_ascii_space; -using AK::is_ascii_upper_alpha; -using AK::is_unicode; -using AK::is_unicode_control; -using AK::is_unicode_noncharacter; -using AK::is_unicode_scalar_value; -using AK::is_unicode_surrogate; -using AK::parse_ascii_base36_digit; -using AK::parse_ascii_digit; -using AK::parse_ascii_hex_digit; -using AK::to_ascii_lowercase; -using AK::to_ascii_uppercase; +/* + * Copyright (c) 2021, Max Wipfli + * Copyright (c) 2022, the SerenityOS developers. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include "Array.h" +#include "Types.h" + + // NOTE: For a quick reference for most of this, see https://www.cplusplus.com/reference/cctype/ and https://infra.spec.whatwg.org/#code-points. + // NOTE: To avoid ambiguity when including this header, all methods contains names should contain "ascii" or "unicode". + +namespace AK { + +constexpr bool is_ascii(u32 code_point) +{ + return code_point < 0x80; +} + +constexpr bool is_ascii_digit(u32 code_point) +{ + return code_point >= '0' && code_point <= '9'; +} + +constexpr bool is_ascii_upper_alpha(u32 code_point) +{ + return (code_point >= 'A' && code_point <= 'Z'); +} + +constexpr bool is_ascii_lower_alpha(u32 code_point) +{ + return (code_point >= 'a' && code_point <= 'z'); +} + +constexpr bool is_ascii_alpha(u32 code_point) +{ + return is_ascii_lower_alpha(code_point) || is_ascii_upper_alpha(code_point); +} + +constexpr bool is_ascii_alphanumeric(u32 code_point) +{ + return is_ascii_alpha(code_point) || is_ascii_digit(code_point); +} + +constexpr bool is_ascii_binary_digit(u32 code_point) +{ + return code_point == '0' || code_point == '1'; +} + +constexpr bool is_ascii_octal_digit(u32 code_point) +{ + return code_point >= '0' && code_point <= '7'; +} + +constexpr bool is_ascii_hex_digit(u32 code_point) +{ + return is_ascii_digit(code_point) || (code_point >= 'A' && code_point <= 'F') || (code_point >= 'a' && code_point <= 'f'); +} + +constexpr bool is_ascii_blank(u32 code_point) +{ + return code_point == '\t' || code_point == ' '; +} + +constexpr bool is_ascii_space(u32 code_point) +{ + return code_point == ' ' || code_point == '\t' || code_point == '\n' || code_point == '\v' || code_point == '\f' || code_point == '\r'; +} + +constexpr bool is_ascii_punctuation(u32 code_point) +{ + return (code_point >= 0x21 && code_point <= 0x2F) || (code_point >= 0x3A && code_point <= 0x40) || (code_point >= 0x5B && code_point <= 0x60) || (code_point >= 0x7B && code_point <= 0x7E); +} + +constexpr bool is_ascii_graphical(u32 code_point) +{ + return code_point >= 0x21 && code_point <= 0x7E; +} + +constexpr bool is_ascii_printable(u32 code_point) +{ + return code_point >= 0x20 && code_point <= 0x7E; +} + +constexpr bool is_ascii_c0_control(u32 code_point) +{ + return code_point < 0x20; +} + +constexpr bool is_ascii_control(u32 code_point) +{ + return is_ascii_c0_control(code_point) || code_point == 0x7F; +} + +constexpr bool is_unicode(u32 code_point) +{ + return code_point <= 0x10FFFF; +} + +constexpr bool is_unicode_control(u32 code_point) +{ + return is_ascii_c0_control(code_point) || (code_point >= 0x7E && code_point <= 0x9F); +} + +constexpr bool is_unicode_surrogate(u32 code_point) +{ + return code_point >= 0xD800 && code_point <= 0xDFFF; +} + +constexpr bool is_unicode_scalar_value(u32 code_point) +{ + return is_unicode(code_point) && !is_unicode_surrogate(code_point); +} + +constexpr bool is_unicode_noncharacter(u32 code_point) +{ + return is_unicode(code_point) && ((code_point >= 0xFDD0 && code_point <= 0xFDEF) || ((code_point & 0xFFFE) == 0xFFFE) || ((code_point & 0xFFFF) == 0xFFFF)); +} + +constexpr u32 to_ascii_lowercase(u32 code_point) +{ + if (is_ascii_upper_alpha(code_point)) + return code_point + 0x20; + return code_point; +} + +constexpr u32 to_ascii_uppercase(u32 code_point) +{ + if (is_ascii_lower_alpha(code_point)) + return code_point - 0x20; + return code_point; +} + +constexpr u32 parse_ascii_digit(u32 code_point) +{ + if (is_ascii_digit(code_point)) + return code_point - '0'; + VERIFY_NOT_REACHED(); +} + +constexpr u32 parse_ascii_hex_digit(u32 code_point) +{ + if (is_ascii_digit(code_point)) + return parse_ascii_digit(code_point); + if (code_point >= 'A' && code_point <= 'F') + return code_point - 'A' + 10; + if (code_point >= 'a' && code_point <= 'f') + return code_point - 'a' + 10; + VERIFY_NOT_REACHED(); +} + +constexpr u32 parse_ascii_base36_digit(u32 code_point) +{ + if (is_ascii_digit(code_point)) + return parse_ascii_digit(code_point); + if (code_point >= 'A' && code_point <= 'Z') + return code_point - 'A' + 10; + if (code_point >= 'a' && code_point <= 'z') + return code_point - 'a' + 10; + VERIFY_NOT_REACHED(); +} + +} + +using AK::is_ascii; +using AK::is_ascii_alpha; +using AK::is_ascii_alphanumeric; +using AK::is_ascii_binary_digit; +using AK::is_ascii_blank; +using AK::is_ascii_c0_control; +using AK::is_ascii_control; +using AK::is_ascii_digit; +using AK::is_ascii_graphical; +using AK::is_ascii_hex_digit; +using AK::is_ascii_lower_alpha; +using AK::is_ascii_octal_digit; +using AK::is_ascii_printable; +using AK::is_ascii_punctuation; +using AK::is_ascii_space; +using AK::is_ascii_upper_alpha; +using AK::is_unicode; +using AK::is_unicode_control; +using AK::is_unicode_noncharacter; +using AK::is_unicode_scalar_value; +using AK::is_unicode_surrogate; +using AK::parse_ascii_base36_digit; +using AK::parse_ascii_digit; +using AK::parse_ascii_hex_digit; +using AK::to_ascii_lowercase; +using AK::to_ascii_uppercase; diff --git a/AK/AK/Checked.h b/LibC-Shim/AK/Checked.h similarity index 95% rename from AK/AK/Checked.h rename to LibC-Shim/AK/Checked.h index a9b069f..09ece74 100644 --- a/AK/AK/Checked.h +++ b/LibC-Shim/AK/Checked.h @@ -1,448 +1,448 @@ -/* - * Copyright (C) 2011-2019 Apple Inc. All rights reserved. - * Copyright (c) 2020-2021, Andreas Kling - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#pragma once - -#include "./AK/Assertions.h" -#include "./AK/Concepts.h" -#include "./AK/NumericLimits.h" -#include "./AK/StdLibExtras.h" - -namespace AK { - -template= sizeof(Source)), bool destination_is_signed = NumericLimits::is_signed(), bool source_is_signed = NumericLimits::is_signed()> -struct TypeBoundsChecker; - -template -struct TypeBoundsChecker { - static constexpr bool is_within_range(Source value) - { - return value <= NumericLimits::max(); - } -}; - -template -struct TypeBoundsChecker { - static constexpr bool is_within_range(Source value) - { - return value <= NumericLimits::max() - && NumericLimits::min() <= value; - } -}; - -template -struct TypeBoundsChecker { - static constexpr bool is_within_range(Source value) - { - return value >= 0 && value <= NumericLimits::max(); - } -}; - -template -struct TypeBoundsChecker { - static constexpr bool is_within_range(Source value) - { - return value <= static_cast(NumericLimits::max()); - } -}; - -template -struct TypeBoundsChecker { - static constexpr bool is_within_range(Source) - { - return true; - } -}; - -template -struct TypeBoundsChecker { - static constexpr bool is_within_range(Source) - { - return true; - } -}; - -template -struct TypeBoundsChecker { - static constexpr bool is_within_range(Source value) - { - return value >= 0; - } -}; - -template -struct TypeBoundsChecker { - static constexpr bool is_within_range(Source value) - { - if (sizeof(Destination) > sizeof(Source)) - return true; - return value <= static_cast(NumericLimits::max()); - } -}; - -template -[[nodiscard]] constexpr bool is_within_range(Source value) -{ - return TypeBoundsChecker::is_within_range(value); -} - -template -class Checked { -public: - constexpr Checked() = default; - - explicit constexpr Checked(T value) - : m_value(value) - { - } - - template - constexpr Checked(U value) - { - m_overflow = !is_within_range(value); - m_value = value; - } - - constexpr Checked(Checked const&) = default; - - constexpr Checked(Checked&& other) - : m_value(exchange(other.m_value, 0)) - , m_overflow(exchange(other.m_overflow, false)) - { - } - - template - constexpr Checked& operator=(U value) - { - *this = Checked(value); - return *this; - } - - constexpr Checked& operator=(Checked const& other) = default; - - constexpr Checked& operator=(Checked&& other) - { - m_value = exchange(other.m_value, 0); - m_overflow = exchange(other.m_overflow, false); - return *this; - } - - [[nodiscard]] constexpr bool has_overflow() const - { - return m_overflow; - } - - ALWAYS_INLINE constexpr bool operator!() const - { - VERIFY(!m_overflow); - return !m_value; - } - - ALWAYS_INLINE constexpr T value() const - { - VERIFY(!m_overflow); - return m_value; - } - - constexpr void add(T other) - { - m_overflow |= __builtin_add_overflow(m_value, other, &m_value); - } - - constexpr void sub(T other) - { - m_overflow |= __builtin_sub_overflow(m_value, other, &m_value); - } - - constexpr void mul(T other) - { - m_overflow |= __builtin_mul_overflow(m_value, other, &m_value); - } - - constexpr void div(T other) - { - if constexpr (IsSigned) { - // Ensure that the resulting value won't be out of range, this can only happen when dividing by -1. - if (other == -1 && m_value == NumericLimits::min()) { - m_overflow = true; - return; - } - } - if (other == 0) { - m_overflow = true; - return; - } - m_value /= other; - } - - constexpr void saturating_sub(T other) - { - sub(other); - // Depending on whether other was positive or negative, we have to saturate to min or max. - if (m_overflow && other <= 0) - m_value = NumericLimits::max(); - else if (m_overflow) - m_value = NumericLimits::min(); - m_overflow = false; - } - - constexpr void saturating_add(T other) - { - add(other); - // Depending on whether other was positive or negative, we have to saturate to max or min. - if (m_overflow && other >= 0) - m_value = NumericLimits::max(); - else if (m_overflow) - m_value = NumericLimits::min(); - m_overflow = false; - } - - constexpr Checked& operator+=(Checked const& other) - { - m_overflow |= other.m_overflow; - add(other.value()); - return *this; - } - - constexpr Checked& operator+=(T other) - { - add(other); - return *this; - } - - constexpr Checked& operator-=(Checked const& other) - { - m_overflow |= other.m_overflow; - sub(other.value()); - return *this; - } - - constexpr Checked& operator-=(T other) - { - sub(other); - return *this; - } - - constexpr Checked& operator*=(Checked const& other) - { - m_overflow |= other.m_overflow; - mul(other.value()); - return *this; - } - - constexpr Checked& operator*=(T other) - { - mul(other); - return *this; - } - - constexpr Checked& operator/=(Checked const& other) - { - m_overflow |= other.m_overflow; - div(other.value()); - return *this; - } - - constexpr Checked& operator/=(T other) - { - div(other); - return *this; - } - - constexpr Checked& operator++() - { - add(1); - return *this; - } - - constexpr Checked operator++(int) - { - Checked old { *this }; - add(1); - return old; - } - - constexpr Checked& operator--() - { - sub(1); - return *this; - } - - constexpr Checked operator--(int) - { - Checked old { *this }; - sub(1); - return old; - } - - template - static constexpr bool addition_would_overflow(U u, V v) - { - Checked checked; - checked = u; - checked += v; - return checked.has_overflow(); - } - - template - [[nodiscard]] static constexpr bool multiplication_would_overflow(U u, V v) - { - Checked checked; - checked = u; - checked *= v; - return checked.has_overflow(); - } - - template - [[nodiscard]] static constexpr bool multiplication_would_overflow(U u, V v, X x) - { - Checked checked; - checked = u; - checked *= v; - checked *= x; - return checked.has_overflow(); - } - -private: - T m_value {}; - bool m_overflow { false }; -}; - -template -constexpr Checked operator+(Checked const& a, Checked const& b) -{ - Checked c { a }; - c.add(b.value()); - return c; -} - -template -constexpr Checked operator-(Checked const& a, Checked const& b) -{ - Checked c { a }; - c.sub(b.value()); - return c; -} - -template -constexpr Checked operator*(Checked const& a, Checked const& b) -{ - Checked c { a }; - c.mul(b.value()); - return c; -} - -template -constexpr Checked operator/(Checked const& a, Checked const& b) -{ - Checked c { a }; - c.div(b.value()); - return c; -} - -template -constexpr bool operator<(Checked const& a, T b) -{ - return a.value() < b; -} - -template -constexpr bool operator>(Checked const& a, T b) -{ - return a.value() > b; -} - -template -constexpr bool operator>=(Checked const& a, T b) -{ - return a.value() >= b; -} - -template -constexpr bool operator<=(Checked const& a, T b) -{ - return a.value() <= b; -} - -template -constexpr bool operator==(Checked const& a, T b) -{ - return a.value() == b; -} - -template -constexpr bool operator!=(Checked const& a, T b) -{ - return a.value() != b; -} - -template -constexpr bool operator<(T a, Checked const& b) -{ - return a < b.value(); -} - -template -constexpr bool operator>(T a, Checked const& b) -{ - return a > b.value(); -} - -template -constexpr bool operator>=(T a, Checked const& b) -{ - return a >= b.value(); -} - -template -constexpr bool operator<=(T a, Checked const& b) -{ - return a <= b.value(); -} - -template -constexpr bool operator==(T a, Checked const& b) -{ - return a == b.value(); -} - -template -constexpr bool operator!=(T a, Checked const& b) -{ - return a != b.value(); -} - -template -constexpr Checked make_checked(T value) -{ - return Checked(value); -} - -} - -using AK::Checked; -using AK::make_checked; +/* + * Copyright (C) 2011-2019 Apple Inc. All rights reserved. + * Copyright (c) 2020-2021, Andreas Kling + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include "Assertions.h" +#include "Concepts.h" +#include "NumericLimits.h" +#include "StdLibExtras.h" + +namespace AK { + +template= sizeof(Source)), bool destination_is_signed = NumericLimits::is_signed(), bool source_is_signed = NumericLimits::is_signed()> +struct TypeBoundsChecker; + +template +struct TypeBoundsChecker { + static constexpr bool is_within_range(Source value) + { + return value <= NumericLimits::max(); + } +}; + +template +struct TypeBoundsChecker { + static constexpr bool is_within_range(Source value) + { + return value <= NumericLimits::max() + && NumericLimits::min() <= value; + } +}; + +template +struct TypeBoundsChecker { + static constexpr bool is_within_range(Source value) + { + return value >= 0 && value <= NumericLimits::max(); + } +}; + +template +struct TypeBoundsChecker { + static constexpr bool is_within_range(Source value) + { + return value <= static_cast(NumericLimits::max()); + } +}; + +template +struct TypeBoundsChecker { + static constexpr bool is_within_range(Source) + { + return true; + } +}; + +template +struct TypeBoundsChecker { + static constexpr bool is_within_range(Source) + { + return true; + } +}; + +template +struct TypeBoundsChecker { + static constexpr bool is_within_range(Source value) + { + return value >= 0; + } +}; + +template +struct TypeBoundsChecker { + static constexpr bool is_within_range(Source value) + { + if (sizeof(Destination) > sizeof(Source)) + return true; + return value <= static_cast(NumericLimits::max()); + } +}; + +template +[[nodiscard]] constexpr bool is_within_range(Source value) +{ + return TypeBoundsChecker::is_within_range(value); +} + +template +class Checked { +public: + constexpr Checked() = default; + + explicit constexpr Checked(T value) + : m_value(value) + { + } + + template + constexpr Checked(U value) + { + m_overflow = !is_within_range(value); + m_value = value; + } + + constexpr Checked(Checked const&) = default; + + constexpr Checked(Checked&& other) + : m_value(exchange(other.m_value, 0)) + , m_overflow(exchange(other.m_overflow, false)) + { + } + + template + constexpr Checked& operator=(U value) + { + *this = Checked(value); + return *this; + } + + constexpr Checked& operator=(Checked const& other) = default; + + constexpr Checked& operator=(Checked&& other) + { + m_value = exchange(other.m_value, 0); + m_overflow = exchange(other.m_overflow, false); + return *this; + } + + [[nodiscard]] constexpr bool has_overflow() const + { + return m_overflow; + } + + ALWAYS_INLINE constexpr bool operator!() const + { + VERIFY(!m_overflow); + return !m_value; + } + + ALWAYS_INLINE constexpr T value() const + { + VERIFY(!m_overflow); + return m_value; + } + + constexpr void add(T other) + { + m_overflow |= __builtin_add_overflow(m_value, other, &m_value); + } + + constexpr void sub(T other) + { + m_overflow |= __builtin_sub_overflow(m_value, other, &m_value); + } + + constexpr void mul(T other) + { + m_overflow |= __builtin_mul_overflow(m_value, other, &m_value); + } + + constexpr void div(T other) + { + if constexpr (IsSigned) { + // Ensure that the resulting value won't be out of range, this can only happen when dividing by -1. + if (other == -1 && m_value == NumericLimits::min()) { + m_overflow = true; + return; + } + } + if (other == 0) { + m_overflow = true; + return; + } + m_value /= other; + } + + constexpr void saturating_sub(T other) + { + sub(other); + // Depending on whether other was positive or negative, we have to saturate to min or max. + if (m_overflow && other <= 0) + m_value = NumericLimits::max(); + else if (m_overflow) + m_value = NumericLimits::min(); + m_overflow = false; + } + + constexpr void saturating_add(T other) + { + add(other); + // Depending on whether other was positive or negative, we have to saturate to max or min. + if (m_overflow && other >= 0) + m_value = NumericLimits::max(); + else if (m_overflow) + m_value = NumericLimits::min(); + m_overflow = false; + } + + constexpr Checked& operator+=(Checked const& other) + { + m_overflow |= other.m_overflow; + add(other.value()); + return *this; + } + + constexpr Checked& operator+=(T other) + { + add(other); + return *this; + } + + constexpr Checked& operator-=(Checked const& other) + { + m_overflow |= other.m_overflow; + sub(other.value()); + return *this; + } + + constexpr Checked& operator-=(T other) + { + sub(other); + return *this; + } + + constexpr Checked& operator*=(Checked const& other) + { + m_overflow |= other.m_overflow; + mul(other.value()); + return *this; + } + + constexpr Checked& operator*=(T other) + { + mul(other); + return *this; + } + + constexpr Checked& operator/=(Checked const& other) + { + m_overflow |= other.m_overflow; + div(other.value()); + return *this; + } + + constexpr Checked& operator/=(T other) + { + div(other); + return *this; + } + + constexpr Checked& operator++() + { + add(1); + return *this; + } + + constexpr Checked operator++(int) + { + Checked old { *this }; + add(1); + return old; + } + + constexpr Checked& operator--() + { + sub(1); + return *this; + } + + constexpr Checked operator--(int) + { + Checked old { *this }; + sub(1); + return old; + } + + template + static constexpr bool addition_would_overflow(U u, V v) + { + Checked checked; + checked = u; + checked += v; + return checked.has_overflow(); + } + + template + [[nodiscard]] static constexpr bool multiplication_would_overflow(U u, V v) + { + Checked checked; + checked = u; + checked *= v; + return checked.has_overflow(); + } + + template + [[nodiscard]] static constexpr bool multiplication_would_overflow(U u, V v, X x) + { + Checked checked; + checked = u; + checked *= v; + checked *= x; + return checked.has_overflow(); + } + +private: + T m_value {}; + bool m_overflow { false }; +}; + +template +constexpr Checked operator+(Checked const& a, Checked const& b) +{ + Checked c { a }; + c.add(b.value()); + return c; +} + +template +constexpr Checked operator-(Checked const& a, Checked const& b) +{ + Checked c { a }; + c.sub(b.value()); + return c; +} + +template +constexpr Checked operator*(Checked const& a, Checked const& b) +{ + Checked c { a }; + c.mul(b.value()); + return c; +} + +template +constexpr Checked operator/(Checked const& a, Checked const& b) +{ + Checked c { a }; + c.div(b.value()); + return c; +} + +template +constexpr bool operator<(Checked const& a, T b) +{ + return a.value() < b; +} + +template +constexpr bool operator>(Checked const& a, T b) +{ + return a.value() > b; +} + +template +constexpr bool operator>=(Checked const& a, T b) +{ + return a.value() >= b; +} + +template +constexpr bool operator<=(Checked const& a, T b) +{ + return a.value() <= b; +} + +template +constexpr bool operator==(Checked const& a, T b) +{ + return a.value() == b; +} + +template +constexpr bool operator!=(Checked const& a, T b) +{ + return a.value() != b; +} + +template +constexpr bool operator<(T a, Checked const& b) +{ + return a < b.value(); +} + +template +constexpr bool operator>(T a, Checked const& b) +{ + return a > b.value(); +} + +template +constexpr bool operator>=(T a, Checked const& b) +{ + return a >= b.value(); +} + +template +constexpr bool operator<=(T a, Checked const& b) +{ + return a <= b.value(); +} + +template +constexpr bool operator==(T a, Checked const& b) +{ + return a == b.value(); +} + +template +constexpr bool operator!=(T a, Checked const& b) +{ + return a != b.value(); +} + +template +constexpr Checked make_checked(T value) +{ + return Checked(value); +} + +} + +using AK::Checked; +using AK::make_checked; diff --git a/AK/AK/CheckedFormatString.h b/LibC-Shim/AK/CheckedFormatString.h similarity index 80% rename from AK/AK/CheckedFormatString.h rename to LibC-Shim/AK/CheckedFormatString.h index ec4952b..bd1f7e1 100644 --- a/AK/AK/CheckedFormatString.h +++ b/LibC-Shim/AK/CheckedFormatString.h @@ -1,42 +1,42 @@ -/* - * Copyright (c) 2021, the SerenityOS developers. - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include "./AK/AllOf.h" -#include "./AK/AnyOf.h" -#include "./AK/Array.h" -#include "./AK/StdLibExtras.h" -#include "./AK/StringView.h" - -namespace AK::Format::Detail { -template -struct CheckedFormatString { - template - consteval CheckedFormatString(char const (&fmt)[N]) - : m_string{ fmt, N - 1 } - { - } - - template - CheckedFormatString(const T& unchecked_fmt) requires(requires(T t) { StringView{ t }; }) - : m_string(unchecked_fmt) - { - } - - auto view() const { return m_string; } - -private: - StringView m_string; -}; -} - -namespace AK { - -template -using CheckedFormatString = Format::Detail::CheckedFormatString...>; - -} +/* + * Copyright (c) 2021, the SerenityOS developers. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include "AllOf.h" +#include "AnyOf.h" +#include "Array.h" +#include "StdLibExtras.h" +#include "StringView.h" + +namespace AK::Format::Detail { +template +struct CheckedFormatString { + template + consteval CheckedFormatString(char const (&fmt)[N]) + : m_string{ fmt, N - 1 } + { + } + + template + CheckedFormatString(const T& unchecked_fmt) requires(requires(T t) { StringView{ t }; }) + : m_string(unchecked_fmt) + { + } + + auto view() const { return m_string; } + +private: + StringView m_string; +}; +} + +namespace AK { + +template +using CheckedFormatString = Format::Detail::CheckedFormatString...>; + +} diff --git a/AK/AK/Concepts.h b/LibC-Shim/AK/Concepts.h similarity index 92% rename from AK/AK/Concepts.h rename to LibC-Shim/AK/Concepts.h index 75d8c79..e1bf12f 100644 --- a/AK/AK/Concepts.h +++ b/LibC-Shim/AK/Concepts.h @@ -1,128 +1,128 @@ -/* - * Copyright (c) 2020, the SerenityOS developers. - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include "./AK/Forward.h" -#include "./AK/IterationDecision.h" -#include "./AK/StdLibExtras.h" - -namespace AK::Concepts { - -template -concept Integral = IsIntegral; - -template -concept FloatingPoint = IsFloatingPoint; - -template -concept Fundamental = IsFundamental; - -template -concept Arithmetic = IsArithmetic; - -template -concept Signed = IsSigned; - -template -concept Unsigned = IsUnsigned; - -template -concept Enum = IsEnum; - -template -concept SameAs = IsSame; - -template -concept OneOf = IsOneOf; - -template -concept OneOfIgnoringCV = IsOneOfIgnoringCV; - -template typename S> -concept SpecializationOf = IsSpecializationOf; - -template -concept AnyString = Detail::IsConstructible; - -template -concept HashCompatible = IsHashCompatible, Detail::Decay>; - -template -concept ArrayLike = requires(ArrayT array, SizeT index) -{ - { - array[index] - } - -> SameAs&>; - - { - array.size() - } - -> SameAs; - - { - array.span() - } - -> SameAs>>; - - { - array.data() - } - -> SameAs*>; -}; - -template -concept VoidFunction = requires(Func func, Args... args) -{ - { - func(args...) - } - -> SameAs; -}; - -template -concept IteratorFunction = requires(Func func, Args... args) -{ - { - func(args...) - } - -> SameAs; -}; - -template -concept IteratorPairWith = requires(T it, EndT end) -{ - *it; - { it != end } -> SameAs; - ++it; -}; - -template -concept IterableContainer = requires -{ - { declval().begin() } -> IteratorPairWith().end())>; -}; - -} - -using AK::Concepts::Arithmetic; -using AK::Concepts::ArrayLike; -using AK::Concepts::Enum; -using AK::Concepts::FloatingPoint; -using AK::Concepts::Fundamental; -using AK::Concepts::Integral; -using AK::Concepts::IterableContainer; -using AK::Concepts::IteratorFunction; -using AK::Concepts::IteratorPairWith; -using AK::Concepts::OneOf; -using AK::Concepts::OneOfIgnoringCV; -using AK::Concepts::SameAs; -using AK::Concepts::Signed; -using AK::Concepts::SpecializationOf; -using AK::Concepts::Unsigned; -using AK::Concepts::VoidFunction; - +/* + * Copyright (c) 2020, the SerenityOS developers. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include "Forward.h" +#include "IterationDecision.h" +#include "StdLibExtras.h" + +namespace AK::Concepts { + +template +concept Integral = IsIntegral; + +template +concept FloatingPoint = IsFloatingPoint; + +template +concept Fundamental = IsFundamental; + +template +concept Arithmetic = IsArithmetic; + +template +concept Signed = IsSigned; + +template +concept Unsigned = IsUnsigned; + +template +concept Enum = IsEnum; + +template +concept SameAs = IsSame; + +template +concept OneOf = IsOneOf; + +template +concept OneOfIgnoringCV = IsOneOfIgnoringCV; + +template typename S> +concept SpecializationOf = IsSpecializationOf; + +template +concept AnyString = Detail::IsConstructible; + +template +concept HashCompatible = IsHashCompatible, Detail::Decay>; + +template +concept ArrayLike = requires(ArrayT array, SizeT index) +{ + { + array[index] + } + -> SameAs&>; + + { + array.size() + } + -> SameAs; + + { + array.span() + } + -> SameAs>>; + + { + array.data() + } + -> SameAs*>; +}; + +template +concept VoidFunction = requires(Func func, Args... args) +{ + { + func(args...) + } + -> SameAs; +}; + +template +concept IteratorFunction = requires(Func func, Args... args) +{ + { + func(args...) + } + -> SameAs; +}; + +template +concept IteratorPairWith = requires(T it, EndT end) +{ + *it; + { it != end } -> SameAs; + ++it; +}; + +template +concept IterableContainer = requires +{ + { declval().begin() } -> IteratorPairWith().end())>; +}; + +} + +using AK::Concepts::Arithmetic; +using AK::Concepts::ArrayLike; +using AK::Concepts::Enum; +using AK::Concepts::FloatingPoint; +using AK::Concepts::Fundamental; +using AK::Concepts::Integral; +using AK::Concepts::IterableContainer; +using AK::Concepts::IteratorFunction; +using AK::Concepts::IteratorPairWith; +using AK::Concepts::OneOf; +using AK::Concepts::OneOfIgnoringCV; +using AK::Concepts::SameAs; +using AK::Concepts::Signed; +using AK::Concepts::SpecializationOf; +using AK::Concepts::Unsigned; +using AK::Concepts::VoidFunction; + diff --git a/AK/AK/DateConstants.h b/LibC-Shim/AK/DateConstants.h similarity index 92% rename from AK/AK/DateConstants.h rename to LibC-Shim/AK/DateConstants.h index 5201705..cd5a471 100644 --- a/AK/AK/DateConstants.h +++ b/LibC-Shim/AK/DateConstants.h @@ -1,47 +1,47 @@ -/* - * Copyright (c) 2022, the SerenityOS developers. - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include "./AK/Array.h" -#include "./AK/StringView.h" - -namespace AK { - -static constexpr Array long_day_names = { - "Sunday"sv, "Monday"sv, "Tuesday"sv, "Wednesday"sv, "Thursday"sv, "Friday"sv, "Saturday"sv -}; - -static constexpr Array short_day_names = { - "Sun"sv, "Mon"sv, "Tue"sv, "Wed"sv, "Thu"sv, "Fri"sv, "Sat"sv -}; - -static constexpr Array mini_day_names = { - "Su"sv, "Mo"sv, "Tu"sv, "We"sv, "Th"sv, "Fr"sv, "Sa"sv -}; - -static constexpr Array micro_day_names = { - "S"sv, "M"sv, "T"sv, "W"sv, "T"sv, "F"sv, "S"sv -}; - -static constexpr Array long_month_names = { - "January"sv, "February"sv, "March"sv, "April"sv, "May"sv, "June"sv, - "July"sv, "August"sv, "September"sv, "October"sv, "November"sv, "December"sv -}; - -static constexpr Array short_month_names = { - "Jan"sv, "Feb"sv, "Mar"sv, "Apr"sv, "May"sv, "Jun"sv, - "Jul"sv, "Aug"sv, "Sep"sv, "Oct"sv, "Nov"sv, "Dec"sv -}; - -} - -using AK::long_day_names; -using AK::long_month_names; -using AK::micro_day_names; -using AK::mini_day_names; -using AK::short_day_names; -using AK::short_month_names; +/* + * Copyright (c) 2022, the SerenityOS developers. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include "Array.h" +#include "StringView.h" + +namespace AK { + +static constexpr Array long_day_names = { + "Sunday"sv, "Monday"sv, "Tuesday"sv, "Wednesday"sv, "Thursday"sv, "Friday"sv, "Saturday"sv +}; + +static constexpr Array short_day_names = { + "Sun"sv, "Mon"sv, "Tue"sv, "Wed"sv, "Thu"sv, "Fri"sv, "Sat"sv +}; + +static constexpr Array mini_day_names = { + "Su"sv, "Mo"sv, "Tu"sv, "We"sv, "Th"sv, "Fr"sv, "Sa"sv +}; + +static constexpr Array micro_day_names = { + "S"sv, "M"sv, "T"sv, "W"sv, "T"sv, "F"sv, "S"sv +}; + +static constexpr Array long_month_names = { + "January"sv, "February"sv, "March"sv, "April"sv, "May"sv, "June"sv, + "July"sv, "August"sv, "September"sv, "October"sv, "November"sv, "December"sv +}; + +static constexpr Array short_month_names = { + "Jan"sv, "Feb"sv, "Mar"sv, "Apr"sv, "May"sv, "Jun"sv, + "Jul"sv, "Aug"sv, "Sep"sv, "Oct"sv, "Nov"sv, "Dec"sv +}; + +} + +using AK::long_day_names; +using AK::long_month_names; +using AK::micro_day_names; +using AK::mini_day_names; +using AK::short_day_names; +using AK::short_month_names; diff --git a/AK/AK/Debug.h b/LibC-Shim/AK/Debug.h similarity index 96% rename from AK/AK/Debug.h rename to LibC-Shim/AK/Debug.h index 4ab39fb..50c5ea4 100644 --- a/AK/AK/Debug.h +++ b/LibC-Shim/AK/Debug.h @@ -1,8 +1,8 @@ -#pragma once - -#define HEAP_DEBUG 0 -#define PROMISE_DEBUG 0 -#define JS_MODULE_DEBUG 0 -#define LEXER_DEBUG 0 -#define SYNTAX_HIGHLIGHTING_DEBUG 0 +#pragma once + +#define HEAP_DEBUG 0 +#define PROMISE_DEBUG 0 +#define JS_MODULE_DEBUG 0 +#define LEXER_DEBUG 0 +#define SYNTAX_HIGHLIGHTING_DEBUG 0 #define JS_BYTECODE_DEBUG 0 \ No newline at end of file diff --git a/AK/AK/Demangle.h b/LibC-Shim/AK/Demangle.h similarity index 75% rename from AK/AK/Demangle.h rename to LibC-Shim/AK/Demangle.h index 25ace6a..4a5f8b0 100644 --- a/AK/AK/Demangle.h +++ b/LibC-Shim/AK/Demangle.h @@ -1,18 +1,18 @@ -/* - * Copyright (c) 2018-2020, Andreas Kling - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include "./AK/String.h" -#include "./AK/StringView.h" - -namespace AK { - -ALWAYS_INLINE String demangle(StringView name); - -} - -using AK::demangle; +/* + * Copyright (c) 2018-2020, Andreas Kling + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include "String.h" +#include "StringView.h" + +namespace AK { + +ALWAYS_INLINE String demangle(StringView name); + +} + +using AK::demangle; diff --git a/AK/AK/DisjointChunks.h b/LibC-Shim/AK/DisjointChunks.h similarity index 83% rename from AK/AK/DisjointChunks.h rename to LibC-Shim/AK/DisjointChunks.h index 9ee370a..88c1fba 100644 --- a/AK/AK/DisjointChunks.h +++ b/LibC-Shim/AK/DisjointChunks.h @@ -1,52 +1,52 @@ -#pragma once - -#include "./AK/AllOf.h" -#include "./AK/Forward.h" -#include "./AK/Span.h" -#include "./AK/StdLibExtras.h" -#include "./AK/Try.h" - -namespace AK { - -template> -class DisjointChunks { -public: - DisjointChunks() = default; - ~DisjointChunks() = default; - DisjointChunks(DisjointChunks const&) = default; - DisjointChunks(DisjointChunks&&) = default; - - DisjointChunks& operator=(DisjointChunks&&) = default; - DisjointChunks& operator=(DisjointChunks const&) = default; - - void append(ChunkType&& chunk); - void extend(DisjointChunks&& chunks); - void extend(DisjointChunks const& chunks); - - ChunkType& first_chunk(); - ChunkType& last_chunk(); - ChunkType const& first_chunk() const; - ChunkType const& last_chunk() const; - - void ensure_capacity(size_t needed_capacity); - - void insert(size_t index, T value); - - void clear(); - - T& operator[](size_t index); - T const& at(size_t index) const; - T& at(size_t index); - - T* find(size_t index); - - T const* find(size_t index) const; - - size_t size() const; - - bool is_empty() const; -}; - -} - -using AK::DisjointChunks; \ No newline at end of file +#pragma once + +#include "AllOf.h" +#include "Forward.h" +#include "Span.h" +#include "StdLibExtras.h" +#include "Try.h" + +namespace AK { + +template> +class DisjointChunks { +public: + DisjointChunks() = default; + ~DisjointChunks() = default; + DisjointChunks(DisjointChunks const&) = default; + DisjointChunks(DisjointChunks&&) = default; + + DisjointChunks& operator=(DisjointChunks&&) = default; + DisjointChunks& operator=(DisjointChunks const&) = default; + + void append(ChunkType&& chunk); + void extend(DisjointChunks&& chunks); + void extend(DisjointChunks const& chunks); + + ChunkType& first_chunk(); + ChunkType& last_chunk(); + ChunkType const& first_chunk() const; + ChunkType const& last_chunk() const; + + void ensure_capacity(size_t needed_capacity); + + void insert(size_t index, T value); + + void clear(); + + T& operator[](size_t index); + T const& at(size_t index) const; + T& at(size_t index); + + T* find(size_t index); + + T const* find(size_t index) const; + + size_t size() const; + + bool is_empty() const; +}; + +} + +using AK::DisjointChunks; diff --git a/AK/AK/DistinctNumeric.h b/LibC-Shim/AK/DistinctNumeric.h similarity index 96% rename from AK/AK/DistinctNumeric.h rename to LibC-Shim/AK/DistinctNumeric.h index 3cf6eba..a7f4ca0 100644 --- a/AK/AK/DistinctNumeric.h +++ b/LibC-Shim/AK/DistinctNumeric.h @@ -1,298 +1,298 @@ -/* - * Copyright (c) 2020, Ben Wiederhake - * Copyright (c) 2021, Andreas Kling - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include "./AK/Format.h" -#include "./AK/Traits.h" -#include "./AK/Types.h" - -namespace AK { - -/** - * This implements a "distinct" numeric type that is intentionally incompatible - * to other incantations. The intention is that each "distinct" type that you - * want simply gets different values for `fn_length` and `line`. The macros - * `TYPEDEF_DISTINCT_NUMERIC_*()` at the bottom of `DistinctNumeric.h`. - * - * `Incr`, `Cmp`, `Bool`, `Flags`, `Shift`, and `Arith` simply split up the - * space of operators into 6 simple categories: - * - No matter the values of these, `DistinctNumeric` always implements `==` and `!=`. - * - If `Incr` is true, then `++a`, `a++`, `--a`, and `a--` are implemented. - * - If `Cmp` is true, then `a>b`, `a=b`, and `a<=b` are implemented. - * - If `Bool` is true, then `!a`, `a&&b`, and `a||b` are implemented (but not `operator bool()`, because of overzealous integer promotion rules). - * - If `Flags` is true, then `~a`, `a&b`, `a|b`, `a^b`, `a&=b`, `a|=b`, and `a^=b` are implemented. - * - If `Shift` is true, then `a<>b`, `a<<=b`, `a>>=b` are implemented. - * - If `Arith` is true, then `a+b`, `a-b`, `+a`, `-a`, `a*b`, `a/b`, `a%b`, and the respective `a_=b` versions are implemented. - * The semantics are always those of the underlying basic type `T`. - * - * These can be combined arbitrarily. Want a numeric type that supports `++a` - * and `a >> b` but not `a > b`? Sure thing, just set - * `Incr=true, Cmp=false, Shift=true` and you're done! - * Furthermore, some of these overloads make more sense with specific types, like `a&&b` which should be able to operate - * - * I intentionally decided against overloading `&a` because these shall remain - * numeric types. - * - * The C++20 `operator<=>` would require, among other things `std::weak_equality`. - * Since we do not have that, it cannot be implemented. - * - * The are many operators that do not work on `int`, so I left them out: - * `a[b]`, `*a`, `a->b`, `a.b`, `a->*b`, `a.*b`. - * - * There are many more operators that do not make sense for numerical types, - * or cannot be overloaded in the first place. Naturally, they are not implemented. - */ -template -class DistinctNumeric { - using Self = DistinctNumeric; - -public: - constexpr DistinctNumeric() = default; - - constexpr DistinctNumeric(T value) - : m_value{ value } - { - } - - constexpr const T& value() const { return m_value; } - constexpr T& value() { return m_value; } - - // Always implemented: identity. - constexpr bool operator==(Self const& other) const - { - return this->m_value == other.m_value; - } - constexpr bool operator!=(Self const& other) const - { - return this->m_value != other.m_value; - } - - // Only implemented when `Incr` is true: - constexpr Self& operator++() - { - static_assert(Incr, "'++a' is only available for DistinctNumeric types with 'Incr'."); - this->m_value += 1; - return *this; - } - constexpr Self operator++(int) - { - static_assert(Incr, "'a++' is only available for DistinctNumeric types with 'Incr'."); - Self ret = this->m_value; - this->m_value += 1; - return ret; - } - constexpr Self& operator--() - { - static_assert(Incr, "'--a' is only available for DistinctNumeric types with 'Incr'."); - this->m_value -= 1; - return *this; - } - constexpr Self operator--(int) - { - static_assert(Incr, "'a--' is only available for DistinctNumeric types with 'Incr'."); - Self ret = this->m_value; - this->m_value -= 1; - return ret; - } - - // Only implemented when `Cmp` is true: - constexpr bool operator>(Self const& other) const - { - static_assert(Cmp, "'a>b' is only available for DistinctNumeric types with 'Cmp'."); - return this->m_value > other.m_value; - } - constexpr bool operator<(Self const& other) const - { - static_assert(Cmp, "'am_value < other.m_value; - } - constexpr bool operator>=(Self const& other) const - { - static_assert(Cmp, "'a>=b' is only available for DistinctNumeric types with 'Cmp'."); - return this->m_value >= other.m_value; - } - constexpr bool operator<=(Self const& other) const - { - static_assert(Cmp, "'a<=b' is only available for DistinctNumeric types with 'Cmp'."); - return this->m_value <= other.m_value; - } - // 'operator<=>' cannot be implemented. See class comment. - - // Only implemented when `bool` is true: - constexpr bool operator!() const - { - static_assert(Bool, "'!a' is only available for DistinctNumeric types with 'Bool'."); - return !this->m_value; - } - // Intentionally don't define `operator bool() const` here. C++ is a bit - // overzealous, and whenever there would be a type error, C++ instead tries - // to convert to a common int-ish type first. `bool` is int-ish, so - // `operator bool() const` would defy the entire point of this class. - - // Only implemented when `Flags` is true: - constexpr Self operator~() const - { - static_assert(Flags, "'~a' is only available for DistinctNumeric types with 'Flags'."); - return ~this->m_value; - } - constexpr Self operator&(Self const& other) const - { - static_assert(Flags, "'a&b' is only available for DistinctNumeric types with 'Flags'."); - return this->m_value & other.m_value; - } - constexpr Self operator|(Self const& other) const - { - static_assert(Flags, "'a|b' is only available for DistinctNumeric types with 'Flags'."); - return this->m_value | other.m_value; - } - constexpr Self operator^(Self const& other) const - { - static_assert(Flags, "'a^b' is only available for DistinctNumeric types with 'Flags'."); - return this->m_value ^ other.m_value; - } - constexpr Self& operator&=(Self const& other) - { - static_assert(Flags, "'a&=b' is only available for DistinctNumeric types with 'Flags'."); - this->m_value &= other.m_value; - return *this; - } - constexpr Self& operator|=(Self const& other) - { - static_assert(Flags, "'a|=b' is only available for DistinctNumeric types with 'Flags'."); - this->m_value |= other.m_value; - return *this; - } - constexpr Self& operator^=(Self const& other) - { - static_assert(Flags, "'a^=b' is only available for DistinctNumeric types with 'Flags'."); - this->m_value ^= other.m_value; - return *this; - } - - // Only implemented when `Shift` is true: - // TODO: Should this take `int` instead? - constexpr Self operator<<(Self const& other) const - { - static_assert(Shift, "'a<m_value << other.m_value; - } - constexpr Self operator>>(Self const& other) const - { - static_assert(Shift, "'a>>b' is only available for DistinctNumeric types with 'Shift'."); - return this->m_value >> other.m_value; - } - constexpr Self& operator<<=(Self const& other) - { - static_assert(Shift, "'a<<=b' is only available for DistinctNumeric types with 'Shift'."); - this->m_value <<= other.m_value; - return *this; - } - constexpr Self& operator>>=(Self const& other) - { - static_assert(Shift, "'a>>=b' is only available for DistinctNumeric types with 'Shift'."); - this->m_value >>= other.m_value; - return *this; - } - - // Only implemented when `Arith` is true: - constexpr Self operator+(Self const& other) const - { - static_assert(Arith, "'a+b' is only available for DistinctNumeric types with 'Arith'."); - return this->m_value + other.m_value; - } - constexpr Self operator-(Self const& other) const - { - static_assert(Arith, "'a-b' is only available for DistinctNumeric types with 'Arith'."); - return this->m_value - other.m_value; - } - constexpr Self operator+() const - { - static_assert(Arith, "'+a' is only available for DistinctNumeric types with 'Arith'."); - return +this->m_value; - } - constexpr Self operator-() const - { - static_assert(Arith, "'-a' is only available for DistinctNumeric types with 'Arith'."); - return -this->m_value; - } - constexpr Self operator*(Self const& other) const - { - static_assert(Arith, "'a*b' is only available for DistinctNumeric types with 'Arith'."); - return this->m_value * other.m_value; - } - constexpr Self operator/(Self const& other) const - { - static_assert(Arith, "'a/b' is only available for DistinctNumeric types with 'Arith'."); - return this->m_value / other.m_value; - } - constexpr Self operator%(Self const& other) const - { - static_assert(Arith, "'a%b' is only available for DistinctNumeric types with 'Arith'."); - return this->m_value % other.m_value; - } - constexpr Self& operator+=(Self const& other) - { - static_assert(Arith, "'a+=b' is only available for DistinctNumeric types with 'Arith'."); - this->m_value += other.m_value; - return *this; - } - constexpr Self& operator-=(Self const& other) - { - static_assert(Arith, "'a+=b' is only available for DistinctNumeric types with 'Arith'."); - this->m_value += other.m_value; - return *this; - } - constexpr Self& operator*=(Self const& other) - { - static_assert(Arith, "'a*=b' is only available for DistinctNumeric types with 'Arith'."); - this->m_value *= other.m_value; - return *this; - } - constexpr Self& operator/=(Self const& other) - { - static_assert(Arith, "'a/=b' is only available for DistinctNumeric types with 'Arith'."); - this->m_value /= other.m_value; - return *this; - } - constexpr Self& operator%=(Self const& other) - { - static_assert(Arith, "'a%=b' is only available for DistinctNumeric types with 'Arith'."); - this->m_value %= other.m_value; - return *this; - } - -private: - T m_value{}; -}; - -template -struct Formatter> : Formatter { - ErrorOr format(FormatBuilder& builder, DistinctNumeric value) - { - return Formatter::format(builder, value.value()); - } -}; - -// TODO: When 'consteval' sufficiently-well supported by host compilers, try to -// provide a more usable interface like this one: -// https://gist.github.com/alimpfard/a3b750e8c3a2f44fb3a2d32038968ddf - -} - -#define AK_TYPEDEF_DISTINCT_NUMERIC_GENERAL(T, Incr, Cmp, Bool, Flags, Shift, Arith, NAME) \ - using NAME = DistinctNumeric; -#define AK_TYPEDEF_DISTINCT_ORDERED_ID(T, NAME) AK_TYPEDEF_DISTINCT_NUMERIC_GENERAL(T, false, true, true, false, false, false, NAME) -// TODO: Further type aliases? - -template -struct Traits> : public GenericTraits> { - static constexpr bool is_trivial() { return true; } - static constexpr auto hash(DistinctNumeric const& d) { return Traits::hash(d.value()); } -}; - -using AK::DistinctNumeric; +/* + * Copyright (c) 2020, Ben Wiederhake + * Copyright (c) 2021, Andreas Kling + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include "Format.h" +#include "Traits.h" +#include "Types.h" + +namespace AK { + +/** + * This implements a "distinct" numeric type that is intentionally incompatible + * to other incantations. The intention is that each "distinct" type that you + * want simply gets different values for `fn_length` and `line`. The macros + * `TYPEDEF_DISTINCT_NUMERIC_*()` at the bottom of `DistinctNumeric.h`. + * + * `Incr`, `Cmp`, `Bool`, `Flags`, `Shift`, and `Arith` simply split up the + * space of operators into 6 simple categories: + * - No matter the values of these, `DistinctNumeric` always implements `==` and `!=`. + * - If `Incr` is true, then `++a`, `a++`, `--a`, and `a--` are implemented. + * - If `Cmp` is true, then `a>b`, `a=b`, and `a<=b` are implemented. + * - If `Bool` is true, then `!a`, `a&&b`, and `a||b` are implemented (but not `operator bool()`, because of overzealous integer promotion rules). + * - If `Flags` is true, then `~a`, `a&b`, `a|b`, `a^b`, `a&=b`, `a|=b`, and `a^=b` are implemented. + * - If `Shift` is true, then `a<>b`, `a<<=b`, `a>>=b` are implemented. + * - If `Arith` is true, then `a+b`, `a-b`, `+a`, `-a`, `a*b`, `a/b`, `a%b`, and the respective `a_=b` versions are implemented. + * The semantics are always those of the underlying basic type `T`. + * + * These can be combined arbitrarily. Want a numeric type that supports `++a` + * and `a >> b` but not `a > b`? Sure thing, just set + * `Incr=true, Cmp=false, Shift=true` and you're done! + * Furthermore, some of these overloads make more sense with specific types, like `a&&b` which should be able to operate + * + * I intentionally decided against overloading `&a` because these shall remain + * numeric types. + * + * The C++20 `operator<=>` would require, among other things `std::weak_equality`. + * Since we do not have that, it cannot be implemented. + * + * The are many operators that do not work on `int`, so I left them out: + * `a[b]`, `*a`, `a->b`, `a.b`, `a->*b`, `a.*b`. + * + * There are many more operators that do not make sense for numerical types, + * or cannot be overloaded in the first place. Naturally, they are not implemented. + */ +template +class DistinctNumeric { + using Self = DistinctNumeric; + +public: + constexpr DistinctNumeric() = default; + + constexpr DistinctNumeric(T value) + : m_value{ value } + { + } + + constexpr const T& value() const { return m_value; } + constexpr T& value() { return m_value; } + + // Always implemented: identity. + constexpr bool operator==(Self const& other) const + { + return this->m_value == other.m_value; + } + constexpr bool operator!=(Self const& other) const + { + return this->m_value != other.m_value; + } + + // Only implemented when `Incr` is true: + constexpr Self& operator++() + { + static_assert(Incr, "'++a' is only available for DistinctNumeric types with 'Incr'."); + this->m_value += 1; + return *this; + } + constexpr Self operator++(int) + { + static_assert(Incr, "'a++' is only available for DistinctNumeric types with 'Incr'."); + Self ret = this->m_value; + this->m_value += 1; + return ret; + } + constexpr Self& operator--() + { + static_assert(Incr, "'--a' is only available for DistinctNumeric types with 'Incr'."); + this->m_value -= 1; + return *this; + } + constexpr Self operator--(int) + { + static_assert(Incr, "'a--' is only available for DistinctNumeric types with 'Incr'."); + Self ret = this->m_value; + this->m_value -= 1; + return ret; + } + + // Only implemented when `Cmp` is true: + constexpr bool operator>(Self const& other) const + { + static_assert(Cmp, "'a>b' is only available for DistinctNumeric types with 'Cmp'."); + return this->m_value > other.m_value; + } + constexpr bool operator<(Self const& other) const + { + static_assert(Cmp, "'am_value < other.m_value; + } + constexpr bool operator>=(Self const& other) const + { + static_assert(Cmp, "'a>=b' is only available for DistinctNumeric types with 'Cmp'."); + return this->m_value >= other.m_value; + } + constexpr bool operator<=(Self const& other) const + { + static_assert(Cmp, "'a<=b' is only available for DistinctNumeric types with 'Cmp'."); + return this->m_value <= other.m_value; + } + // 'operator<=>' cannot be implemented. See class comment. + + // Only implemented when `bool` is true: + constexpr bool operator!() const + { + static_assert(Bool, "'!a' is only available for DistinctNumeric types with 'Bool'."); + return !this->m_value; + } + // Intentionally don't define `operator bool() const` here. C++ is a bit + // overzealous, and whenever there would be a type error, C++ instead tries + // to convert to a common int-ish type first. `bool` is int-ish, so + // `operator bool() const` would defy the entire point of this class. + + // Only implemented when `Flags` is true: + constexpr Self operator~() const + { + static_assert(Flags, "'~a' is only available for DistinctNumeric types with 'Flags'."); + return ~this->m_value; + } + constexpr Self operator&(Self const& other) const + { + static_assert(Flags, "'a&b' is only available for DistinctNumeric types with 'Flags'."); + return this->m_value & other.m_value; + } + constexpr Self operator|(Self const& other) const + { + static_assert(Flags, "'a|b' is only available for DistinctNumeric types with 'Flags'."); + return this->m_value | other.m_value; + } + constexpr Self operator^(Self const& other) const + { + static_assert(Flags, "'a^b' is only available for DistinctNumeric types with 'Flags'."); + return this->m_value ^ other.m_value; + } + constexpr Self& operator&=(Self const& other) + { + static_assert(Flags, "'a&=b' is only available for DistinctNumeric types with 'Flags'."); + this->m_value &= other.m_value; + return *this; + } + constexpr Self& operator|=(Self const& other) + { + static_assert(Flags, "'a|=b' is only available for DistinctNumeric types with 'Flags'."); + this->m_value |= other.m_value; + return *this; + } + constexpr Self& operator^=(Self const& other) + { + static_assert(Flags, "'a^=b' is only available for DistinctNumeric types with 'Flags'."); + this->m_value ^= other.m_value; + return *this; + } + + // Only implemented when `Shift` is true: + // TODO: Should this take `int` instead? + constexpr Self operator<<(Self const& other) const + { + static_assert(Shift, "'a<m_value << other.m_value; + } + constexpr Self operator>>(Self const& other) const + { + static_assert(Shift, "'a>>b' is only available for DistinctNumeric types with 'Shift'."); + return this->m_value >> other.m_value; + } + constexpr Self& operator<<=(Self const& other) + { + static_assert(Shift, "'a<<=b' is only available for DistinctNumeric types with 'Shift'."); + this->m_value <<= other.m_value; + return *this; + } + constexpr Self& operator>>=(Self const& other) + { + static_assert(Shift, "'a>>=b' is only available for DistinctNumeric types with 'Shift'."); + this->m_value >>= other.m_value; + return *this; + } + + // Only implemented when `Arith` is true: + constexpr Self operator+(Self const& other) const + { + static_assert(Arith, "'a+b' is only available for DistinctNumeric types with 'Arith'."); + return this->m_value + other.m_value; + } + constexpr Self operator-(Self const& other) const + { + static_assert(Arith, "'a-b' is only available for DistinctNumeric types with 'Arith'."); + return this->m_value - other.m_value; + } + constexpr Self operator+() const + { + static_assert(Arith, "'+a' is only available for DistinctNumeric types with 'Arith'."); + return +this->m_value; + } + constexpr Self operator-() const + { + static_assert(Arith, "'-a' is only available for DistinctNumeric types with 'Arith'."); + return -this->m_value; + } + constexpr Self operator*(Self const& other) const + { + static_assert(Arith, "'a*b' is only available for DistinctNumeric types with 'Arith'."); + return this->m_value * other.m_value; + } + constexpr Self operator/(Self const& other) const + { + static_assert(Arith, "'a/b' is only available for DistinctNumeric types with 'Arith'."); + return this->m_value / other.m_value; + } + constexpr Self operator%(Self const& other) const + { + static_assert(Arith, "'a%b' is only available for DistinctNumeric types with 'Arith'."); + return this->m_value % other.m_value; + } + constexpr Self& operator+=(Self const& other) + { + static_assert(Arith, "'a+=b' is only available for DistinctNumeric types with 'Arith'."); + this->m_value += other.m_value; + return *this; + } + constexpr Self& operator-=(Self const& other) + { + static_assert(Arith, "'a+=b' is only available for DistinctNumeric types with 'Arith'."); + this->m_value += other.m_value; + return *this; + } + constexpr Self& operator*=(Self const& other) + { + static_assert(Arith, "'a*=b' is only available for DistinctNumeric types with 'Arith'."); + this->m_value *= other.m_value; + return *this; + } + constexpr Self& operator/=(Self const& other) + { + static_assert(Arith, "'a/=b' is only available for DistinctNumeric types with 'Arith'."); + this->m_value /= other.m_value; + return *this; + } + constexpr Self& operator%=(Self const& other) + { + static_assert(Arith, "'a%=b' is only available for DistinctNumeric types with 'Arith'."); + this->m_value %= other.m_value; + return *this; + } + +private: + T m_value{}; +}; + +template +struct Formatter> : Formatter { + ErrorOr format(FormatBuilder& builder, DistinctNumeric value) + { + return Formatter::format(builder, value.value()); + } +}; + +// TODO: When 'consteval' sufficiently-well supported by host compilers, try to +// provide a more usable interface like this one: +// https://gist.github.com/alimpfard/a3b750e8c3a2f44fb3a2d32038968ddf + +} + +#define AK_TYPEDEF_DISTINCT_NUMERIC_GENERAL(T, Incr, Cmp, Bool, Flags, Shift, Arith, NAME) \ + using NAME = DistinctNumeric; +#define AK_TYPEDEF_DISTINCT_ORDERED_ID(T, NAME) AK_TYPEDEF_DISTINCT_NUMERIC_GENERAL(T, false, true, true, false, false, false, NAME) +// TODO: Further type aliases? + +template +struct Traits> : public GenericTraits> { + static constexpr bool is_trivial() { return true; } + static constexpr auto hash(DistinctNumeric const& d) { return Traits::hash(d.value()); } +}; + +using AK::DistinctNumeric; diff --git a/AK/AK/Endian.h b/LibC-Shim/AK/Endian.h similarity index 93% rename from AK/AK/Endian.h rename to LibC-Shim/AK/Endian.h index 54b32f9..eeceb1f 100644 --- a/AK/AK/Endian.h +++ b/LibC-Shim/AK/Endian.h @@ -1,126 +1,126 @@ -/* - * Copyright (c) 2020, the SerenityOS developers. - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include "./AK/Format.h" -#include "./AK/Forward.h" -#include "./AK/Platform.h" - -namespace AK { - -template -ALWAYS_INLINE constexpr T convert_between_host_and_little_endian(T value) -{ -#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ - return value; -#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ - if constexpr (sizeof(T) == 8) - return __builtin_bswap64(value); - if constexpr (sizeof(T) == 4) - return __builtin_bswap32(value); - if constexpr (sizeof(T) == 2) - return __builtin_bswap16(value); - if constexpr (sizeof(T) == 1) - return value; -#endif -} - -template -ALWAYS_INLINE constexpr T convert_between_host_and_big_endian(T value) -{ -#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ - if constexpr (sizeof(T) == 8) - return __builtin_bswap64(value); - if constexpr (sizeof(T) == 4) - return __builtin_bswap32(value); - if constexpr (sizeof(T) == 2) - return __builtin_bswap16(value); - if constexpr (sizeof(T) == 1) - return value; -#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ - return value; -#endif -} - -template -ALWAYS_INLINE T convert_between_host_and_network_endian(T value) -{ - return convert_between_host_and_big_endian(value); -} - -template -class LittleEndian; - -template -InputStream& operator>>(InputStream&, LittleEndian&); - -template -OutputStream& operator<<(OutputStream&, LittleEndian); - -template -class LittleEndian { -public: - friend InputStream& operator>>(InputStream&, LittleEndian&); - friend OutputStream& operator<< (OutputStream&, LittleEndian); - - constexpr LittleEndian() = default; - - constexpr LittleEndian(T value) - : m_value(convert_between_host_and_little_endian(value)) - { - } - - constexpr operator T() const { return convert_between_host_and_little_endian(m_value); } - -private: - T m_value { 0 }; -}; - -template -class BigEndian; - -template -InputStream& operator>>(InputStream&, BigEndian&); - -template -OutputStream& operator<<(OutputStream&, BigEndian); - -template -class BigEndian { -public: - friend InputStream& operator>>(InputStream&, BigEndian&); - friend OutputStream& operator<< (OutputStream&, BigEndian); - - constexpr BigEndian() = default; - - constexpr BigEndian(T value) - : m_value(convert_between_host_and_big_endian(value)) - { - } - - constexpr operator T() const { return convert_between_host_and_big_endian(m_value); } - -private: - T m_value { 0 }; -}; - -template -using NetworkOrdered = BigEndian; - -template -requires(HasFormatter) struct Formatter> : Formatter { -}; - -template -requires(HasFormatter) struct Formatter> : Formatter { -}; - -} - -using AK::BigEndian; -using AK::LittleEndian; -using AK::NetworkOrdered; +/* + * Copyright (c) 2020, the SerenityOS developers. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include "Format.h" +#include "Forward.h" +#include "Platform.h" + +namespace AK { + +template +ALWAYS_INLINE constexpr T convert_between_host_and_little_endian(T value) +{ +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + return value; +#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + if constexpr (sizeof(T) == 8) + return __builtin_bswap64(value); + if constexpr (sizeof(T) == 4) + return __builtin_bswap32(value); + if constexpr (sizeof(T) == 2) + return __builtin_bswap16(value); + if constexpr (sizeof(T) == 1) + return value; +#endif +} + +template +ALWAYS_INLINE constexpr T convert_between_host_and_big_endian(T value) +{ +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + if constexpr (sizeof(T) == 8) + return __builtin_bswap64(value); + if constexpr (sizeof(T) == 4) + return __builtin_bswap32(value); + if constexpr (sizeof(T) == 2) + return __builtin_bswap16(value); + if constexpr (sizeof(T) == 1) + return value; +#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + return value; +#endif +} + +template +ALWAYS_INLINE T convert_between_host_and_network_endian(T value) +{ + return convert_between_host_and_big_endian(value); +} + +template +class LittleEndian; + +template +InputStream& operator>>(InputStream&, LittleEndian&); + +template +OutputStream& operator<<(OutputStream&, LittleEndian); + +template +class LittleEndian { +public: + friend InputStream& operator>>(InputStream&, LittleEndian&); + friend OutputStream& operator<< (OutputStream&, LittleEndian); + + constexpr LittleEndian() = default; + + constexpr LittleEndian(T value) + : m_value(convert_between_host_and_little_endian(value)) + { + } + + constexpr operator T() const { return convert_between_host_and_little_endian(m_value); } + +private: + T m_value { 0 }; +}; + +template +class BigEndian; + +template +InputStream& operator>>(InputStream&, BigEndian&); + +template +OutputStream& operator<<(OutputStream&, BigEndian); + +template +class BigEndian { +public: + friend InputStream& operator>>(InputStream&, BigEndian&); + friend OutputStream& operator<< (OutputStream&, BigEndian); + + constexpr BigEndian() = default; + + constexpr BigEndian(T value) + : m_value(convert_between_host_and_big_endian(value)) + { + } + + constexpr operator T() const { return convert_between_host_and_big_endian(m_value); } + +private: + T m_value { 0 }; +}; + +template +using NetworkOrdered = BigEndian; + +template +requires(HasFormatter) struct Formatter> : Formatter { +}; + +template +requires(HasFormatter) struct Formatter> : Formatter { +}; + +} + +using AK::BigEndian; +using AK::LittleEndian; +using AK::NetworkOrdered; diff --git a/AK/AK/EnumBits.h b/LibC-Shim/AK/EnumBits.h similarity index 97% rename from AK/AK/EnumBits.h rename to LibC-Shim/AK/EnumBits.h index 86fc0c5..139c390 100644 --- a/AK/AK/EnumBits.h +++ b/LibC-Shim/AK/EnumBits.h @@ -1,87 +1,87 @@ -/* - * Copyright (c) 2021, Brian Gianforcaro - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include "./AK/StdLibExtras.h" - -// Enables bitwise operators for the specified Enum type. -// -#define AK_ENUM_BITWISE_OPERATORS(Enum) \ - _AK_ENUM_BITWISE_OPERATORS_INTERNAL(Enum, ) - -// Enables bitwise operators for the specified Enum type, this -// version is meant for use on enums which are private to the -// containing type. -// -#define AK_ENUM_BITWISE_FRIEND_OPERATORS(Enum) \ - _AK_ENUM_BITWISE_OPERATORS_INTERNAL(Enum, friend) - -#define _AK_ENUM_BITWISE_OPERATORS_INTERNAL(Enum, Prefix) \ - \ - [[nodiscard]] Prefix constexpr Enum operator|(Enum lhs, Enum rhs) \ - { \ - using Type = UnderlyingType; \ - return static_cast( \ - static_cast(lhs) | static_cast(rhs)); \ - } \ - \ - [[nodiscard]] Prefix constexpr Enum operator&(Enum lhs, Enum rhs) \ - { \ - using Type = UnderlyingType; \ - return static_cast( \ - static_cast(lhs) & static_cast(rhs)); \ - } \ - \ - [[nodiscard]] Prefix constexpr Enum operator^(Enum lhs, Enum rhs) \ - { \ - using Type = UnderlyingType; \ - return static_cast( \ - static_cast(lhs) ^ static_cast(rhs)); \ - } \ - \ - [[nodiscard]] Prefix constexpr Enum operator~(Enum rhs) \ - { \ - using Type = UnderlyingType; \ - return static_cast( \ - ~static_cast(rhs)); \ - } \ - \ - Prefix constexpr Enum& operator|=(Enum& lhs, Enum rhs) \ - { \ - using Type = UnderlyingType; \ - lhs = static_cast( \ - static_cast(lhs) | static_cast(rhs)); \ - return lhs; \ - } \ - \ - Prefix constexpr Enum& operator&=(Enum& lhs, Enum rhs) \ - { \ - using Type = UnderlyingType; \ - lhs = static_cast( \ - static_cast(lhs) & static_cast(rhs)); \ - return lhs; \ - } \ - \ - Prefix constexpr Enum& operator^=(Enum& lhs, Enum rhs) \ - { \ - using Type = UnderlyingType; \ - lhs = static_cast( \ - static_cast(lhs) ^ static_cast(rhs)); \ - return lhs; \ - } \ - \ - Prefix constexpr bool has_flag(Enum value, Enum mask) \ - { \ - using Type = UnderlyingType; \ - return static_cast(value & mask) == static_cast(mask); \ - } \ - \ - Prefix constexpr bool has_any_flag(Enum value, Enum mask) \ - { \ - using Type = UnderlyingType; \ - return static_cast(value & mask) != 0; \ - } +/* + * Copyright (c) 2021, Brian Gianforcaro + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include "StdLibExtras.h" + +// Enables bitwise operators for the specified Enum type. +// +#define AK_ENUM_BITWISE_OPERATORS(Enum) \ + _AK_ENUM_BITWISE_OPERATORS_INTERNAL(Enum, ) + +// Enables bitwise operators for the specified Enum type, this +// version is meant for use on enums which are private to the +// containing type. +// +#define AK_ENUM_BITWISE_FRIEND_OPERATORS(Enum) \ + _AK_ENUM_BITWISE_OPERATORS_INTERNAL(Enum, friend) + +#define _AK_ENUM_BITWISE_OPERATORS_INTERNAL(Enum, Prefix) \ + \ + [[nodiscard]] Prefix constexpr Enum operator|(Enum lhs, Enum rhs) \ + { \ + using Type = UnderlyingType; \ + return static_cast( \ + static_cast(lhs) | static_cast(rhs)); \ + } \ + \ + [[nodiscard]] Prefix constexpr Enum operator&(Enum lhs, Enum rhs) \ + { \ + using Type = UnderlyingType; \ + return static_cast( \ + static_cast(lhs) & static_cast(rhs)); \ + } \ + \ + [[nodiscard]] Prefix constexpr Enum operator^(Enum lhs, Enum rhs) \ + { \ + using Type = UnderlyingType; \ + return static_cast( \ + static_cast(lhs) ^ static_cast(rhs)); \ + } \ + \ + [[nodiscard]] Prefix constexpr Enum operator~(Enum rhs) \ + { \ + using Type = UnderlyingType; \ + return static_cast( \ + ~static_cast(rhs)); \ + } \ + \ + Prefix constexpr Enum& operator|=(Enum& lhs, Enum rhs) \ + { \ + using Type = UnderlyingType; \ + lhs = static_cast( \ + static_cast(lhs) | static_cast(rhs)); \ + return lhs; \ + } \ + \ + Prefix constexpr Enum& operator&=(Enum& lhs, Enum rhs) \ + { \ + using Type = UnderlyingType; \ + lhs = static_cast( \ + static_cast(lhs) & static_cast(rhs)); \ + return lhs; \ + } \ + \ + Prefix constexpr Enum& operator^=(Enum& lhs, Enum rhs) \ + { \ + using Type = UnderlyingType; \ + lhs = static_cast( \ + static_cast(lhs) ^ static_cast(rhs)); \ + return lhs; \ + } \ + \ + Prefix constexpr bool has_flag(Enum value, Enum mask) \ + { \ + using Type = UnderlyingType; \ + return static_cast(value & mask) == static_cast(mask); \ + } \ + \ + Prefix constexpr bool has_any_flag(Enum value, Enum mask) \ + { \ + using Type = UnderlyingType; \ + return static_cast(value & mask) != 0; \ + } diff --git a/AK/AK/Error.h b/LibC-Shim/AK/Error.h similarity index 92% rename from AK/AK/Error.h rename to LibC-Shim/AK/Error.h index 7136160..646f3ba 100644 --- a/AK/AK/Error.h +++ b/LibC-Shim/AK/Error.h @@ -1,124 +1,124 @@ -/* - * Copyright (c) 2021, Andreas Kling - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include -#include -#include "./AK/Optional.h" -#include "./AK/StringView.h" -#include "./AK/Try.h" -#include "./AK/Variant.h" - -namespace AK { - -class Error { -public: - static Error from_errno(int code) { return Error(code); } - static Error from_syscall(StringView syscall_name, int rc) { return Error(syscall_name, rc); } - static Error from_string_view(StringView string_literal) { return Error(string_literal); } - - bool is_errno() const { return m_code != 0; } - bool is_syscall() const { return m_syscall; } - - template - ALWAYS_INLINE static Error from_string_literal(char const (&string_literal)[N]); - - bool operator==(Error const& other) const - { - return m_code == other.m_code && m_string_literal == other.m_string_literal && m_syscall == other.m_syscall; - } - - int code() const { return m_code; } - StringView string_literal() const { return m_string_literal; } - -protected: - Error(int code) - : m_code(code) - { - } - -private: - Error(StringView string_literal) - : m_string_literal(string_literal) - { - } - - Error(StringView syscall_name, int rc) - : m_code(-rc) - , m_string_literal(syscall_name) - , m_syscall(true) - { - } - - int m_code{ 0 }; - StringView m_string_literal; - bool m_syscall{ false }; -}; - -template -class ErrorOr final : public Variant { -public: - using Variant::Variant; - - template - ALWAYS_INLINE ErrorOr(U&& value) requires(!IsSame, ErrorOr>) - : Variant(forward(value)) - { - } - - T& value() - { - return this->template get(); - } - T const& value() const { return this->template get(); } - ErrorType& error() { return this->template get(); } - ErrorType const& error() const { return this->template get(); } - - bool is_error() const { return this->template has(); } - - T release_value() { return move(value()); } - ErrorType release_error() { return move(error()); } - - T release_value_but_fixme_should_propagate_errors() - { - VERIFY(!is_error()); - return release_value(); - } - -private: - using Variant::downcast; -}; - -template -class ErrorOr { -public: - ErrorOr(ErrorType error) - : m_error(move(error)) - { - } - - ErrorOr() = default; - ErrorOr(ErrorOr&& other) = default; - ErrorOr(ErrorOr const& other) = default; - ~ErrorOr() = default; - - ErrorOr& operator=(ErrorOr&& other) = default; - ErrorOr& operator=(ErrorOr const& other) = default; - - ErrorType& error() { return m_error.value(); } - bool is_error() const { return m_error.has_value(); } - ErrorType release_error() { return m_error.release_value(); } - void release_value() { } - -private: - Optional m_error; -}; - -} - -using AK::Error; -using AK::ErrorOr; +/* + * Copyright (c) 2021, Andreas Kling + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include +#include "Optional.h" +#include "StringView.h" +#include "Try.h" +#include "Variant.h" + +namespace AK { + +class Error { +public: + static Error from_errno(int code) { return Error(code); } + static Error from_syscall(StringView syscall_name, int rc) { return Error(syscall_name, rc); } + static Error from_string_view(StringView string_literal) { return Error(string_literal); } + + bool is_errno() const { return m_code != 0; } + bool is_syscall() const { return m_syscall; } + + template + ALWAYS_INLINE static Error from_string_literal(char const (&string_literal)[N]); + + bool operator==(Error const& other) const + { + return m_code == other.m_code && m_string_literal == other.m_string_literal && m_syscall == other.m_syscall; + } + + int code() const { return m_code; } + StringView string_literal() const { return m_string_literal; } + +protected: + Error(int code) + : m_code(code) + { + } + +private: + Error(StringView string_literal) + : m_string_literal(string_literal) + { + } + + Error(StringView syscall_name, int rc) + : m_code(-rc) + , m_string_literal(syscall_name) + , m_syscall(true) + { + } + + int m_code{ 0 }; + StringView m_string_literal; + bool m_syscall{ false }; +}; + +template +class ErrorOr final : public Variant { +public: + using Variant::Variant; + + template + ALWAYS_INLINE ErrorOr(U&& value) requires(!IsSame, ErrorOr>) + : Variant(forward(value)) + { + } + + T& value() + { + return this->template get(); + } + T const& value() const { return this->template get(); } + ErrorType& error() { return this->template get(); } + ErrorType const& error() const { return this->template get(); } + + bool is_error() const { return this->template has(); } + + T release_value() { return move(value()); } + ErrorType release_error() { return move(error()); } + + T release_value_but_fixme_should_propagate_errors() + { + VERIFY(!is_error()); + return release_value(); + } + +private: + using Variant::downcast; +}; + +template +class ErrorOr { +public: + ErrorOr(ErrorType error) + : m_error(move(error)) + { + } + + ErrorOr() = default; + ErrorOr(ErrorOr&& other) = default; + ErrorOr(ErrorOr const& other) = default; + ~ErrorOr() = default; + + ErrorOr& operator=(ErrorOr&& other) = default; + ErrorOr& operator=(ErrorOr const& other) = default; + + ErrorType& error() { return m_error.value(); } + bool is_error() const { return m_error.has_value(); } + ErrorType release_error() { return m_error.release_value(); } + void release_value() { } + +private: + Optional m_error; +}; + +} + +using AK::Error; +using AK::ErrorOr; diff --git a/AK/AK/Find.h b/LibC-Shim/AK/Find.h similarity index 90% rename from AK/AK/Find.h rename to LibC-Shim/AK/Find.h index adb8699..4e1645e 100644 --- a/AK/AK/Find.h +++ b/LibC-Shim/AK/Find.h @@ -1,38 +1,38 @@ -/* - * Copyright (c) 2021, the SerenityOS developers. - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include "./AK/Concepts.h" -#include "./AK/Traits.h" -#include "./AK/Types.h" - -namespace AK { - -template TIterator, typename TUnaryPredicate> -constexpr TIterator find_if(TIterator first, TEndIterator last, TUnaryPredicate&& pred) -{ - for (; first != last; ++first) { - if (pred(*first)) { - return first; - } - } - return last; -} - -template TIterator, typename T> -constexpr TIterator find(TIterator first, TEndIterator last, T const& value) -{ - return find_if(first, last, [&](auto const& v) { return Traits::equals(value, v); }); -} - -template TIterator, typename T> -constexpr size_t find_index(TIterator first, TEndIterator last, T const& value) requires(requires(TIterator it) { it.index(); }) -{ - return find_if(first, last, [&](auto const& v) { return Traits::equals(value, v); }).index(); -} - -} +/* + * Copyright (c) 2021, the SerenityOS developers. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include "Concepts.h" +#include "Traits.h" +#include "Types.h" + +namespace AK { + +template TIterator, typename TUnaryPredicate> +constexpr TIterator find_if(TIterator first, TEndIterator last, TUnaryPredicate&& pred) +{ + for (; first != last; ++first) { + if (pred(*first)) { + return first; + } + } + return last; +} + +template TIterator, typename T> +constexpr TIterator find(TIterator first, TEndIterator last, T const& value) +{ + return find_if(first, last, [&](auto const& v) { return Traits::equals(value, v); }); +} + +template TIterator, typename T> +constexpr size_t find_index(TIterator first, TEndIterator last, T const& value) requires(requires(TIterator it) { it.index(); }) +{ + return find_if(first, last, [&](auto const& v) { return Traits::equals(value, v); }).index(); +} + +} diff --git a/AK/pthread.h b/LibC-Shim/AK/FixedPoint.h similarity index 100% rename from AK/pthread.h rename to LibC-Shim/AK/FixedPoint.h diff --git a/AK/AK/FlyString.cpp b/LibC-Shim/AK/FlyString.cpp similarity index 92% rename from AK/AK/FlyString.cpp rename to LibC-Shim/AK/FlyString.cpp index 822011d..47aaf80 100644 --- a/AK/AK/FlyString.cpp +++ b/LibC-Shim/AK/FlyString.cpp @@ -1,6 +1,6 @@ -#include "pch.h" -#include "FlyString.h" - -namespace AK { - +#include "pch.h" +#include "FlyString.h" + +namespace AK { + } \ No newline at end of file diff --git a/AK/AK/FlyString.h b/LibC-Shim/AK/FlyString.h similarity index 93% rename from AK/AK/FlyString.h rename to LibC-Shim/AK/FlyString.h index a9fe2e9..e70c2d6 100644 --- a/AK/AK/FlyString.h +++ b/LibC-Shim/AK/FlyString.h @@ -1,74 +1,74 @@ -#pragma once - -#include "./AK/String.h" -#include "./AK/StringUtils.h" - -namespace AK { - -class FlyString { -public: - FlyString() = default; - FlyString(FlyString const& other) - : m_impl(other.impl()) - { - } - FlyString(FlyString&& other) - : m_impl(move(other.m_impl)) - { - } - FlyString(String const&); - FlyString(StringView); - FlyString(char const* string) - : FlyString(static_cast(string)) - { - } - - static FlyString from_fly_impl(NonnullRefPtr impl); - - FlyString& operator=(FlyString&& other); - FlyString& operator=(FlyString const& other); - - bool is_empty() const { return true; } - bool is_null() const { return true; } - - bool operator==(FlyString const& other) const { return m_impl == other.m_impl; } - bool operator!=(FlyString const& other) const { return m_impl != other.m_impl; } - - bool operator==(String const&) const; - bool operator!=(String const& string) const { return !(*this == string); } - - bool operator==(StringView) const; - bool operator!=(StringView string) const { return !(*this == string); } - - bool operator==(char const*) const; - bool operator!=(char const* string) const { return !(*this == string); } - - StringImpl const* impl() const { return m_impl; } - char const* characters() const { return nullptr; } - size_t length() const { return 0; } - - ALWAYS_INLINE u32 hash() const { return 0; } - ALWAYS_INLINE StringView view() const; - - FlyString to_lowercase() const; - - template - Optional to_int(TrimWhitespace = TrimWhitespace::Yes) const; - template - Optional to_uint(TrimWhitespace = TrimWhitespace::Yes) const; - - template - ALWAYS_INLINE constexpr bool is_one_of(Ts... strings) const; - -private: - RefPtr m_impl; -}; - -template<> -struct Traits : public GenericTraits { - static unsigned hash(FlyString const& s) { return s.hash(); } -}; - -} - -using AK::FlyString; +#pragma once + +#include "String.h" +#include "StringUtils.h" + +namespace AK { + +class FlyString { +public: + FlyString() = default; + FlyString(FlyString const& other) + : m_impl(other.impl()) + { + } + FlyString(FlyString&& other) + : m_impl(move(other.m_impl)) + { + } + FlyString(String const&); + FlyString(StringView); + FlyString(char const* string) + : FlyString(static_cast(string)) + { + } + + static FlyString from_fly_impl(NonnullRefPtr impl); + + FlyString& operator=(FlyString&& other); + FlyString& operator=(FlyString const& other); + + bool is_empty() const { return true; } + bool is_null() const { return true; } + + bool operator==(FlyString const& other) const { return m_impl == other.m_impl; } + bool operator!=(FlyString const& other) const { return m_impl != other.m_impl; } + + bool operator==(String const&) const; + bool operator!=(String const& string) const { return !(*this == string); } + + bool operator==(StringView) const; + bool operator!=(StringView string) const { return !(*this == string); } + + bool operator==(char const*) const; + bool operator!=(char const* string) const { return !(*this == string); } + + StringImpl const* impl() const { return m_impl; } + char const* characters() const { return nullptr; } + size_t length() const { return 0; } + + ALWAYS_INLINE u32 hash() const { return 0; } + ALWAYS_INLINE StringView view() const; + + FlyString to_lowercase() const; + + template + Optional to_int(TrimWhitespace = TrimWhitespace::Yes) const; + template + Optional to_uint(TrimWhitespace = TrimWhitespace::Yes) const; + + template + ALWAYS_INLINE constexpr bool is_one_of(Ts... strings) const; + +private: + RefPtr m_impl; +}; + +template<> +struct Traits : public GenericTraits { + static unsigned hash(FlyString const& s) { return s.hash(); } +}; + +} + +using AK::FlyString; diff --git a/LibC-Shim/AK/Format.cpp b/LibC-Shim/AK/Format.cpp new file mode 100644 index 0000000..ce3b0e5 --- /dev/null +++ b/LibC-Shim/AK/Format.cpp @@ -0,0 +1,2 @@ +#include "pch.h" +#include "Format.h" diff --git a/AK/AK/Format.h b/LibC-Shim/AK/Format.h similarity index 91% rename from AK/AK/Format.h rename to LibC-Shim/AK/Format.h index 3f90d10..ffd8903 100644 --- a/AK/AK/Format.h +++ b/LibC-Shim/AK/Format.h @@ -1,581 +1,643 @@ -#pragma once -#ifndef _CRT_SECURE_NO_WARNINGS -#define _CRT_SECURE_NO_WARNINGS -#endif - -#include -#include -#include "./AK/CheckedFormatString.h" -#include "./AK/AllOf.h" -#include "./AK/AnyOf.h" -#include "./AK/Array.h" -#include "./AK/Error.h" -#include "./AK/FixedPoint.h" -#include "./AK/Forward.h" -#include "./AK/Optional.h" -#include "./AK/StringView.h" -// FIXME: this shouldn't be here -#include "./AK/Math.h" - -namespace AK { - -class TypeErasedFormatParams; -class FormatParser; -class FormatBuilder; - -template -struct Formatter { - using __no_formatter_defined = void; -}; - -template -inline constexpr bool HasFormatter = true; - -template -inline constexpr bool HasFormatter::__no_formatter_defined> = false; - -constexpr size_t max_format_arguments = 256; - -struct TypeErasedParameter { - enum class Type { - UInt8, - UInt16, - UInt32, - UInt64, - Int8, - Int16, - Int32, - Int64, - Custom - }; - - template - static consteval Type get_type_from_size() - { - if constexpr (is_unsigned) { - if constexpr (size == 1) - return Type::UInt8; - if constexpr (size == 2) - return Type::UInt16; - if constexpr (size == 4) - return Type::UInt32; - if constexpr (size == 8) - return Type::UInt64; - } - else { - if constexpr (size == 1) - return Type::Int8; - if constexpr (size == 2) - return Type::Int16; - if constexpr (size == 4) - return Type::Int32; - if constexpr (size == 8) - return Type::Int64; - } - - VERIFY_NOT_REACHED(); - } - - template - static consteval Type get_type() - { - if constexpr (IsIntegral) - return get_type_from_size>(); - else - return Type::Custom; - } - - template - constexpr auto visit(Visitor&& visitor) const - { - switch (type) { - case TypeErasedParameter::Type::UInt8: - return visitor(*static_cast(value)); - case TypeErasedParameter::Type::UInt16: - return visitor(*static_cast(value)); - case TypeErasedParameter::Type::UInt32: - return visitor(*static_cast(value)); - case TypeErasedParameter::Type::UInt64: - return visitor(*static_cast(value)); - case TypeErasedParameter::Type::Int8: - return visitor(*static_cast(value)); - case TypeErasedParameter::Type::Int16: - return visitor(*static_cast(value)); - case TypeErasedParameter::Type::Int32: - return visitor(*static_cast(value)); - case TypeErasedParameter::Type::Int64: - return visitor(*static_cast(value)); - default: - TODO(); - } - } - - constexpr size_t to_size() const - { - return visit([](T value) { - if constexpr (sizeof(T) > sizeof(size_t)) - VERIFY(value < NumericLimits::max()); - if constexpr (IsSigned) - VERIFY(value > 0); - return static_cast(value); - }); - } - - // FIXME: Getters and setters. - - void const* value; - Type type; - ErrorOr(*formatter)(TypeErasedFormatParams&, FormatBuilder&, FormatParser&, void const* value); -}; - -class FormatBuilder { -public: - enum class Align { - Default, - Left, - Center, - Right, - }; - enum class SignMode { - OnlyIfNeeded, - Always, - Reserved, - Default = OnlyIfNeeded, - }; - - explicit FormatBuilder(StringBuilder& builder) - : m_builder(builder) - { - } - - ErrorOr put_padding(char fill, size_t amount); - - ErrorOr put_literal(StringView value); - - ErrorOr put_string( - StringView value, - Align align = Align::Left, - size_t min_width = 0, - size_t max_width = NumericLimits::max(), - char fill = ' '); - - ErrorOr put_u64( - u64 value, - u8 base = 10, - bool prefix = false, - bool upper_case = false, - bool zero_pad = false, - Align align = Align::Right, - size_t min_width = 0, - char fill = ' ', - SignMode sign_mode = SignMode::OnlyIfNeeded, - bool is_negative = false); - - ErrorOr put_i64( - i64 value, - u8 base = 10, - bool prefix = false, - bool upper_case = false, - bool zero_pad = false, - Align align = Align::Right, - size_t min_width = 0, - char fill = ' ', - SignMode sign_mode = SignMode::OnlyIfNeeded); - - ErrorOr put_fixed_point( - i64 integer_value, - u64 fraction_value, - u64 fraction_one, - u8 base = 10, - bool upper_case = false, - bool zero_pad = false, - Align align = Align::Right, - size_t min_width = 0, - size_t precision = 6, - char fill = ' ', - SignMode sign_mode = SignMode::OnlyIfNeeded); - - ErrorOr put_f80( - long double value, - u8 base = 10, - bool upper_case = false, - Align align = Align::Right, - size_t min_width = 0, - size_t precision = 6, - char fill = ' ', - SignMode sign_mode = SignMode::OnlyIfNeeded); - - ErrorOr put_f64( - double value, - u8 base = 10, - bool upper_case = false, - bool zero_pad = false, - Align align = Align::Right, - size_t min_width = 0, - size_t precision = 6, - char fill = ' ', - SignMode sign_mode = SignMode::OnlyIfNeeded); - - ErrorOr put_hexdump( - ReadonlyBytes, - size_t width, - char fill = ' '); - - StringBuilder const& builder() const - { - return m_builder; - } - StringBuilder& builder() { return m_builder; } - -private: - StringBuilder& m_builder; -}; - -class TypeErasedFormatParams { -public: - Span parameters() const { return m_parameters; } - - void set_parameters(Span parameters) { m_parameters = parameters; } - size_t take_next_index() { return m_next_index++; } - -private: - Span m_parameters; - size_t m_next_index{ 0 }; -}; - -template -ErrorOr __format_value(TypeErasedFormatParams& params, FormatBuilder& builder, FormatParser& parser, void const* value) -{ - Formatter formatter; - - formatter.parse(params, parser); - return formatter.format(builder, *static_cast(value)); -} - -template -class VariadicFormatParams : public TypeErasedFormatParams { -public: - static_assert(sizeof...(Parameters) <= max_format_arguments); - - explicit VariadicFormatParams(Parameters const&... parameters) - //: m_data({ TypeErasedParameter {¶meters, TypeErasedParameter::get_type(), __format_value}...}) - { - //this->set_parameters(m_data); - } - -private: - //Array m_data; -}; - -// We use the same format for most types for consistency. This is taken directly from -// std::format. One difference is that we are not counting the width or sign towards the -// total width when calculating zero padding for numbers. -// https://en.cppreference.com/w/cpp/utility/format/formatter#Standard_format_specification -struct StandardFormatter { - enum class Mode { - Default, - Binary, - BinaryUppercase, - Decimal, - Octal, - Hexadecimal, - HexadecimalUppercase, - Character, - String, - Pointer, - Float, - Hexfloat, - HexfloatUppercase, - HexDump, - }; - - FormatBuilder::Align m_align = FormatBuilder::Align::Default; - FormatBuilder::SignMode m_sign_mode = FormatBuilder::SignMode::OnlyIfNeeded; - Mode m_mode = Mode::Default; - bool m_alternative_form = false; - char m_fill = ' '; - bool m_zero_pad = false; - Optional m_width; - Optional m_precision; - - void parse(TypeErasedFormatParams&, FormatParser&); -}; - -template -struct Formatter : StandardFormatter { - Formatter() = default; - explicit Formatter(StandardFormatter formatter) - : StandardFormatter(move(formatter)) - { - } - - ErrorOr format(FormatBuilder&, T); -}; - -template<> -struct Formatter : StandardFormatter { - Formatter() = default; - explicit Formatter(StandardFormatter formatter) - : StandardFormatter(move(formatter)) - { - } - - ErrorOr format(FormatBuilder&, StringView); -}; - -template - requires(HasFormatter) struct Formatter> : StandardFormatter { - - Formatter() = default; - explicit Formatter(StandardFormatter formatter) - : StandardFormatter(move(formatter)) - { - } - ErrorOr format(FormatBuilder& builder, Vector value); -}; - -template<> -struct Formatter : Formatter { - ErrorOr format(FormatBuilder& builder, ReadonlyBytes value) - { - if (m_mode == Mode::Pointer) { - Formatter formatter{ *this }; - return formatter.format(builder, reinterpret_cast(value.data())); - } - if (m_mode == Mode::Default || m_mode == Mode::HexDump) { - m_mode = Mode::HexDump; - return Formatter::format(builder, value); - } - return Formatter::format(builder, value); - } -}; - -template<> -struct Formatter : Formatter { -}; - -// FIXME: Printing raw char pointers is inherently dangerous. Remove this and -// its users and prefer StringView over it. -template<> -struct Formatter : Formatter { - ErrorOr format(FormatBuilder& builder, char const* value) - { - if (m_mode == Mode::Pointer) { - Formatter formatter{ *this }; - return formatter.format(builder, reinterpret_cast(value)); - } - - return Formatter::format(builder, value != nullptr ? StringView{ value, __builtin_strlen(value) } : "(null)"sv); - } -}; -template<> -struct Formatter : Formatter { -}; -template -struct Formatter : Formatter { -}; -template -struct Formatter : Formatter { - ErrorOr format(FormatBuilder& builder, unsigned char const* value) - { - if (m_mode == Mode::Pointer) { - Formatter formatter{ *this }; - return formatter.format(builder, reinterpret_cast(value)); - } - return Formatter::format(builder, { value, Size }); - } -}; -template<> -struct Formatter : Formatter { -}; -template<> -struct Formatter : Formatter { -}; - -template -struct Formatter : StandardFormatter { - ErrorOr format(FormatBuilder& builder, T* value) - { - if (m_mode == Mode::Default) - m_mode = Mode::Pointer; - - Formatter formatter{ *this }; - return formatter.format(builder, reinterpret_cast(value)); - } -}; - -template<> -struct Formatter : StandardFormatter { - ErrorOr format(FormatBuilder&, char); -}; -template<> -struct Formatter : StandardFormatter { - ErrorOr format(FormatBuilder& builder, wchar_t); -}; -template<> -struct Formatter : StandardFormatter { - ErrorOr format(FormatBuilder&, bool); -}; - -template<> -struct Formatter : StandardFormatter { - ErrorOr format(FormatBuilder&, float value); -}; -template<> -struct Formatter : StandardFormatter { - Formatter() = default; - explicit Formatter(StandardFormatter formatter) - : StandardFormatter(formatter) - { - } - - ErrorOr format(FormatBuilder&, double); -}; - -template<> -struct Formatter : StandardFormatter { - Formatter() = default; - explicit Formatter(StandardFormatter formatter) - : StandardFormatter(formatter) - { - } - - ErrorOr format(FormatBuilder&, long double value); -}; - -template -struct Formatter> : StandardFormatter { - Formatter() = default; - explicit Formatter(StandardFormatter formatter) - : StandardFormatter(formatter) - { - } - - ErrorOr format(FormatBuilder& builder, FixedPoint value); -}; - -template<> -struct Formatter : Formatter { - ErrorOr format(FormatBuilder& builder, std::nullptr_t) - { - if (m_mode == Mode::Default) - m_mode = Mode::Pointer; - - return Formatter::format(builder, 0); - } -}; - -ErrorOr vformat(StringBuilder&, StringView fmtstr, TypeErasedFormatParams&); - -void vout(FILE*, StringView fmtstr, TypeErasedFormatParams&, bool newline = false); - -template -void out(FILE* file, CheckedFormatString&& fmtstr, Parameters const&... parameters); - -template -void outln(FILE* file, CheckedFormatString&& fmtstr, Parameters const&... parameters); - -ALWAYS_INLINE void outln(FILE* file) { fputc('\n', file); } - -template -void out(CheckedFormatString&& fmtstr, Parameters const&... parameters); - -template -void outln(CheckedFormatString&& fmtstr, Parameters const&... parameters); - -ALWAYS_INLINE void outln() { outln(stdout); } - -#define outln_if(flag, fmt, ...) \ - do { \ - if constexpr (flag) \ - outln(fmt, ##__VA_ARGS__); \ - } while (0) - -template -void warn(CheckedFormatString&& fmtstr, Parameters const&... parameters); - -template -void warnln(CheckedFormatString&& fmtstr, Parameters const&... parameters); - -ALWAYS_INLINE void warnln() { outln(stderr); } - -#define warnln_if(flag, fmt, ...) \ - do { \ - if constexpr (flag) \ - warnln(fmt, ##__VA_ARGS__); \ - } while (0) - -void vdbgln(StringView fmtstr, TypeErasedFormatParams&); - -template -void dbgln(CheckedFormatString&& fmtstr, Parameters const&... parameters); - -//ALWAYS_INLINE void dbgln() { dbgln(""); } - -void set_debug_enabled(bool); - -template -class FormatIfSupported { -public: - explicit FormatIfSupported(const T& value) - : m_value(value) - { - } - - const T& value() const { return m_value; } - -private: - const T& m_value; -}; -template -struct __FormatIfSupported : Formatter { - ErrorOr format(FormatBuilder& builder, FormatIfSupported const&); -}; -template -struct __FormatIfSupported : Formatter { - ErrorOr format(FormatBuilder& builder, FormatIfSupported const& value); -}; -template -struct Formatter> : __FormatIfSupported> { -}; - -// This is a helper class, the idea is that if you want to implement a formatter you can inherit -// from this class to "break down" the formatting. -struct FormatString { -}; -template<> -struct Formatter : Formatter { - template - ErrorOr format(FormatBuilder& builder, StringView fmtstr, Parameters const&... parameters); - ErrorOr vformat(FormatBuilder& builder, StringView fmtstr, TypeErasedFormatParams& params); -}; - -template<> -struct Formatter : Formatter { - ErrorOr format(FormatBuilder& builder, Error const& error); -}; - -template -struct Formatter> : Formatter { - ErrorOr format(FormatBuilder& builder, ErrorOr const& error_or); -}; - -} // namespace AK - -using AK::out; -using AK::outln; - -using AK::warn; -using AK::warnln; - -using AK::dbgln; - -using AK::CheckedFormatString; -using AK::FormatIfSupported; -using AK::FormatString; - -#define dbgln_if(flag, fmt, ...) \ - do { \ - if constexpr (flag) \ - dbgln(fmt, ##__VA_ARGS__); \ - } while (0) +#pragma once +#ifndef _CRT_SECURE_NO_WARNINGS +#define _CRT_SECURE_NO_WARNINGS +#endif + +#include +#include +#include "CheckedFormatString.h" +#include "AllOf.h" +#include "AnyOf.h" +#include "Array.h" +#include "Error.h" +#include "FixedPoint.h" +#include "Forward.h" +#include "Optional.h" +#include "StringView.h" +// FIXME: this shouldn't be here +#include "Math.h" + +namespace AK { + +class TypeErasedFormatParams; +class FormatParser; +class FormatBuilder; + +template +struct Formatter { + using __no_formatter_defined = void; +}; + +template +inline constexpr bool HasFormatter = true; + +template +inline constexpr bool HasFormatter::__no_formatter_defined> = false; + +constexpr size_t max_format_arguments = 256; + +struct TypeErasedParameter { + enum class Type { + UInt8, + UInt16, + UInt32, + UInt64, + Int8, + Int16, + Int32, + Int64, + Custom + }; + + template + static consteval Type get_type_from_size() + { + if constexpr (is_unsigned) { + if constexpr (size == 1) + return Type::UInt8; + if constexpr (size == 2) + return Type::UInt16; + if constexpr (size == 4) + return Type::UInt32; + if constexpr (size == 8) + return Type::UInt64; + } + else { + if constexpr (size == 1) + return Type::Int8; + if constexpr (size == 2) + return Type::Int16; + if constexpr (size == 4) + return Type::Int32; + if constexpr (size == 8) + return Type::Int64; + } + + VERIFY_NOT_REACHED(); + } + + template + static consteval Type get_type() + { + if constexpr (IsIntegral) + return get_type_from_size>(); + else + return Type::Custom; + } + + template + constexpr auto visit(Visitor&& visitor) const + { + switch (type) { + case TypeErasedParameter::Type::UInt8: + return visitor(*static_cast(value)); + case TypeErasedParameter::Type::UInt16: + return visitor(*static_cast(value)); + case TypeErasedParameter::Type::UInt32: + return visitor(*static_cast(value)); + case TypeErasedParameter::Type::UInt64: + return visitor(*static_cast(value)); + case TypeErasedParameter::Type::Int8: + return visitor(*static_cast(value)); + case TypeErasedParameter::Type::Int16: + return visitor(*static_cast(value)); + case TypeErasedParameter::Type::Int32: + return visitor(*static_cast(value)); + case TypeErasedParameter::Type::Int64: + return visitor(*static_cast(value)); + default: + TODO(); + } + } + + constexpr size_t to_size() const + { + return visit([](T value) { + if constexpr (sizeof(T) > sizeof(size_t)) + VERIFY(value < NumericLimits::max()); + if constexpr (IsSigned) + VERIFY(value > 0); + return static_cast(value); + }); + } + + // FIXME: Getters and setters. + + void const* value; + Type type; + ErrorOr(*formatter)(TypeErasedFormatParams&, FormatBuilder&, FormatParser&, void const* value); +}; + +class FormatBuilder { +public: + enum class Align { + Default, + Left, + Center, + Right, + }; + enum class SignMode { + OnlyIfNeeded, + Always, + Reserved, + Default = OnlyIfNeeded, + }; + + explicit FormatBuilder(StringBuilder& builder) + : m_builder(builder) + { + } + + ErrorOr put_padding(char fill, size_t amount); + + ErrorOr put_literal(StringView value); + + ErrorOr put_string( + StringView value, + Align align = Align::Left, + size_t min_width = 0, + size_t max_width = NumericLimits::max(), + char fill = ' '); + + ErrorOr put_u64( + u64 value, + u8 base = 10, + bool prefix = false, + bool upper_case = false, + bool zero_pad = false, + Align align = Align::Right, + size_t min_width = 0, + char fill = ' ', + SignMode sign_mode = SignMode::OnlyIfNeeded, + bool is_negative = false); + + ErrorOr put_i64( + i64 value, + u8 base = 10, + bool prefix = false, + bool upper_case = false, + bool zero_pad = false, + Align align = Align::Right, + size_t min_width = 0, + char fill = ' ', + SignMode sign_mode = SignMode::OnlyIfNeeded); + + ErrorOr put_fixed_point( + i64 integer_value, + u64 fraction_value, + u64 fraction_one, + u8 base = 10, + bool upper_case = false, + bool zero_pad = false, + Align align = Align::Right, + size_t min_width = 0, + size_t precision = 6, + char fill = ' ', + SignMode sign_mode = SignMode::OnlyIfNeeded); + + ErrorOr put_f80( + long double value, + u8 base = 10, + bool upper_case = false, + Align align = Align::Right, + size_t min_width = 0, + size_t precision = 6, + char fill = ' ', + SignMode sign_mode = SignMode::OnlyIfNeeded); + + ErrorOr put_f64( + double value, + u8 base = 10, + bool upper_case = false, + bool zero_pad = false, + Align align = Align::Right, + size_t min_width = 0, + size_t precision = 6, + char fill = ' ', + SignMode sign_mode = SignMode::OnlyIfNeeded); + + ErrorOr put_hexdump( + ReadonlyBytes, + size_t width, + char fill = ' '); + + StringBuilder const& builder() const + { + return m_builder; + } + StringBuilder& builder() { return m_builder; } + +private: + StringBuilder& m_builder; +}; + +class TypeErasedFormatParams { +public: + Span parameters() const { return m_parameters; } + + void set_parameters(Span parameters) { m_parameters = parameters; } + size_t take_next_index() { return m_next_index++; } + +private: + Span m_parameters; + size_t m_next_index{ 0 }; +}; + +template +ErrorOr __format_value(TypeErasedFormatParams& params, FormatBuilder& builder, FormatParser& parser, void const* value) +{ + Formatter formatter; + + formatter.parse(params, parser); + return formatter.format(builder, *static_cast(value)); +} + +template +class VariadicFormatParams : public TypeErasedFormatParams { +public: + static_assert(sizeof...(Parameters) <= max_format_arguments); + + explicit VariadicFormatParams(Parameters const&... parameters) + //: m_data({ TypeErasedParameter {¶meters, TypeErasedParameter::get_type(), __format_value}...}) + { + //this->set_parameters(m_data); + } + +private: + //Array m_data; +}; + +// We use the same format for most types for consistency. This is taken directly from +// std::format. One difference is that we are not counting the width or sign towards the +// total width when calculating zero padding for numbers. +// https://en.cppreference.com/w/cpp/utility/format/formatter#Standard_format_specification +struct StandardFormatter { + enum class Mode { + Default, + Binary, + BinaryUppercase, + Decimal, + Octal, + Hexadecimal, + HexadecimalUppercase, + Character, + String, + Pointer, + Float, + Hexfloat, + HexfloatUppercase, + HexDump, + }; + + FormatBuilder::Align m_align = FormatBuilder::Align::Default; + FormatBuilder::SignMode m_sign_mode = FormatBuilder::SignMode::OnlyIfNeeded; + Mode m_mode = Mode::Default; + bool m_alternative_form = false; + char m_fill = ' '; + bool m_zero_pad = false; + Optional m_width; + Optional m_precision; + + void parse(TypeErasedFormatParams&, FormatParser&); +}; + +template +struct Formatter : StandardFormatter { + Formatter() = default; + explicit Formatter(StandardFormatter formatter) + : StandardFormatter(move(formatter)) + { + } + + ErrorOr format(FormatBuilder&, T); +}; + +template<> +struct Formatter : StandardFormatter { + Formatter() = default; + explicit Formatter(StandardFormatter formatter) + : StandardFormatter(move(formatter)) + { + } + + ErrorOr format(FormatBuilder&, StringView); +}; + +template + requires(HasFormatter) struct Formatter> : StandardFormatter { + + Formatter() = default; + explicit Formatter(StandardFormatter formatter) + : StandardFormatter(move(formatter)) + { + } + ErrorOr format(FormatBuilder& builder, Vector value); +}; + +template<> +struct Formatter : Formatter { + ErrorOr format(FormatBuilder& builder, ReadonlyBytes value) + { + if (m_mode == Mode::Pointer) { + Formatter formatter{ *this }; + return formatter.format(builder, reinterpret_cast(value.data())); + } + if (m_mode == Mode::Default || m_mode == Mode::HexDump) { + m_mode = Mode::HexDump; + return Formatter::format(builder, value); + } + return Formatter::format(builder, value); + } +}; + +template<> +struct Formatter : Formatter { +}; + +// FIXME: Printing raw char pointers is inherently dangerous. Remove this and +// its users and prefer StringView over it. +template<> +struct Formatter : Formatter { + ErrorOr format(FormatBuilder& builder, char const* value) + { + if (m_mode == Mode::Pointer) { + Formatter formatter{ *this }; + return formatter.format(builder, reinterpret_cast(value)); + } + + return Formatter::format(builder, value != nullptr ? StringView{ value, __builtin_strlen(value) } : "(null)"sv); + } +}; +template<> +struct Formatter : Formatter { +}; +template +struct Formatter : Formatter { +}; +template +struct Formatter : Formatter { + ErrorOr format(FormatBuilder& builder, unsigned char const* value) + { + if (m_mode == Mode::Pointer) { + Formatter formatter{ *this }; + return formatter.format(builder, reinterpret_cast(value)); + } + return Formatter::format(builder, { value, Size }); + } +}; +template<> +struct Formatter : Formatter { +}; +template<> +struct Formatter : Formatter { +}; + +template +struct Formatter : StandardFormatter { + ErrorOr format(FormatBuilder& builder, T* value) + { + if (m_mode == Mode::Default) + m_mode = Mode::Pointer; + + Formatter formatter{ *this }; + return formatter.format(builder, reinterpret_cast(value)); + } +}; + +template<> +struct Formatter : StandardFormatter { + ErrorOr format(FormatBuilder&, char); +}; +template<> +struct Formatter : StandardFormatter { + ErrorOr format(FormatBuilder& builder, wchar_t); +}; +template<> +struct Formatter : StandardFormatter { + ErrorOr format(FormatBuilder&, bool); +}; + +template<> +struct Formatter : StandardFormatter { + ErrorOr format(FormatBuilder&, float value); +}; +template<> +struct Formatter : StandardFormatter { + Formatter() = default; + explicit Formatter(StandardFormatter formatter) + : StandardFormatter(formatter) + { + } + + ErrorOr format(FormatBuilder&, double); +}; + +template<> +struct Formatter : StandardFormatter { + Formatter() = default; + explicit Formatter(StandardFormatter formatter) + : StandardFormatter(formatter) + { + } + + ErrorOr format(FormatBuilder&, long double value); +}; + +template +struct Formatter> : StandardFormatter { + Formatter() = default; + explicit Formatter(StandardFormatter formatter) + : StandardFormatter(formatter) + { + } + + ErrorOr format(FormatBuilder& builder, FixedPoint value); +}; + +template<> +struct Formatter : Formatter { + ErrorOr format(FormatBuilder& builder, std::nullptr_t) + { + if (m_mode == Mode::Default) + m_mode = Mode::Pointer; + + return Formatter::format(builder, 0); + } +}; + +ErrorOr vformat(StringBuilder&, StringView fmtstr, TypeErasedFormatParams&); + +void vout(FILE*, StringView fmtstr, TypeErasedFormatParams&, bool newline = false) +{ + // FIXME: Impl this. + VERIFY_NOT_REACHED(); +} + +template +void out(FILE* file, CheckedFormatString&& fmtstr, Parameters const&... parameters) +{ + // FIXME: Impl this. + VERIFY_NOT_REACHED(); +} + +template +void outln(FILE* file, CheckedFormatString&& fmtstr, Parameters const&... parameters) +{ + // FIXME: Impl this. + VERIFY_NOT_REACHED(); +} + +ALWAYS_INLINE void outln(FILE* file) { fputc('\n', file); } + +template +void out(CheckedFormatString&& fmtstr, Parameters const&... parameters) +{ + // FIXME: Impl this. + VERIFY_NOT_REACHED(); +} + +template +void outln(CheckedFormatString&& fmtstr, Parameters const&... parameters) +{ + // FIXME: Impl this. + VERIFY_NOT_REACHED(); +} + +ALWAYS_INLINE void outln() { outln(stdout); } + +#define outln_if(flag, fmt, ...) \ + do { \ + if constexpr (flag) \ + outln(fmt, ##__VA_ARGS__); \ + } while (0) + +template +void warn(CheckedFormatString&& fmtstr, Parameters const&... parameters) +{ + // FIXME: Impl this. + VERIFY_NOT_REACHED(); +} + +template +void warnln(CheckedFormatString&& fmtstr, Parameters const&... parameters) +{ + // FIXME: Impl this. + VERIFY_NOT_REACHED(); +} + +ALWAYS_INLINE void warnln() { outln(stderr); } + +#define warnln_if(flag, fmt, ...) \ + do { \ + if constexpr (flag) \ + warnln(fmt, ##__VA_ARGS__); \ + } while (0) + +void vdbgln(StringView fmtstr, TypeErasedFormatParams&); + +template +void dbgln(CheckedFormatString&& fmtstr, Parameters const&... parameters) +{ + // FIXME: Impl this. + VERIFY_NOT_REACHED(); +} + +//ALWAYS_INLINE void dbgln() { dbgln(""); } + +void set_debug_enabled(bool); + +template +class FormatIfSupported { +public: + explicit FormatIfSupported(const T& value) + : m_value(value) + { + } + + const T& value() const { return m_value; } + +private: + const T& m_value; +}; +template +struct __FormatIfSupported : Formatter { + ErrorOr format(FormatBuilder& builder, FormatIfSupported const&) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return {}; + } +}; +template +struct __FormatIfSupported : Formatter { + ErrorOr format(FormatBuilder& builder, FormatIfSupported const& value) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return {}; + } +}; +template +struct Formatter> : __FormatIfSupported> { +}; + +// This is a helper class, the idea is that if you want to implement a formatter you can inherit +// from this class to "break down" the formatting. +struct FormatString { +}; +template<> +struct Formatter : Formatter { + template + ErrorOr format(FormatBuilder& builder, StringView fmtstr, Parameters const&... parameters) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return {}; + } + ErrorOr vformat(FormatBuilder& builder, StringView fmtstr, TypeErasedFormatParams& params) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return {}; + } +}; + +template<> +struct Formatter : Formatter { + ErrorOr format(FormatBuilder& builder, Error const& error) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return {}; + } +}; + +template +struct Formatter> : Formatter { + ErrorOr format(FormatBuilder& builder, ErrorOr const& error_or) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return {}; + } +}; + +} // namespace AK + +using AK::out; +using AK::outln; + +using AK::warn; +using AK::warnln; + +using AK::dbgln; + +using AK::CheckedFormatString; +using AK::FormatIfSupported; +using AK::FormatString; + +#define dbgln_if(flag, fmt, ...) \ + do { \ + if constexpr (flag) \ + dbgln(fmt, ##__VA_ARGS__); \ + } while (0) diff --git a/AK/AK/Forward.h b/LibC-Shim/AK/Forward.h similarity index 92% rename from AK/AK/Forward.h rename to LibC-Shim/AK/Forward.h index fbcbddd..b419fd2 100644 --- a/AK/AK/Forward.h +++ b/LibC-Shim/AK/Forward.h @@ -1,190 +1,190 @@ -/* - * Copyright (c) 2020, Andreas Kling - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include -#include "./AK/Types.h" -#include "./AK/NumericLimits.h" -#include "./AK/Platform.h" - -namespace AK { - -namespace Detail { - -template -class ByteBuffer; - -} - -class Bitmap; -using ByteBuffer = AK::Detail::ByteBuffer<32>; -class Error; -class GenericLexer; -class IPv4Address; -class JsonArray; -class JsonObject; -class JsonValue; -class StackInfo; -class String; -class StringBuilder; -class StringImpl; -class StringView; -class Time; -class URL; -class FlyString; -class Utf16View; -class Utf32View; -class Utf8CodePointIterator; -class Utf8View; -class InputStream; -class InputMemoryStream; -class DuplexMemoryStream; -class OutputStream; -class InputBitStream; -class OutputBitStream; -class OutputMemoryStream; - -template -class CircularDuplexStream; - -template -class Span; - -template -struct Array; - -template -class SimpleIterator; - -using ReadonlyBytes = Span; -using Bytes = Span; - -//template -//class Atomic; - -template -class SinglyLinkedList; - -template -class DoublyLinkedList; - -template -class CircularQueue; - -template -struct Traits; - -template, bool IsOrdered = false> -class HashTable; - -template> -using OrderedHashTable = HashTable; - -template, bool IsOrdered = false> -class HashMap; - -template> -using OrderedHashMap = HashMap; - -template -class Badge; - -template -class FixedArray; - -template -class FixedPoint; - -template -class Function; - -template -class Function; - -template -class NonnullRefPtr; - -template -class NonnullOwnPtr; - -template -class NonnullRefPtrVector; - -template -class NonnullOwnPtrVector; - -template -class Optional; - -template -class RefPtr; - -template -class OwnPtr; - -template -class WeakPtr; - -template -requires(!IsRvalueReference) class Vector; - -template -class ErrorOr; - -} - -using AK::Array; -//using AK::Atomic; -using AK::Badge; -using AK::Bitmap; -using AK::ByteBuffer; -using AK::Bytes; -using AK::CircularDuplexStream; -using AK::CircularQueue; -using AK::DoublyLinkedList; -using AK::DuplexMemoryStream; -using AK::Error; -using AK::ErrorOr; -using AK::FixedArray; -using AK::FixedPoint; -using AK::FlyString; -using AK::Function; -using AK::GenericLexer; -using AK::HashMap; -using AK::HashTable; -using AK::InputBitStream; -using AK::InputMemoryStream; -using AK::InputStream; -using AK::IPv4Address; -using AK::JsonArray; -using AK::JsonObject; -using AK::JsonValue; -using AK::NonnullOwnPtr; -using AK::NonnullOwnPtrVector; -using AK::NonnullRefPtr; -using AK::NonnullRefPtrVector; -using AK::Optional; -using AK::OutputBitStream; -using AK::OutputMemoryStream; -using AK::OutputStream; -using AK::OwnPtr; -using AK::ReadonlyBytes; -using AK::RefPtr; -using AK::SinglyLinkedList; -using AK::Span; -using AK::StackInfo; -using AK::String; -using AK::StringBuilder; -using AK::StringImpl; -using AK::StringView; -using AK::Time; -using AK::Traits; -using AK::URL; -using AK::Utf16View; -using AK::Utf32View; -using AK::Utf8CodePointIterator; -using AK::Utf8View; \ No newline at end of file +/* + * Copyright (c) 2020, Andreas Kling + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include "Types.h" +#include "NumericLimits.h" +#include "Platform.h" + +namespace AK { + +namespace Detail { + +template +class ByteBuffer; + +} + +class Bitmap; +using ByteBuffer = AK::Detail::ByteBuffer<32>; +class Error; +class GenericLexer; +class IPv4Address; +class JsonArray; +class JsonObject; +class JsonValue; +class StackInfo; +class String; +class StringBuilder; +class StringImpl; +class StringView; +class Time; +class URL; +class FlyString; +class Utf16View; +class Utf32View; +class Utf8CodePointIterator; +class Utf8View; +class InputStream; +class InputMemoryStream; +class DuplexMemoryStream; +class OutputStream; +class InputBitStream; +class OutputBitStream; +class OutputMemoryStream; + +template +class CircularDuplexStream; + +template +class Span; + +template +struct Array; + +template +class SimpleIterator; + +using ReadonlyBytes = Span; +using Bytes = Span; + +//template +//class Atomic; + +template +class SinglyLinkedList; + +template +class DoublyLinkedList; + +template +class CircularQueue; + +template +struct Traits; + +template, bool IsOrdered = false> +class HashTable; + +template> +using OrderedHashTable = HashTable; + +template, bool IsOrdered = false> +class HashMap; + +template> +using OrderedHashMap = HashMap; + +template +class Badge; + +template +class FixedArray; + +template +class FixedPoint; + +template +class Function; + +template +class Function; + +template +class NonnullRefPtr; + +template +class NonnullOwnPtr; + +template +class NonnullRefPtrVector; + +template +class NonnullOwnPtrVector; + +template +class Optional; + +template +class RefPtr; + +template +class OwnPtr; + +template +class WeakPtr; + +template +requires(!IsRvalueReference) class Vector; + +template +class ErrorOr; + +} + +using AK::Array; +//using AK::Atomic; +using AK::Badge; +using AK::Bitmap; +using AK::ByteBuffer; +using AK::Bytes; +using AK::CircularDuplexStream; +using AK::CircularQueue; +using AK::DoublyLinkedList; +using AK::DuplexMemoryStream; +using AK::Error; +using AK::ErrorOr; +using AK::FixedArray; +using AK::FixedPoint; +using AK::FlyString; +using AK::Function; +using AK::GenericLexer; +using AK::HashMap; +using AK::HashTable; +using AK::InputBitStream; +using AK::InputMemoryStream; +using AK::InputStream; +using AK::IPv4Address; +using AK::JsonArray; +using AK::JsonObject; +using AK::JsonValue; +using AK::NonnullOwnPtr; +using AK::NonnullOwnPtrVector; +using AK::NonnullRefPtr; +using AK::NonnullRefPtrVector; +using AK::Optional; +using AK::OutputBitStream; +using AK::OutputMemoryStream; +using AK::OutputStream; +using AK::OwnPtr; +using AK::ReadonlyBytes; +using AK::RefPtr; +using AK::SinglyLinkedList; +using AK::Span; +using AK::StackInfo; +using AK::String; +using AK::StringBuilder; +using AK::StringImpl; +using AK::StringView; +using AK::Time; +using AK::Traits; +using AK::URL; +using AK::Utf16View; +using AK::Utf32View; +using AK::Utf8CodePointIterator; +using AK::Utf8View; diff --git a/AK/AK/Function.h b/LibC-Shim/AK/Function.h similarity index 67% rename from AK/AK/Function.h rename to LibC-Shim/AK/Function.h index 71c39ca..c5ea205 100644 --- a/AK/AK/Function.h +++ b/LibC-Shim/AK/Function.h @@ -1,138 +1,191 @@ -/* - * Copyright (C) 2016 Apple Inc. All rights reserved. - * Copyright (c) 2021, Gunnar Beutner - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -#pragma once - -#include "./AK/Assertions.h" -#include "./AK/Atomic.h" -#include "./AK/BitCast.h" -#include "./AK/Noncopyable.h" -#include "./AK/ScopeGuard.h" -#include "./AK/StdLibExtras.h" -#include "./AK/Types.h" - -namespace AK { - -template -class Function; - -template -inline constexpr bool IsFunctionPointer = (IsPointer && IsFunction>); - -// Not a function pointer, and not an lvalue reference. -template -inline constexpr bool IsFunctionObject = (!IsFunctionPointer && IsRvalueReference); - -template -class Function { - AK_MAKE_NONCOPYABLE(Function); - -public: - Function() = default; - Function(std::nullptr_t) - { - } - - ~Function() = default; - - template - Function(CallableType&& callable) requires((IsFunctionObject&& IsCallableWithArguments && !IsSame, Function>)); - - template - Function(FunctionType f) requires((IsFunctionPointer&& IsCallableWithArguments, In...> && !IsSame, Function>)); - - Function(Function&& other); - - Out operator()(In... in) const; - - explicit operator bool() const; - - template - Function& operator=(CallableType&& callable) requires((IsFunctionObject&& IsCallableWithArguments)); - - template - Function& operator=(FunctionType f) requires((IsFunctionPointer&& IsCallableWithArguments, In...>)); - - Function& operator=(std::nullptr_t); - - Function& operator=(Function&& other); - -private: - class CallableWrapperBase { - public: - virtual ~CallableWrapperBase() = default; - // Note: This is not const to allow storing mutable lambdas. - virtual Out call(In...) = 0; - virtual void destroy() = 0; - virtual void init_and_swap(u8*, size_t) = 0; - }; - - template - class CallableWrapper final : public CallableWrapperBase { - AK_MAKE_NONMOVABLE(CallableWrapper); - AK_MAKE_NONCOPYABLE(CallableWrapper); - - public: - explicit CallableWrapper(CallableType&& callable) - : m_callable(move(callable)) - { - } - - Out call(In... in) final override; - - void destroy(); - - void init_and_swap(u8* destination, size_t size) final override; - - private: - CallableType m_callable; - }; - - enum class FunctionKind { - NullPointer, - Inline, - Outline, - }; - - CallableWrapperBase* callable_wrapper() const; - - void clear(bool may_defer = true); - - template - void init_with_callable(Callable&& callable); - - void move_from(Function&& other); - - FunctionKind m_kind{ FunctionKind::NullPointer }; - bool m_deferred_clear{ false }; - //mutable Atomic m_call_nesting_level{ 0 }; - static constexpr size_t inline_capacity = 4 * sizeof(void*); - //alignas(max(alignof(CallableWrapperBase), alignof(CallableWrapperBase*))) u8 m_storage[inline_capacity]; -}; - -} - -using AK::Function; +/* + * Copyright (C) 2016 Apple Inc. All rights reserved. + * Copyright (c) 2021, Gunnar Beutner + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include "Assertions.h" +#include "Atomic.h" +#include "BitCast.h" +#include "Noncopyable.h" +#include "ScopeGuard.h" +#include "StdLibExtras.h" +#include "Types.h" + +namespace AK { + +template +class Function; + +template +inline constexpr bool IsFunctionPointer = (IsPointer && IsFunction>); + +// Not a function pointer, and not an lvalue reference. +template +inline constexpr bool IsFunctionObject = (!IsFunctionPointer && IsRvalueReference); + +template +class Function { + AK_MAKE_NONCOPYABLE(Function); + +public: + Function() = default; + Function(std::nullptr_t) + { + } + + ~Function() = default; + + template + Function(CallableType&& callable) requires((IsFunctionObject&& IsCallableWithArguments && !IsSame, Function>)) + { + } + + template + Function(FunctionType f) requires((IsFunctionPointer&& IsCallableWithArguments, In...> && !IsSame, Function>)) + { + } + + Function(Function&& other); + + Out operator()(In... in) const + { + auto* wrapper = callable_wrapper(); + VERIFY(wrapper); + return wrapper->call(forward(in)...); + } + + explicit operator bool() const { return !!callable_wrapper(); } + + template + Function& operator=(CallableType&& callable) requires((IsFunctionObject && IsCallableWithArguments)) + { + clear(); + init_with_callable(forward(callable)); + return *this; + } + + template + Function& operator=(FunctionType f) requires((IsFunctionPointer && IsCallableWithArguments, In...>)) + { + clear(); + if (f) + init_with_callable(move(f)); + return *this; + } + + Function& operator=(std::nullptr_t) + { + clear(); + return *this; + } + + Function& operator=(Function&& other) + { + if (this != &other) { + clear(); + move_from(move(other)); + } + return *this; + } + +private: + class CallableWrapperBase { + public: + virtual ~CallableWrapperBase() = default; + // Note: This is not const to allow storing mutable lambdas. + virtual Out call(In...) = 0; + virtual void destroy() = 0; + virtual void init_and_swap(u8*, size_t) = 0; + }; + + template + class CallableWrapper final : public CallableWrapperBase { + AK_MAKE_NONMOVABLE(CallableWrapper); + AK_MAKE_NONCOPYABLE(CallableWrapper); + + public: + explicit CallableWrapper(CallableType&& callable) + : m_callable(move(callable)) + { + } + + Out call(In... in) final override + { + return m_callable(forward(in)...); + } + + void destroy() final override + { + delete this; + } + + void init_and_swap(u8* destination, size_t size) final override + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + } + + private: + CallableType m_callable; + }; + + enum class FunctionKind { + NullPointer, + Inline, + Outline, + }; + + CallableWrapperBase* callable_wrapper() const; + + void clear(bool may_defer = true) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + } + + template + void init_with_callable(Callable&& callable) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + } + + void move_from(Function&& other) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + } + + FunctionKind m_kind{ FunctionKind::NullPointer }; + bool m_deferred_clear{ false }; + mutable Atomic m_call_nesting_level{ 0 }; + static constexpr size_t inline_capacity = 4 * sizeof(void*); + //alignas(max(alignof(CallableWrapperBase), alignof(CallableWrapperBase*))) u8 m_storage[inline_capacity]; +}; + +} + +using AK::Function; diff --git a/AK/AK/GenericLexer.cpp b/LibC-Shim/AK/GenericLexer.cpp similarity index 92% rename from AK/AK/GenericLexer.cpp rename to LibC-Shim/AK/GenericLexer.cpp index 7410bcc..175496e 100644 --- a/AK/AK/GenericLexer.cpp +++ b/LibC-Shim/AK/GenericLexer.cpp @@ -1,6 +1,6 @@ -#include "pch.h" -#include "GenericLexer.h" - -namespace AK { - +#include "pch.h" +#include "GenericLexer.h" + +namespace AK { + } \ No newline at end of file diff --git a/AK/AK/GenericLexer.h b/LibC-Shim/AK/GenericLexer.h similarity index 92% rename from AK/AK/GenericLexer.h rename to LibC-Shim/AK/GenericLexer.h index 7cf25e1..99d1f21 100644 --- a/AK/AK/GenericLexer.h +++ b/LibC-Shim/AK/GenericLexer.h @@ -1,96 +1,96 @@ -#pragma once - -#include "./AK/Result.h" -#include "./AK/StringView.h" - -namespace AK { - -class GenericLexer { -public: - constexpr explicit GenericLexer(StringView input) - : m_input(input) - { - } - - constexpr size_t tell(); - constexpr size_t tell_remaining(); - - bool is_eof(); - bool next_is(char*) { - return false; - } - bool next_is(char) { - return false; - } - bool next_is(const char[]) { - return false; - } - bool next_is(StringView) { - return false; - } - - constexpr char peek(size_t offset = 0) const; - - void retreat(); - - char consume(); - - template - constexpr bool consume_specific(const T& next); - - bool consume_specific(String const& next); - - constexpr bool consume_specific(char const* next); - - char consume_escaped_character(char, StringView); - - StringView consume(size_t count); - StringView consume_all(); - StringView consume_line(); - StringView consume_until(char); - StringView consume_until(StringView); - StringView consume_quoted_string(char escape_char = 0); - - enum class UnicodeEscapeError { - MalformedUnicodeEscape, - UnicodeEscapeOverflow, - }; - - Result consume_escaped_code_point(bool combine_surrogate_pairs = true); - - constexpr void ignore(size_t count = 1); - - constexpr void ignore_until(char stop); - - constexpr void ignore_until(char const* stop); - - template - StringView consume_while(TPredicate pred); - - template - StringView consume_until(TPredicate pred); - -protected: - StringView m_input; - size_t m_index{ 0 }; -}; - -constexpr auto is_any_of(StringView values) -{ - return [values](auto c) { return values.contains(c); }; -} - -constexpr auto is_not_any_of(StringView values) -{ - return [values](auto c) { return !values.contains(c); }; -} - -//constexpr auto is_path_separator = is_any_of("/\\"sv); -//constexpr auto is_quote = is_any_of("'\""sv); - -} - -using AK::GenericLexer; -using AK::is_any_of; -//using AK::is_path_separator; -//using AK::is_quote; \ No newline at end of file +#pragma once + +#include "Result.h" +#include "StringView.h" + +namespace AK { + +class GenericLexer { +public: + constexpr explicit GenericLexer(StringView input) + : m_input(input) + { + } + + constexpr size_t tell(); + constexpr size_t tell_remaining(); + + bool is_eof(); + bool next_is(char*) { + return false; + } + bool next_is(char) { + return false; + } + bool next_is(const char[]) { + return false; + } + bool next_is(StringView) { + return false; + } + + constexpr char peek(size_t offset = 0) const; + + void retreat(); + + char consume(); + + template + constexpr bool consume_specific(const T& next); + + bool consume_specific(String const& next); + + constexpr bool consume_specific(char const* next); + + char consume_escaped_character(char, StringView); + + StringView consume(size_t count); + StringView consume_all(); + StringView consume_line(); + StringView consume_until(char); + StringView consume_until(StringView); + StringView consume_quoted_string(char escape_char = 0); + + enum class UnicodeEscapeError { + MalformedUnicodeEscape, + UnicodeEscapeOverflow, + }; + + Result consume_escaped_code_point(bool combine_surrogate_pairs = true); + + constexpr void ignore(size_t count = 1); + + constexpr void ignore_until(char stop); + + constexpr void ignore_until(char const* stop); + + template + StringView consume_while(TPredicate pred); + + template + StringView consume_until(TPredicate pred); + +protected: + StringView m_input; + size_t m_index{ 0 }; +}; + +constexpr auto is_any_of(StringView values) +{ + return [values](auto c) { return values.contains(c); }; +} + +constexpr auto is_not_any_of(StringView values) +{ + return [values](auto c) { return !values.contains(c); }; +} + +//constexpr auto is_path_separator = is_any_of("/\\"sv); +//constexpr auto is_quote = is_any_of("'\""sv); + +} + +using AK::GenericLexer; +using AK::is_any_of; +//using AK::is_path_separator; +//using AK::is_quote; diff --git a/AK/AK/HashFunctions.h b/LibC-Shim/AK/HashFunctions.h similarity index 92% rename from AK/AK/HashFunctions.h rename to LibC-Shim/AK/HashFunctions.h index 6209ce2..b1c2ad1 100644 --- a/AK/AK/HashFunctions.h +++ b/LibC-Shim/AK/HashFunctions.h @@ -1,36 +1,36 @@ -/* - * Copyright (c) 2018-2020, Andreas Kling - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include "./AK/Types.h" - -constexpr unsigned int_hash(u32 key) -{ - key += ~(key << 15); - key ^= (key >> 10); - key += (key << 3); - key ^= (key >> 6); - key += ~(key << 11); - key ^= (key >> 16); - return key; -} - -constexpr unsigned pair_int_hash(u32 key1, u32 key2) -{ - return int_hash((int_hash(key1) * 209) ^ (int_hash(key2 * 413))); -} - -constexpr unsigned u64_hash(u64 key) -{ - u32 first = key & 0xFFFFFFFF; - u32 last = key >> 32; - return pair_int_hash(first, last); -} - -constexpr unsigned ptr_hash(FlatPtr ptr); - -ALWAYS_INLINE unsigned ptr_hash(void const* ptr); +/* + * Copyright (c) 2018-2020, Andreas Kling + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include "Types.h" + +constexpr unsigned int_hash(u32 key) +{ + key += ~(key << 15); + key ^= (key >> 10); + key += (key << 3); + key ^= (key >> 6); + key += ~(key << 11); + key ^= (key >> 16); + return key; +} + +constexpr unsigned pair_int_hash(u32 key1, u32 key2) +{ + return int_hash((int_hash(key1) * 209) ^ (int_hash(key2 * 413))); +} + +constexpr unsigned u64_hash(u64 key) +{ + u32 first = key & 0xFFFFFFFF; + u32 last = key >> 32; + return pair_int_hash(first, last); +} + +constexpr unsigned ptr_hash(FlatPtr ptr); + +ALWAYS_INLINE unsigned ptr_hash(void const* ptr); diff --git a/AK/AK/HashMap.h b/LibC-Shim/AK/HashMap.h similarity index 95% rename from AK/AK/HashMap.h rename to LibC-Shim/AK/HashMap.h index cf44941..c30f885 100644 --- a/AK/AK/HashMap.h +++ b/LibC-Shim/AK/HashMap.h @@ -1,126 +1,126 @@ -/* - * Copyright (c) 2018-2020, Andreas Kling - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include "./AK/HashTable.h" -#include "./AK/Optional.h" -#include "./AK/Vector.h" -#include - -namespace AK { - -template -class HashMap { -private: - struct Entry { - K key; - V value; - }; - - struct EntryTraits { - static unsigned hash(Entry const& entry) { return KeyTraits::hash(entry.key); } - static bool equals(Entry const& a, Entry const& b) { return KeyTraits::equals(a.key, b.key); } - }; - -public: - using KeyType = K; - using ValueType = V; - - HashMap() = default; - - HashMap(std::initializer_list list) - { - } - - bool is_empty() const; - size_t size() const; - size_t capacity() const; - void clear(); - void clear_with_capacity(); - - HashSetResult set(const K& key, const V& value) { return m_table.set({ key, value }); } - HashSetResult set(const K& key, V&& value) { return m_table.set({ key, move(value) }); } - HashSetResult set(K&& key, V&& value) { return m_table.set({ move(key), move(value) }); } - ErrorOr try_set(const K& key, const V& value) { return m_table.try_set({ key, value }); } - ErrorOr try_set(const K& key, V&& value) { return m_table.try_set({ key, move(value) }); } - ErrorOr try_set(K&& key, V&& value) { return m_table.try_set({ move(key), move(value) }); } - - bool remove(const K& key); - - template Key> - requires(IsSame>) bool remove(Key const& key); - - template - bool remove_all_matching(TUnaryPredicate const& predicate); - - using HashTableType = HashTable; - using IteratorType = typename HashTableType::Iterator; - using ConstIteratorType = typename HashTableType::ConstIterator; - - IteratorType begin(); - IteratorType end(); - IteratorType find(const K& key); - template - IteratorType find(unsigned hash, TUnaryPredicate predicate); - - ConstIteratorType begin() const; - ConstIteratorType end() const; - ConstIteratorType find(const K& key) const; - template - ConstIteratorType find(unsigned hash, TUnaryPredicate predicate) const; - - template Key> - requires(IsSame>) IteratorType find(Key const& key); - - template Key> - requires(IsSame>) ConstIteratorType find(Key const& key) const; - - void ensure_capacity(size_t capacity); - ErrorOr try_ensure_capacity(size_t capacity); - - Optional::ConstPeekType> get(const K& key) const requires(!IsPointer::PeekType>); - - Optional::ConstPeekType> get(const K& key) const requires(IsPointer::PeekType>); - - Optional::PeekType> get(const K& key) requires(!IsConst::PeekType>); - - template Key> - requires(IsSame>) Optional::PeekType> get(Key const& key) - const requires(!IsPointer::PeekType>); - - template Key> - requires(IsSame>) Optional::ConstPeekType> get(Key const& key) - const requires(IsPointer::PeekType>); - - template Key> - requires(IsSame>) Optional::PeekType> get(Key const& key) - requires(!IsConst::PeekType>); - - bool contains(const K& key) const; - - template Key> - requires(IsSame>) bool contains(Key const& value); - - void remove(IteratorType it); - - V& ensure(const K& key); - - template - V& ensure(K const& key, Callback initialization_callback); - - Vector keys() const; - - u32 hash() const; - -private: - HashTableType m_table; -}; - -} - -using AK::HashMap; -using AK::OrderedHashMap; +/* + * Copyright (c) 2018-2020, Andreas Kling + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include "HashTable.h" +#include "Optional.h" +#include "Vector.h" +#include + +namespace AK { + +template +class HashMap { +private: + struct Entry { + K key; + V value; + }; + + struct EntryTraits { + static unsigned hash(Entry const& entry) { return KeyTraits::hash(entry.key); } + static bool equals(Entry const& a, Entry const& b) { return KeyTraits::equals(a.key, b.key); } + }; + +public: + using KeyType = K; + using ValueType = V; + + HashMap() = default; + + HashMap(std::initializer_list list) + { + } + + bool is_empty() const; + size_t size() const; + size_t capacity() const; + void clear(); + void clear_with_capacity(); + + HashSetResult set(const K& key, const V& value) { return m_table.set({ key, value }); } + HashSetResult set(const K& key, V&& value) { return m_table.set({ key, move(value) }); } + HashSetResult set(K&& key, V&& value) { return m_table.set({ move(key), move(value) }); } + ErrorOr try_set(const K& key, const V& value) { return m_table.try_set({ key, value }); } + ErrorOr try_set(const K& key, V&& value) { return m_table.try_set({ key, move(value) }); } + ErrorOr try_set(K&& key, V&& value) { return m_table.try_set({ move(key), move(value) }); } + + bool remove(const K& key); + + template Key> + requires(IsSame>) bool remove(Key const& key); + + template + bool remove_all_matching(TUnaryPredicate const& predicate); + + using HashTableType = HashTable; + using IteratorType = typename HashTableType::Iterator; + using ConstIteratorType = typename HashTableType::ConstIterator; + + IteratorType begin(); + IteratorType end(); + IteratorType find(const K& key); + template + IteratorType find(unsigned hash, TUnaryPredicate predicate); + + ConstIteratorType begin() const; + ConstIteratorType end() const; + ConstIteratorType find(const K& key) const; + template + ConstIteratorType find(unsigned hash, TUnaryPredicate predicate) const; + + template Key> + requires(IsSame>) IteratorType find(Key const& key); + + template Key> + requires(IsSame>) ConstIteratorType find(Key const& key) const; + + void ensure_capacity(size_t capacity); + ErrorOr try_ensure_capacity(size_t capacity); + + Optional::ConstPeekType> get(const K& key) const requires(!IsPointer::PeekType>); + + Optional::ConstPeekType> get(const K& key) const requires(IsPointer::PeekType>); + + Optional::PeekType> get(const K& key) requires(!IsConst::PeekType>); + + template Key> + requires(IsSame>) Optional::PeekType> get(Key const& key) + const requires(!IsPointer::PeekType>); + + template Key> + requires(IsSame>) Optional::ConstPeekType> get(Key const& key) + const requires(IsPointer::PeekType>); + + template Key> + requires(IsSame>) Optional::PeekType> get(Key const& key) + requires(!IsConst::PeekType>); + + bool contains(const K& key) const; + + template Key> + requires(IsSame>) bool contains(Key const& value); + + void remove(IteratorType it); + + V& ensure(const K& key); + + template + V& ensure(K const& key, Callback initialization_callback); + + Vector keys() const; + + u32 hash() const; + +private: + HashTableType m_table; +}; + +} + +using AK::HashMap; +using AK::OrderedHashMap; diff --git a/AK/AK/HashTable.h b/LibC-Shim/AK/HashTable.h similarity index 94% rename from AK/AK/HashTable.h rename to LibC-Shim/AK/HashTable.h index d4cb42d..4228a31 100644 --- a/AK/AK/HashTable.h +++ b/LibC-Shim/AK/HashTable.h @@ -1,271 +1,271 @@ -/* - * Copyright (c) 2018-2020, Andreas Kling - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include "./AK/Concepts.h" -#include "./AK/Error.h" -#include "./AK/Forward.h" -#include "./AK/HashFunctions.h" -#include "./AK/StdLibExtras.h" -#include "./AK/Traits.h" -#include "./AK/Types.h" - -namespace AK { - -enum class HashSetResult { - InsertedNewEntry, - ReplacedExistingEntry, - KeptExistingEntry -}; - -enum class HashSetExistingEntryBehavior { - Keep, - Replace -}; - -// Upper nibble determines state class: -// - 0: unused bucket -// - 1: used bucket -// - F: end bucket -// Lower nibble determines state within a class. -enum class BucketState : u8 { - Free = 0x00, - Used = 0x10, - Deleted = 0x01, - Rehashed = 0x12, - End = 0xFF, -}; - -// Note that because there's the end state, used and free are not 100% opposites! -constexpr bool is_used_bucket(BucketState state) -{ - return (static_cast(state) & 0xf0) == 0x10; -} - -constexpr bool is_free_bucket(BucketState state) -{ - return (static_cast(state) & 0xf0) == 0x00; -} - -template -class HashTableIterator { - friend HashTableType; - -public: - bool operator==(HashTableIterator const& other) const { return m_bucket == other.m_bucket; } - bool operator!=(HashTableIterator const& other) const { return m_bucket != other.m_bucket; } - T& operator*() { return *m_bucket->slot(); } - T* operator->() { return m_bucket->slot(); } - void operator++() { skip_to_next(); } - -private: - void skip_to_next() - { - if (!m_bucket) - return; - do { - ++m_bucket; - if (m_bucket->state == BucketState::Used) - return; - } while (m_bucket->state != BucketState::End); - if (m_bucket->state == BucketState::End) - m_bucket = nullptr; - } - - explicit HashTableIterator(BucketType* bucket) - : m_bucket(bucket) - { - } - - BucketType* m_bucket{ nullptr }; -}; - -template -class OrderedHashTableIterator { - friend OrderedHashTableType; - -public: - bool operator==(OrderedHashTableIterator const& other) const { return m_bucket == other.m_bucket; } - bool operator!=(OrderedHashTableIterator const& other) const { return m_bucket != other.m_bucket; } - T& operator*() { return *m_bucket->slot(); } - T* operator->() { return m_bucket->slot(); } - void operator++() { m_bucket = m_bucket->next; } - void operator--() { m_bucket = m_bucket->previous; } - -private: - explicit OrderedHashTableIterator(BucketType* bucket) - : m_bucket(bucket) - { - } - - BucketType* m_bucket{ nullptr }; -}; - -template -class HashTable { - static constexpr size_t load_factor_in_percent = 60; - - struct Bucket { - BucketState state; - alignas(T) u8 storage[sizeof(T)]; - - T* slot() { return reinterpret_cast(storage); } - const T* slot() const { return reinterpret_cast(storage); } - }; - - struct OrderedBucket { - OrderedBucket* previous; - OrderedBucket* next; - BucketState state; - alignas(T) u8 storage[sizeof(T)]; - T* slot() { return reinterpret_cast(storage); } - const T* slot() const { return reinterpret_cast(storage); } - }; - - using BucketType = Conditional; - - struct CollectionData { - }; - - struct OrderedCollectionData { - BucketType* head{ nullptr }; - BucketType* tail{ nullptr }; - }; - - using CollectionDataType = Conditional; - -public: - HashTable() = default; - explicit HashTable(size_t capacity); - - ~HashTable() = default; - - HashTable(HashTable const& other); - - HashTable& operator=(HashTable const& other); - - HashTable(HashTable&& other) noexcept - : m_buckets(other.m_buckets) - , m_collection_data(other.m_collection_data) - , m_size(other.m_size) - , m_capacity(other.m_capacity) - , m_deleted_count(other.m_deleted_count) - { - } - - HashTable& operator=(HashTable&& other) noexcept; - - friend void swap(HashTable& a, HashTable& b) noexcept; - - bool is_empty() const { return m_size == 0; } - size_t size() const { return m_size; } - size_t capacity() const { return m_capacity; } - - template - ErrorOr try_set_from(U(&from_array)[N]); - template - void set_from(U(&from_array)[N]); - - void ensure_capacity(size_t capacity); - - ErrorOr try_ensure_capacity(size_t capacity); - - bool contains(T const& value) const; - - template K> - requires(IsSame>) bool contains(K const& value) const; - - using Iterator = Conditional, - HashTableIterator>; - - Iterator begin(); - - Iterator end(); - - using ConstIterator = Conditional, - HashTableIterator>; - - ConstIterator begin() const; - - ConstIterator end() const; - - void clear(); - void clear_with_capacity(); - - template - ErrorOr try_set(U&& value, HashSetExistingEntryBehavior existing_entry_behavior = HashSetExistingEntryBehavior::Replace); - template - HashSetResult set(U&& value, HashSetExistingEntryBehavior existing_entry_behaviour = HashSetExistingEntryBehavior::Replace); - - template - Iterator find(unsigned hash, TUnaryPredicate predicate); - - Iterator find(T const& value); - - template - ConstIterator find(unsigned hash, TUnaryPredicate predicate) const; - - ConstIterator find(T const& value) const; - - template K> - requires(IsSame>) Iterator find(K const& value); - - template K, typename TUnaryPredicate> - requires(IsSame>) Iterator find(K const& value, TUnaryPredicate predicate); - - template K> - requires(IsSame>) ConstIterator find(K const& value) const; - - template K, typename TUnaryPredicate> - requires(IsSame>) ConstIterator find(K const& value, TUnaryPredicate predicate) const; - - bool remove(const T& value); - - template K> - requires(IsSame>) bool remove(K const& value); - - void remove(Iterator iterator); - - template - bool remove_all_matching(TUnaryPredicate const& predicate); - -private: - void insert_during_rehash(T&& value); - - static constexpr size_t size_in_bytes(size_t capacity); - - ErrorOr try_rehash(size_t new_capacity); - void rehash(size_t new_capacity); - - void rehash_in_place(); - - void rehash_in_place_if_needed(); - - template - BucketType* lookup_with_hash(unsigned hash, TUnaryPredicate predicate) const; - - ErrorOr try_lookup_for_writing(T const& value); - BucketType& lookup_for_writing(T const& value); - - size_t used_bucket_count() const; - bool should_grow() const; - - void delete_bucket(auto& bucket); - - BucketType* m_buckets{ nullptr }; - - CollectionDataType m_collection_data; - size_t m_size{ 0 }; - size_t m_capacity{ 0 }; - size_t m_deleted_count{ 0 }; -}; -} - -using AK::HashTable; -using AK::OrderedHashTable; +/* + * Copyright (c) 2018-2020, Andreas Kling + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include "Concepts.h" +#include "Error.h" +#include "Forward.h" +#include "HashFunctions.h" +#include "StdLibExtras.h" +#include "Traits.h" +#include "Types.h" + +namespace AK { + +enum class HashSetResult { + InsertedNewEntry, + ReplacedExistingEntry, + KeptExistingEntry +}; + +enum class HashSetExistingEntryBehavior { + Keep, + Replace +}; + +// Upper nibble determines state class: +// - 0: unused bucket +// - 1: used bucket +// - F: end bucket +// Lower nibble determines state within a class. +enum class BucketState : u8 { + Free = 0x00, + Used = 0x10, + Deleted = 0x01, + Rehashed = 0x12, + End = 0xFF, +}; + +// Note that because there's the end state, used and free are not 100% opposites! +constexpr bool is_used_bucket(BucketState state) +{ + return (static_cast(state) & 0xf0) == 0x10; +} + +constexpr bool is_free_bucket(BucketState state) +{ + return (static_cast(state) & 0xf0) == 0x00; +} + +template +class HashTableIterator { + friend HashTableType; + +public: + bool operator==(HashTableIterator const& other) const { return m_bucket == other.m_bucket; } + bool operator!=(HashTableIterator const& other) const { return m_bucket != other.m_bucket; } + T& operator*() { return *m_bucket->slot(); } + T* operator->() { return m_bucket->slot(); } + void operator++() { skip_to_next(); } + +private: + void skip_to_next() + { + if (!m_bucket) + return; + do { + ++m_bucket; + if (m_bucket->state == BucketState::Used) + return; + } while (m_bucket->state != BucketState::End); + if (m_bucket->state == BucketState::End) + m_bucket = nullptr; + } + + explicit HashTableIterator(BucketType* bucket) + : m_bucket(bucket) + { + } + + BucketType* m_bucket{ nullptr }; +}; + +template +class OrderedHashTableIterator { + friend OrderedHashTableType; + +public: + bool operator==(OrderedHashTableIterator const& other) const { return m_bucket == other.m_bucket; } + bool operator!=(OrderedHashTableIterator const& other) const { return m_bucket != other.m_bucket; } + T& operator*() { return *m_bucket->slot(); } + T* operator->() { return m_bucket->slot(); } + void operator++() { m_bucket = m_bucket->next; } + void operator--() { m_bucket = m_bucket->previous; } + +private: + explicit OrderedHashTableIterator(BucketType* bucket) + : m_bucket(bucket) + { + } + + BucketType* m_bucket{ nullptr }; +}; + +template +class HashTable { + static constexpr size_t load_factor_in_percent = 60; + + struct Bucket { + BucketState state; + alignas(T) u8 storage[sizeof(T)]; + + T* slot() { return reinterpret_cast(storage); } + const T* slot() const { return reinterpret_cast(storage); } + }; + + struct OrderedBucket { + OrderedBucket* previous; + OrderedBucket* next; + BucketState state; + alignas(T) u8 storage[sizeof(T)]; + T* slot() { return reinterpret_cast(storage); } + const T* slot() const { return reinterpret_cast(storage); } + }; + + using BucketType = Conditional; + + struct CollectionData { + }; + + struct OrderedCollectionData { + BucketType* head{ nullptr }; + BucketType* tail{ nullptr }; + }; + + using CollectionDataType = Conditional; + +public: + HashTable() = default; + explicit HashTable(size_t capacity); + + ~HashTable() = default; + + HashTable(HashTable const& other); + + HashTable& operator=(HashTable const& other); + + HashTable(HashTable&& other) noexcept + : m_buckets(other.m_buckets) + , m_collection_data(other.m_collection_data) + , m_size(other.m_size) + , m_capacity(other.m_capacity) + , m_deleted_count(other.m_deleted_count) + { + } + + HashTable& operator=(HashTable&& other) noexcept; + + friend void swap(HashTable& a, HashTable& b) noexcept; + + bool is_empty() const { return m_size == 0; } + size_t size() const { return m_size; } + size_t capacity() const { return m_capacity; } + + template + ErrorOr try_set_from(U(&from_array)[N]); + template + void set_from(U(&from_array)[N]); + + void ensure_capacity(size_t capacity); + + ErrorOr try_ensure_capacity(size_t capacity); + + bool contains(T const& value) const; + + template K> + requires(IsSame>) bool contains(K const& value) const; + + using Iterator = Conditional, + HashTableIterator>; + + Iterator begin(); + + Iterator end(); + + using ConstIterator = Conditional, + HashTableIterator>; + + ConstIterator begin() const; + + ConstIterator end() const; + + void clear(); + void clear_with_capacity(); + + template + ErrorOr try_set(U&& value, HashSetExistingEntryBehavior existing_entry_behavior = HashSetExistingEntryBehavior::Replace); + template + HashSetResult set(U&& value, HashSetExistingEntryBehavior existing_entry_behaviour = HashSetExistingEntryBehavior::Replace); + + template + Iterator find(unsigned hash, TUnaryPredicate predicate); + + Iterator find(T const& value); + + template + ConstIterator find(unsigned hash, TUnaryPredicate predicate) const; + + ConstIterator find(T const& value) const; + + template K> + requires(IsSame>) Iterator find(K const& value); + + template K, typename TUnaryPredicate> + requires(IsSame>) Iterator find(K const& value, TUnaryPredicate predicate); + + template K> + requires(IsSame>) ConstIterator find(K const& value) const; + + template K, typename TUnaryPredicate> + requires(IsSame>) ConstIterator find(K const& value, TUnaryPredicate predicate) const; + + bool remove(const T& value); + + template K> + requires(IsSame>) bool remove(K const& value); + + void remove(Iterator iterator); + + template + bool remove_all_matching(TUnaryPredicate const& predicate); + +private: + void insert_during_rehash(T&& value); + + static constexpr size_t size_in_bytes(size_t capacity); + + ErrorOr try_rehash(size_t new_capacity); + void rehash(size_t new_capacity); + + void rehash_in_place(); + + void rehash_in_place_if_needed(); + + template + BucketType* lookup_with_hash(unsigned hash, TUnaryPredicate predicate) const; + + ErrorOr try_lookup_for_writing(T const& value); + BucketType& lookup_for_writing(T const& value); + + size_t used_bucket_count() const; + bool should_grow() const; + + void delete_bucket(auto& bucket); + + BucketType* m_buckets{ nullptr }; + + CollectionDataType m_collection_data; + size_t m_size{ 0 }; + size_t m_capacity{ 0 }; + size_t m_deleted_count{ 0 }; +}; +} + +using AK::HashTable; +using AK::OrderedHashTable; diff --git a/AK/AK/Hex.h b/LibC-Shim/AK/Hex.h similarity index 80% rename from AK/AK/Hex.h rename to LibC-Shim/AK/Hex.h index 2bd8995..ad890b3 100644 --- a/AK/AK/Hex.h +++ b/LibC-Shim/AK/Hex.h @@ -1,35 +1,35 @@ -/* - * Copyright (c) 2020, Andreas Kling - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include "./AK/ByteBuffer.h" -#include "./AK/Error.h" -#include "./AK/StringView.h" -#include "./AK/String.h" - -namespace AK { - -constexpr u8 decode_hex_digit(char digit) -{ - if (digit >= '0' && digit <= '9') - return digit - '0'; - if (digit >= 'a' && digit <= 'f') - return 10 + (digit - 'a'); - if (digit >= 'A' && digit <= 'F') - return 10 + (digit - 'A'); - return 255; -} - -ErrorOr decode_hex(StringView); - -String encode_hex(ReadonlyBytes); - -} - -using AK::decode_hex; -using AK::decode_hex_digit; -using AK::encode_hex; +/* + * Copyright (c) 2020, Andreas Kling + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include "ByteBuffer.h" +#include "Error.h" +#include "StringView.h" +#include "String.h" + +namespace AK { + +constexpr u8 decode_hex_digit(char digit) +{ + if (digit >= '0' && digit <= '9') + return digit - '0'; + if (digit >= 'a' && digit <= 'f') + return 10 + (digit - 'a'); + if (digit >= 'A' && digit <= 'F') + return 10 + (digit - 'A'); + return 255; +} + +ErrorOr decode_hex(StringView); + +String encode_hex(ReadonlyBytes); + +} + +using AK::decode_hex; +using AK::decode_hex_digit; +using AK::encode_hex; diff --git a/AK/AK/IPv4Address.h b/LibC-Shim/AK/IPv4Address.h similarity index 94% rename from AK/AK/IPv4Address.h rename to LibC-Shim/AK/IPv4Address.h index 8f56ef9..548826c 100644 --- a/AK/AK/IPv4Address.h +++ b/LibC-Shim/AK/IPv4Address.h @@ -6,12 +6,12 @@ #pragma once -#include "./AK/Endian.h" -#include "./AK/Format.h" -#include "./AK/Optional.h" -#include "./AK/StringView.h" -#include "./AK/Vector.h" -#include "./AK/String.h" +#include "Endian.h" +#include "Format.h" +#include "Optional.h" +#include "StringView.h" +#include "Vector.h" +#include "String.h" namespace AK { diff --git a/AK/AK/IntrusiveDetails.h b/LibC-Shim/AK/IntrusiveDetails.h similarity index 90% rename from AK/AK/IntrusiveDetails.h rename to LibC-Shim/AK/IntrusiveDetails.h index d11f2bb..7da850c 100644 --- a/AK/AK/IntrusiveDetails.h +++ b/LibC-Shim/AK/IntrusiveDetails.h @@ -1,31 +1,31 @@ -/* - * Copyright (c) 2021, Ali Mohammad Pur - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include "./AK/NonnullRefPtr.h" - -namespace AK::Detail { - -template -struct SubstituteIntrusiveContainerType { - using Type = Container; -}; - -template -struct SubstituteIntrusiveContainerType> { - using Type = RefPtr; -}; - -template -struct SelfReferenceIfNeeded { - Container reference = nullptr; -}; -template -struct SelfReferenceIfNeeded { -}; - -} +/* + * Copyright (c) 2021, Ali Mohammad Pur + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include "NonnullRefPtr.h" + +namespace AK::Detail { + +template +struct SubstituteIntrusiveContainerType { + using Type = Container; +}; + +template +struct SubstituteIntrusiveContainerType> { + using Type = RefPtr; +}; + +template +struct SelfReferenceIfNeeded { + Container reference = nullptr; +}; +template +struct SelfReferenceIfNeeded { +}; + +} diff --git a/LibC-Shim/AK/IntrusiveList.cpp b/LibC-Shim/AK/IntrusiveList.cpp new file mode 100644 index 0000000..899a9e2 --- /dev/null +++ b/LibC-Shim/AK/IntrusiveList.cpp @@ -0,0 +1,2 @@ +#include "pch.h" +#include "IntrusiveList.h" diff --git a/AK/AK/IntrusiveList.h b/LibC-Shim/AK/IntrusiveList.h similarity index 90% rename from AK/AK/IntrusiveList.h rename to LibC-Shim/AK/IntrusiveList.h index cff6094..c9f6012 100644 --- a/AK/AK/IntrusiveList.h +++ b/LibC-Shim/AK/IntrusiveList.h @@ -1,127 +1,127 @@ -/* - * Copyright (c) 2018-2020, Andreas Kling - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include -#include "./AK/Assertions.h" -#include "./AK/BitCast.h" -#include "./AK/Forward.h" -#include "./AK/IntrusiveDetails.h" -#include "./AK/Noncopyable.h" -#include "./AK/StdLibExtras.h" - -namespace AK { - -template -class IntrusiveListNode { -public: - void remove(); - bool is_in_list() const; -}; - -template -class IntrusiveList {}; - -// Thanks to https://stackoverflow.com/a/59139500/3142553 -template -class IntrusiveList

{ - AK_MAKE_NONCOPYABLE(IntrusiveList); - AK_MAKE_NONMOVABLE(IntrusiveList); - -public: - IntrusiveList() = default; - ~IntrusiveList(); - - void clear(); - bool is_empty(); - size_t size_slow(); - void append(NodeType&); - void prepend(NodeType&); - void insert_before(NodeType&, NodeType&); - void remove(NodeType&); - - bool contains(const T&) const; - NodeType* first(); - NodeType* last(); - - NodeType take_first(); - NodeType take_last(); - - class Iterator { - public: - Iterator() = default; - Iterator(T* value) - : m_value(move(value)) - { - } - - const NodeType& operator*() const; - auto operator->() const; - NodeType& operator*(); - auto operator->(); - bool operator==(Iterator const& other) const; - bool operator!=(Iterator const& other) const; - Iterator& operator++(); - Iterator& erase(); - - private: - T* m_value{ nullptr }; - }; - - Iterator begin(); - Iterator end() { return Iterator{}; } - - class ReverseIterator { - public: - ReverseIterator() = default; - ReverseIterator(T* value) - : m_value(move(value)) - { - } - - const NodeType& operator*(); - auto operator->() const { return m_value; } - NodeType& operator*(); - auto operator->() { return m_value; } - bool operator==(ReverseIterator const& other) const; - bool operator!=(ReverseIterator const& other) const; - ReverseIterator& operator++(); - ReverseIterator& erase(); - - private: - T* m_value{ nullptr }; - }; - - ReverseIterator rbegin(); - ReverseIterator rend() { return ReverseIterator{}; } - - class ConstIterator { - public: - ConstIterator() = default; - ConstIterator(const T* value) - : m_value(value) - { - } - - const NodeType& operator*() const; - auto operator->() const; - bool operator==(ConstIterator const& other) const; - bool operator!=(ConstIterator const& other) const; - ConstIterator& operator++(); - - private: - const T* m_value{ nullptr }; - }; - - ConstIterator begin() const; - ConstIterator end() const { return ConstIterator{}; } -}; - -} - -using AK::IntrusiveList; -using AK::IntrusiveListNode; +/* + * Copyright (c) 2018-2020, Andreas Kling + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include "Assertions.h" +#include "BitCast.h" +#include "Forward.h" +#include "IntrusiveDetails.h" +#include "Noncopyable.h" +#include "StdLibExtras.h" + +namespace AK { + +template +class IntrusiveListNode { +public: + void remove(); + bool is_in_list() const; +}; + +template +class IntrusiveList {}; + +// Thanks to https://stackoverflow.com/a/59139500/3142553 +template +class IntrusiveList

{ + AK_MAKE_NONCOPYABLE(IntrusiveList); + AK_MAKE_NONMOVABLE(IntrusiveList); + +public: + IntrusiveList() = default; + ~IntrusiveList(); + + void clear(); + bool is_empty(); + size_t size_slow(); + void append(NodeType&); + void prepend(NodeType&); + void insert_before(NodeType&, NodeType&); + void remove(NodeType&); + + bool contains(const T&) const; + NodeType* first(); + NodeType* last(); + + NodeType take_first(); + NodeType take_last(); + + class Iterator { + public: + Iterator() = default; + Iterator(T* value) + : m_value(move(value)) + { + } + + const NodeType& operator*() const; + auto operator->() const; + NodeType& operator*(); + auto operator->(); + bool operator==(Iterator const& other) const; + bool operator!=(Iterator const& other) const; + Iterator& operator++(); + Iterator& erase(); + + private: + T* m_value{ nullptr }; + }; + + Iterator begin(); + Iterator end() { return Iterator{}; } + + class ReverseIterator { + public: + ReverseIterator() = default; + ReverseIterator(T* value) + : m_value(move(value)) + { + } + + const NodeType& operator*(); + auto operator->() const { return m_value; } + NodeType& operator*(); + auto operator->() { return m_value; } + bool operator==(ReverseIterator const& other) const; + bool operator!=(ReverseIterator const& other) const; + ReverseIterator& operator++(); + ReverseIterator& erase(); + + private: + T* m_value{ nullptr }; + }; + + ReverseIterator rbegin(); + ReverseIterator rend() { return ReverseIterator{}; } + + class ConstIterator { + public: + ConstIterator() = default; + ConstIterator(const T* value) + : m_value(value) + { + } + + const NodeType& operator*() const; + auto operator->() const; + bool operator==(ConstIterator const& other) const; + bool operator!=(ConstIterator const& other) const; + ConstIterator& operator++(); + + private: + const T* m_value{ nullptr }; + }; + + ConstIterator begin() const; + ConstIterator end() const { return ConstIterator{}; } +}; + +} + +using AK::IntrusiveList; +using AK::IntrusiveListNode; diff --git a/AK/AK/IntrusiveRedBlackTree.h b/LibC-Shim/AK/IntrusiveRedBlackTree.h similarity index 98% rename from AK/AK/IntrusiveRedBlackTree.h rename to LibC-Shim/AK/IntrusiveRedBlackTree.h index 79dce8f..be15128 100644 --- a/AK/AK/IntrusiveRedBlackTree.h +++ b/LibC-Shim/AK/IntrusiveRedBlackTree.h @@ -6,8 +6,8 @@ #pragma once -#include "./AK/IntrusiveDetails.h" -#include "./AK/RedBlackTree.h" +#include "IntrusiveDetails.h" +#include "RedBlackTree.h" namespace AK::Detail { diff --git a/AK/AK/IterationDecision.h b/LibC-Shim/AK/IterationDecision.h similarity index 92% rename from AK/AK/IterationDecision.h rename to LibC-Shim/AK/IterationDecision.h index a4c7acd..e1629b1 100644 --- a/AK/AK/IterationDecision.h +++ b/LibC-Shim/AK/IterationDecision.h @@ -1,18 +1,18 @@ -/* - * Copyright (c) 2018-2020, Andreas Kling - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -namespace AK { - -enum class IterationDecision { - Continue, - Break, -}; - -} - -using AK::IterationDecision; +/* + * Copyright (c) 2018-2020, Andreas Kling + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +namespace AK { + +enum class IterationDecision { + Continue, + Break, +}; + +} + +using AK::IterationDecision; diff --git a/AK/AK/Iterator.h b/LibC-Shim/AK/Iterator.h similarity index 85% rename from AK/AK/Iterator.h rename to LibC-Shim/AK/Iterator.h index 6f5289c..6c42f93 100644 --- a/AK/AK/Iterator.h +++ b/LibC-Shim/AK/Iterator.h @@ -1,82 +1,90 @@ -/* - * Copyright (c) 2020, the SerenityOS developers. - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include "./AK/Forward.h" - -namespace AK { - -template -class SimpleIterator { -public: - friend Container; - - constexpr bool is_end() const { return m_index == SimpleIterator::end(m_container).m_index; } - constexpr size_t index() const { return m_index; } - - constexpr bool operator==(SimpleIterator other) const { return m_index == other.m_index; } - constexpr bool operator!=(SimpleIterator other) const { return m_index != other.m_index; } - constexpr bool operator<(SimpleIterator other) const { return m_index < other.m_index; } - constexpr bool operator>(SimpleIterator other) const { return m_index > other.m_index; } - constexpr bool operator<=(SimpleIterator other) const { return m_index <= other.m_index; } - constexpr bool operator>=(SimpleIterator other) const { return m_index >= other.m_index; } - - constexpr SimpleIterator operator+(ptrdiff_t delta) const { return SimpleIterator{ m_container, m_index + delta }; } - constexpr SimpleIterator operator-(ptrdiff_t delta) const { return SimpleIterator{ m_container, m_index - delta }; } - - constexpr ptrdiff_t operator-(SimpleIterator other) const { return static_cast(m_index) - other.m_index; } - - constexpr SimpleIterator operator++() - { - ++m_index; - return *this; - } - constexpr SimpleIterator operator++(int) - { - ++m_index; - return SimpleIterator{ m_container, m_index - 1 }; - } - - constexpr SimpleIterator operator--() - { - --m_index; - return *this; - } - constexpr SimpleIterator operator--(int) - { - --m_index; - return SimpleIterator{ m_container, m_index + 1 }; - } - - ALWAYS_INLINE constexpr ValueType const& operator*() const { return (ValueType const&)m_container[m_index]; } - ALWAYS_INLINE constexpr ValueType& operator*() { return (ValueType&)m_container[m_index]; } - - ALWAYS_INLINE constexpr ValueType const* operator->() const { return (ValueType const*)&m_container[m_index]; } - ALWAYS_INLINE constexpr ValueType* operator->() { return (ValueType*)&m_container[m_index]; } - - SimpleIterator& operator=(SimpleIterator const& other) - { - m_index = other.m_index; - return *this; - } - SimpleIterator(SimpleIterator const& obj) = default; - -private: - static constexpr SimpleIterator begin(Container& container); - static constexpr SimpleIterator end(Container& container); - - constexpr SimpleIterator(Container& container, size_t index) - : m_container(container) - , m_index(index) - { - } - - Container& m_container; - size_t m_index; -}; - -} +/* + * Copyright (c) 2020, the SerenityOS developers. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include "Forward.h" + +namespace AK { + +template +class SimpleIterator { +public: + friend Container; + + constexpr bool is_end() const { return m_index == SimpleIterator::end(m_container).m_index; } + constexpr size_t index() const { return m_index; } + + constexpr bool operator==(SimpleIterator other) const { return m_index == other.m_index; } + constexpr bool operator!=(SimpleIterator other) const { return m_index != other.m_index; } + constexpr bool operator<(SimpleIterator other) const { return m_index < other.m_index; } + constexpr bool operator>(SimpleIterator other) const { return m_index > other.m_index; } + constexpr bool operator<=(SimpleIterator other) const { return m_index <= other.m_index; } + constexpr bool operator>=(SimpleIterator other) const { return m_index >= other.m_index; } + + constexpr SimpleIterator operator+(ptrdiff_t delta) const { return SimpleIterator{ m_container, m_index + delta }; } + constexpr SimpleIterator operator-(ptrdiff_t delta) const { return SimpleIterator{ m_container, m_index - delta }; } + + constexpr ptrdiff_t operator-(SimpleIterator other) const { return static_cast(m_index) - other.m_index; } + + constexpr SimpleIterator operator++() + { + ++m_index; + return *this; + } + constexpr SimpleIterator operator++(int) + { + ++m_index; + return SimpleIterator{ m_container, m_index - 1 }; + } + + constexpr SimpleIterator operator--() + { + --m_index; + return *this; + } + constexpr SimpleIterator operator--(int) + { + --m_index; + return SimpleIterator{ m_container, m_index + 1 }; + } + + ALWAYS_INLINE constexpr ValueType const& operator*() const { return (ValueType const&)m_container[m_index]; } + ALWAYS_INLINE constexpr ValueType& operator*() { return (ValueType&)m_container[m_index]; } + + ALWAYS_INLINE constexpr ValueType const* operator->() const { return (ValueType const*)&m_container[m_index]; } + ALWAYS_INLINE constexpr ValueType* operator->() { return (ValueType*)&m_container[m_index]; } + + SimpleIterator& operator=(SimpleIterator const& other) + { + m_index = other.m_index; + return *this; + } + SimpleIterator(SimpleIterator const& obj) = default; + +private: + static constexpr SimpleIterator begin(Container& container) { return { container, 0 }; } + static constexpr SimpleIterator end(Container& container) + { + using RawContainerType = RemoveCV; + + if constexpr (IsSame || IsSame) + return { container, container.length() }; + else + return { container, container.size() }; + } + + constexpr SimpleIterator(Container& container, size_t index) + : m_container(container) + , m_index(index) + { + } + + Container& m_container; + size_t m_index; +}; + +} diff --git a/AK/AK/JsonArray.h b/LibC-Shim/AK/JsonArray.h similarity index 87% rename from AK/AK/JsonArray.h rename to LibC-Shim/AK/JsonArray.h index 2ac47a4..36bf067 100644 --- a/AK/AK/JsonArray.h +++ b/LibC-Shim/AK/JsonArray.h @@ -1,69 +1,69 @@ -/* - * Copyright (c) 2018-2020, Andreas Kling - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include "./AK/Concepts.h" -#include "./AK/JsonObjectSerializer.h" -#include "./AK/JsonValue.h" -#include "./AK/Vector.h" - -namespace AK { - -class JsonArray { -public: - JsonArray() = default; - ~JsonArray() = default; - - JsonArray(JsonArray const& other) - : m_values(other.m_values) - { - } - - JsonArray(JsonArray&& other) - : m_values(move(other.m_values)) - { - } - - template - JsonArray(ContainerT const& source); - - JsonArray& operator=(JsonArray const& other); - - JsonArray& operator=(JsonArray&& other); - - size_t size() const; - bool is_empty() const; - - JsonValue const& at(size_t index) const; - JsonValue const& operator[](size_t index) const; - - void clear() { m_values.clear(); } - void append(JsonValue value); - void set(size_t index, JsonValue value); - - template - typename Builder::OutputType serialized() const; - - template - void serialize(Builder&) const; - - String to_string() const { return serialized(); } - - template - void for_each(Callback callback) const; - - Vector const& values(); - - void ensure_capacity(size_t capacity); - -private: - Vector m_values; -}; - -} - -using AK::JsonArray; +/* + * Copyright (c) 2018-2020, Andreas Kling + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include "Concepts.h" +#include "JsonObjectSerializer.h" +#include "JsonValue.h" +#include "Vector.h" + +namespace AK { + +class JsonArray { +public: + JsonArray() = default; + ~JsonArray() = default; + + JsonArray(JsonArray const& other) + : m_values(other.m_values) + { + } + + JsonArray(JsonArray&& other) + : m_values(move(other.m_values)) + { + } + + template + JsonArray(ContainerT const& source); + + JsonArray& operator=(JsonArray const& other); + + JsonArray& operator=(JsonArray&& other); + + size_t size() const; + bool is_empty() const; + + JsonValue const& at(size_t index) const; + JsonValue const& operator[](size_t index) const; + + void clear() { m_values.clear(); } + void append(JsonValue value); + void set(size_t index, JsonValue value); + + template + typename Builder::OutputType serialized() const; + + template + void serialize(Builder&) const; + + String to_string() const { return serialized(); } + + template + void for_each(Callback callback) const; + + Vector const& values(); + + void ensure_capacity(size_t capacity); + +private: + Vector m_values; +}; + +} + +using AK::JsonArray; diff --git a/AK/AK/JsonObject.h b/LibC-Shim/AK/JsonObject.h similarity index 87% rename from AK/AK/JsonObject.h rename to LibC-Shim/AK/JsonObject.h index a50087d..c3fc045 100644 --- a/AK/AK/JsonObject.h +++ b/LibC-Shim/AK/JsonObject.h @@ -1,73 +1,73 @@ -#pragma once - -#include "./AK/HashMap.h" -#include "./AK/JsonArray.h" -#include "./AK/JsonObjectSerializer.h" -#include "./AK/JsonValue.h" -#include "./AK/String.h" - - -namespace AK { - -class JsonObject { -public: - JsonObject() = default; - ~JsonObject() = default; - - JsonObject(JsonObject const& other) - : m_members(other.m_members) - { - } - - JsonObject(JsonObject&& other) - : m_members(move(other.m_members)) - { - } - - JsonObject& operator=(JsonObject const& other); - - JsonObject& operator=(JsonObject&& other); - - size_t size() const; - bool is_empty() const; - - JsonValue const& get(StringView key) const; - - JsonValue const* get_ptr(StringView key) const; - - bool has(StringView key) const; - - bool has_null(StringView key) const; - bool has_bool(StringView key) const; - bool has_string(StringView key) const; - bool has_i32(StringView key) const; - bool has_u32(StringView key) const; - bool has_i64(StringView key) const; - bool has_u64(StringView key) const; - bool has_number(StringView key) const; - bool has_array(StringView key) const; - bool has_object(StringView key) const; - bool has_double(StringView key) const; - - void set(String const& key, JsonValue value); - - template - void for_each_member(Callback callback) const; - - bool remove(StringView key); - - template - typename Builder::OutputType serialized() const; - - template - void serialize(Builder&) const; - - String to_string() const { return serialized(); } - -private: - OrderedHashMap m_members; -}; - -} - -using AK::JsonObject; +#pragma once + +#include "HashMap.h" +#include "JsonArray.h" +#include "JsonObjectSerializer.h" +#include "JsonValue.h" +#include "String.h" + + +namespace AK { + +class JsonObject { +public: + JsonObject() = default; + ~JsonObject() = default; + + JsonObject(JsonObject const& other) + : m_members(other.m_members) + { + } + + JsonObject(JsonObject&& other) + : m_members(move(other.m_members)) + { + } + + JsonObject& operator=(JsonObject const& other); + + JsonObject& operator=(JsonObject&& other); + + size_t size() const; + bool is_empty() const; + + JsonValue const& get(StringView key) const; + + JsonValue const* get_ptr(StringView key) const; + + bool has(StringView key) const; + + bool has_null(StringView key) const; + bool has_bool(StringView key) const; + bool has_string(StringView key) const; + bool has_i32(StringView key) const; + bool has_u32(StringView key) const; + bool has_i64(StringView key) const; + bool has_u64(StringView key) const; + bool has_number(StringView key) const; + bool has_array(StringView key) const; + bool has_object(StringView key) const; + bool has_double(StringView key) const; + + void set(String const& key, JsonValue value); + + template + void for_each_member(Callback callback) const; + + bool remove(StringView key); + + template + typename Builder::OutputType serialized() const; + + template + void serialize(Builder&) const; + + String to_string() const { return serialized(); } + +private: + OrderedHashMap m_members; +}; + +} + +using AK::JsonObject; diff --git a/AK/AK/JsonObjectSerializer.h b/LibC-Shim/AK/JsonObjectSerializer.h similarity index 92% rename from AK/AK/JsonObjectSerializer.h rename to LibC-Shim/AK/JsonObjectSerializer.h index 50e9667..6f70f09 100644 --- a/AK/AK/JsonObjectSerializer.h +++ b/LibC-Shim/AK/JsonObjectSerializer.h @@ -1 +1 @@ -#pragma once +#pragma once diff --git a/AK/AK/JsonParser.cpp b/LibC-Shim/AK/JsonParser.cpp similarity index 95% rename from AK/AK/JsonParser.cpp rename to LibC-Shim/AK/JsonParser.cpp index deeeaf6..e3035ff 100644 --- a/AK/AK/JsonParser.cpp +++ b/LibC-Shim/AK/JsonParser.cpp @@ -1,2 +1,2 @@ -#include "pch.h" -#include "JsonParser.h" +#include "pch.h" +#include "JsonParser.h" diff --git a/AK/AK/JsonParser.h b/LibC-Shim/AK/JsonParser.h similarity index 88% rename from AK/AK/JsonParser.h rename to LibC-Shim/AK/JsonParser.h index cadb243..9aef014 100644 --- a/AK/AK/JsonParser.h +++ b/LibC-Shim/AK/JsonParser.h @@ -1,38 +1,38 @@ -/* - * Copyright (c) 2018-2020, Andreas Kling - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include "./AK/GenericLexer.h" -#include "./AK/JsonValue.h" - -namespace AK { - -class JsonParser : private GenericLexer { -public: - explicit JsonParser(StringView input) - : GenericLexer(input) - { - } - - ErrorOr parse(); - -private: - ErrorOr parse_helper(); - - ErrorOr consume_and_unescape_string(); - ErrorOr parse_array(); - ErrorOr parse_object(); - ErrorOr parse_number(); - ErrorOr parse_string(); - ErrorOr parse_false(); - ErrorOr parse_true(); - ErrorOr parse_null(); -}; - -} - -using AK::JsonParser; +/* + * Copyright (c) 2018-2020, Andreas Kling + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include "GenericLexer.h" +#include "JsonValue.h" + +namespace AK { + +class JsonParser : private GenericLexer { +public: + explicit JsonParser(StringView input) + : GenericLexer(input) + { + } + + ErrorOr parse(); + +private: + ErrorOr parse_helper(); + + ErrorOr consume_and_unescape_string(); + ErrorOr parse_array(); + ErrorOr parse_object(); + ErrorOr parse_number(); + ErrorOr parse_string(); + ErrorOr parse_false(); + ErrorOr parse_true(); + ErrorOr parse_null(); +}; + +} + +using AK::JsonParser; diff --git a/AK/AK/JsonValue.h b/LibC-Shim/AK/JsonValue.h similarity index 94% rename from AK/AK/JsonValue.h rename to LibC-Shim/AK/JsonValue.h index 1ba7e3a..11df2c2 100644 --- a/AK/AK/JsonValue.h +++ b/LibC-Shim/AK/JsonValue.h @@ -1,251 +1,251 @@ -/* - * Copyright (c) 2018-2020, Andreas Kling - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include "./AK/Forward.h" -#include "./AK/Optional.h" -#include "./AK/StringBuilder.h" -#include "./AK/String.h" - -namespace AK { - -class JsonValue { -public: - enum class Type { - Null, - Int32, - UnsignedInt32, - Int64, - UnsignedInt64, - Double, - Bool, - String, - Array, - Object, - }; - - static ErrorOr from_string(StringView); - - explicit JsonValue(Type = Type::Null); - ~JsonValue() { clear(); } - - JsonValue(JsonValue const&); - JsonValue(JsonValue&&); - - JsonValue& operator=(JsonValue const&); - JsonValue& operator=(JsonValue&&); - - JsonValue(int); - JsonValue(unsigned); - JsonValue(long); - JsonValue(long unsigned); - JsonValue(long long); - JsonValue(long long unsigned); - - JsonValue(double); - JsonValue(bool); - JsonValue(char const*); - JsonValue(String const&); - JsonValue(StringView); - JsonValue(JsonArray const&); - JsonValue(JsonObject const&); - - JsonValue(JsonArray&&); - JsonValue(JsonObject&&); - - // FIXME: Implement these - JsonValue& operator=(JsonArray&&) = delete; - JsonValue& operator=(JsonObject&&) = delete; - - template - typename Builder::OutputType serialized() const; - template - void serialize(Builder&) const; - - String as_string_or(String const& alternative) const - { - if (is_string()) - return as_string(); - return alternative; - } - - String to_string() const - { - if (is_string()) - return as_string(); - return serialized(); - } - - int to_int(int default_value = 0) const - { - return to_i32(default_value); - } - i32 to_i32(i32 default_value = 0) const { return to_number(default_value); } - i64 to_i64(i64 default_value = 0) const { return to_number(default_value); } - - unsigned to_uint(unsigned default_value = 0) const { return to_u32(default_value); } - u32 to_u32(u32 default_value = 0) const { return to_number(default_value); } - u64 to_u64(u64 default_value = 0) const { return to_number(default_value); } - float to_float(float default_value = 0) const - { - return to_number(default_value); - } - double to_double(double default_value = 0) const { return to_number(default_value); } - - FlatPtr to_addr(FlatPtr default_value = 0) const - { -#if defined(AK_ARCH_X86_64) || defined(AK_ARCH_AARCH64) - return to_u64(default_value); -#else - return to_u32(default_value); -#endif - } - - bool to_bool(bool default_value = false) const - { - if (!is_bool()) - return default_value; - return as_bool(); - } - - i32 as_i32() const - { - VERIFY(is_i32()); - return m_value.as_i32; - } - - u32 as_u32() const - { - VERIFY(is_u32()); - return m_value.as_u32; - } - - i64 as_i64() const - { - VERIFY(is_i64()); - return m_value.as_i64; - } - - u64 as_u64() const - { - VERIFY(is_u64()); - return m_value.as_u64; - } - - bool as_bool() const - { - VERIFY(is_bool()); - return m_value.as_bool; - } - - String as_string() const - { - VERIFY(is_string()); - return *m_value.as_string; - } - - JsonObject const& as_object() const - { - VERIFY(is_object()); - return *m_value.as_object; - } - - JsonArray const& as_array() const - { - VERIFY(is_array()); - return *m_value.as_array; - } - - double as_double() const - { - VERIFY(is_double()); - return m_value.as_double; - } - - Type type() const - { - return m_type; - } - - bool is_null() const { return m_type == Type::Null; } - bool is_bool() const { return m_type == Type::Bool; } - bool is_string() const { return m_type == Type::String; } - bool is_i32() const { return m_type == Type::Int32; } - bool is_u32() const { return m_type == Type::UnsignedInt32; } - bool is_i64() const { return m_type == Type::Int64; } - bool is_u64() const { return m_type == Type::UnsignedInt64; } - bool is_double() const - { - return m_type == Type::Double; - } - bool is_array() const - { - return m_type == Type::Array; - } - bool is_object() const { return m_type == Type::Object; } - bool is_number() const - { - switch (m_type) { - case Type::Int32: - case Type::UnsignedInt32: - case Type::Int64: - case Type::UnsignedInt64: - case Type::Double: - return true; - default: - return false; - } - } - - template - T to_number(T default_value = 0) const - { - if (is_double()) - return (T)as_double(); - if (type() == Type::Int32) - return (T)as_i32(); - if (type() == Type::UnsignedInt32) - return (T)as_u32(); - if (type() == Type::Int64) - return (T)as_i64(); - if (type() == Type::UnsignedInt64) - return (T)as_u64(); - return default_value; - } - - bool equals(JsonValue const& other) const; - -private: - void clear(); - void copy_from(JsonValue const&); - - Type m_type { Type::Null }; - - union { - StringImpl* as_string { nullptr }; - JsonArray* as_array; - JsonObject* as_object; - double as_double; - i32 as_i32; - u32 as_u32; - i64 as_i64; - u64 as_u64; - bool as_bool; - } m_value; -}; - -template<> -struct Formatter : Formatter { - ErrorOr format(FormatBuilder& builder, JsonValue const& value) - { - return Formatter::format(builder, value.to_string()); - } -}; - -} - -using AK::JsonValue; +/* + * Copyright (c) 2018-2020, Andreas Kling + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include "Forward.h" +#include "Optional.h" +#include "StringBuilder.h" +#include "String.h" + +namespace AK { + +class JsonValue { +public: + enum class Type { + Null, + Int32, + UnsignedInt32, + Int64, + UnsignedInt64, + Double, + Bool, + String, + Array, + Object, + }; + + static ErrorOr from_string(StringView); + + explicit JsonValue(Type = Type::Null); + ~JsonValue() { clear(); } + + JsonValue(JsonValue const&); + JsonValue(JsonValue&&); + + JsonValue& operator=(JsonValue const&); + JsonValue& operator=(JsonValue&&); + + JsonValue(int); + JsonValue(unsigned); + JsonValue(long); + JsonValue(long unsigned); + JsonValue(long long); + JsonValue(long long unsigned); + + JsonValue(double); + JsonValue(bool); + JsonValue(char const*); + JsonValue(String const&); + JsonValue(StringView); + JsonValue(JsonArray const&); + JsonValue(JsonObject const&); + + JsonValue(JsonArray&&); + JsonValue(JsonObject&&); + + // FIXME: Implement these + JsonValue& operator=(JsonArray&&) = delete; + JsonValue& operator=(JsonObject&&) = delete; + + template + typename Builder::OutputType serialized() const; + template + void serialize(Builder&) const; + + String as_string_or(String const& alternative) const + { + if (is_string()) + return as_string(); + return alternative; + } + + String to_string() const + { + if (is_string()) + return as_string(); + return serialized(); + } + + int to_int(int default_value = 0) const + { + return to_i32(default_value); + } + i32 to_i32(i32 default_value = 0) const { return to_number(default_value); } + i64 to_i64(i64 default_value = 0) const { return to_number(default_value); } + + unsigned to_uint(unsigned default_value = 0) const { return to_u32(default_value); } + u32 to_u32(u32 default_value = 0) const { return to_number(default_value); } + u64 to_u64(u64 default_value = 0) const { return to_number(default_value); } + float to_float(float default_value = 0) const + { + return to_number(default_value); + } + double to_double(double default_value = 0) const { return to_number(default_value); } + + FlatPtr to_addr(FlatPtr default_value = 0) const + { +#if defined(AK_ARCH_X86_64) || defined(AK_ARCH_AARCH64) + return to_u64(default_value); +#else + return to_u32(default_value); +#endif + } + + bool to_bool(bool default_value = false) const + { + if (!is_bool()) + return default_value; + return as_bool(); + } + + i32 as_i32() const + { + VERIFY(is_i32()); + return m_value.as_i32; + } + + u32 as_u32() const + { + VERIFY(is_u32()); + return m_value.as_u32; + } + + i64 as_i64() const + { + VERIFY(is_i64()); + return m_value.as_i64; + } + + u64 as_u64() const + { + VERIFY(is_u64()); + return m_value.as_u64; + } + + bool as_bool() const + { + VERIFY(is_bool()); + return m_value.as_bool; + } + + String as_string() const + { + VERIFY(is_string()); + return *m_value.as_string; + } + + JsonObject const& as_object() const + { + VERIFY(is_object()); + return *m_value.as_object; + } + + JsonArray const& as_array() const + { + VERIFY(is_array()); + return *m_value.as_array; + } + + double as_double() const + { + VERIFY(is_double()); + return m_value.as_double; + } + + Type type() const + { + return m_type; + } + + bool is_null() const { return m_type == Type::Null; } + bool is_bool() const { return m_type == Type::Bool; } + bool is_string() const { return m_type == Type::String; } + bool is_i32() const { return m_type == Type::Int32; } + bool is_u32() const { return m_type == Type::UnsignedInt32; } + bool is_i64() const { return m_type == Type::Int64; } + bool is_u64() const { return m_type == Type::UnsignedInt64; } + bool is_double() const + { + return m_type == Type::Double; + } + bool is_array() const + { + return m_type == Type::Array; + } + bool is_object() const { return m_type == Type::Object; } + bool is_number() const + { + switch (m_type) { + case Type::Int32: + case Type::UnsignedInt32: + case Type::Int64: + case Type::UnsignedInt64: + case Type::Double: + return true; + default: + return false; + } + } + + template + T to_number(T default_value = 0) const + { + if (is_double()) + return (T)as_double(); + if (type() == Type::Int32) + return (T)as_i32(); + if (type() == Type::UnsignedInt32) + return (T)as_u32(); + if (type() == Type::Int64) + return (T)as_i64(); + if (type() == Type::UnsignedInt64) + return (T)as_u64(); + return default_value; + } + + bool equals(JsonValue const& other) const; + +private: + void clear(); + void copy_from(JsonValue const&); + + Type m_type { Type::Null }; + + union { + StringImpl* as_string { nullptr }; + JsonArray* as_array; + JsonObject* as_object; + double as_double; + i32 as_i32; + u32 as_u32; + i64 as_i64; + u64 as_u64; + bool as_bool; + } m_value; +}; + +template<> +struct Formatter : Formatter { + ErrorOr format(FormatBuilder& builder, JsonValue const& value) + { + return Formatter::format(builder, value.to_string()); + } +}; + +} + +using AK::JsonValue; diff --git a/AK/AK/LexicalPath.cpp b/LibC-Shim/AK/LexicalPath.cpp similarity index 100% rename from AK/AK/LexicalPath.cpp rename to LibC-Shim/AK/LexicalPath.cpp diff --git a/AK/AK/LexicalPath.h b/LibC-Shim/AK/LexicalPath.h similarity index 93% rename from AK/AK/LexicalPath.h rename to LibC-Shim/AK/LexicalPath.h index be60aec..43c9355 100644 --- a/AK/AK/LexicalPath.h +++ b/LibC-Shim/AK/LexicalPath.h @@ -1,70 +1,70 @@ -/* - * Copyright (c) 2018-2020, Andreas Kling - * Copyright (c) 2021, Max Wipfli - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include "./AK/String.h" -#include "./AK/Vector.h" - -namespace AK { - -class LexicalPath { -public: - explicit LexicalPath(String); - - bool is_absolute() const { return !m_string.is_empty() && m_string[0] == '/'; } - String const& string() const { return m_string; } - - StringView dirname() const { return m_dirname; } - StringView basename() const { return m_basename; } - StringView title() const { return m_title; } - StringView extension() const { return m_extension; } - - Vector const& parts_view() const { return m_parts; } - Vector parts() const; - - bool has_extension(StringView) const; - - LexicalPath append(StringView) const; - LexicalPath prepend(StringView) const; - LexicalPath parent() const; - - static String canonicalized_path(String); - static String absolute_path(String dir_path, String target); - static String relative_path(StringView absolute_path, StringView prefix); - - template - static LexicalPath join(StringView first, S&&... rest); - - static String dirname(String path); - - static String basename(String path); - - static String title(String path); - - static String extension(String path); - -private: - Vector m_parts; - String m_string; - StringView m_dirname; - StringView m_basename; - StringView m_title; - StringView m_extension; -}; - -template<> -struct Formatter : Formatter { - ErrorOr format(FormatBuilder& builder, LexicalPath const& value) - { - return Formatter::format(builder, value.string()); - } -}; - -}; - -using AK::LexicalPath; +/* + * Copyright (c) 2018-2020, Andreas Kling + * Copyright (c) 2021, Max Wipfli + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include "String.h" +#include "Vector.h" + +namespace AK { + +class LexicalPath { +public: + explicit LexicalPath(String); + + bool is_absolute() const { return !m_string.is_empty() && m_string[0] == '/'; } + String const& string() const { return m_string; } + + StringView dirname() const { return m_dirname; } + StringView basename() const { return m_basename; } + StringView title() const { return m_title; } + StringView extension() const { return m_extension; } + + Vector const& parts_view() const { return m_parts; } + Vector parts() const; + + bool has_extension(StringView) const; + + LexicalPath append(StringView) const; + LexicalPath prepend(StringView) const; + LexicalPath parent() const; + + static String canonicalized_path(String); + static String absolute_path(String dir_path, String target); + static String relative_path(StringView absolute_path, StringView prefix); + + template + static LexicalPath join(StringView first, S&&... rest); + + static String dirname(String path); + + static String basename(String path); + + static String title(String path); + + static String extension(String path); + +private: + Vector m_parts; + String m_string; + StringView m_dirname; + StringView m_basename; + StringView m_title; + StringView m_extension; +}; + +template<> +struct Formatter : Formatter { + ErrorOr format(FormatBuilder& builder, LexicalPath const& value) + { + return Formatter::format(builder, value.string()); + } +}; + +}; + +using AK::LexicalPath; diff --git a/AK/AK/Math.h b/LibC-Shim/AK/Math.h similarity index 78% rename from AK/AK/Math.h rename to LibC-Shim/AK/Math.h index 1745cff..8563231 100644 --- a/AK/AK/Math.h +++ b/LibC-Shim/AK/Math.h @@ -1,36 +1,36 @@ -#pragma once - -#include "./AK/BuiltinWrappers.h" -#include "./AK/Concepts.h" -#include "./AK/NumericLimits.h" -#include "./AK/StdLibExtraDetails.h" -#include "./AK/Types.h" - -namespace AK { - -//template -//constexpr T NaN = __builtin_nan(""); -template -constexpr T Pi = 3.141592653589793238462643383279502884L; -template -constexpr T E = 2.718281828459045235360287471352662498L; -template -constexpr T Sqrt2 = 1.414213562373095048801688724209698079L; -template -constexpr T Sqrt1_2 = 0.707106781186547524400844362104849039L; - -template -ALWAYS_INLINE I round_to(float value); - -template -constexpr T hypot(T x, T y); - -template -constexpr T exp2(T exponent) -{ - return __builtin_exp2(exponent); -}; - -} - -using AK::round_to; +#pragma once + +#include "BuiltinWrappers.h" +#include "Concepts.h" +#include "NumericLimits.h" +#include "StdLibExtraDetails.h" +#include "Types.h" + +namespace AK { + +//template +//constexpr T NaN = __builtin_nan(""); +template +constexpr T Pi = 3.141592653589793238462643383279502884L; +template +constexpr T E = 2.718281828459045235360287471352662498L; +template +constexpr T Sqrt2 = 1.414213562373095048801688724209698079L; +template +constexpr T Sqrt1_2 = 0.707106781186547524400844362104849039L; + +template +ALWAYS_INLINE I round_to(float value); + +template +constexpr T hypot(T x, T y); + +template +constexpr T exp2(T exponent) +{ + return __builtin_exp2(exponent); +}; + +} + +using AK::round_to; diff --git a/AK/AK/MemMem.h b/LibC-Shim/AK/MemMem.h similarity index 83% rename from AK/AK/MemMem.h rename to LibC-Shim/AK/MemMem.h index 51c6273..d213de3 100644 --- a/AK/AK/MemMem.h +++ b/LibC-Shim/AK/MemMem.h @@ -1,31 +1,31 @@ -/* - * Copyright (c) 2020-2022, the SerenityOS developers. - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include "./AK/Array.h" -#include "./AK/Assertions.h" -#include "./AK/Span.h" -#include "./AK/Types.h" -#include "./AK/Vector.h" - -namespace AK { - -namespace Detail { - -constexpr void const* bitap_bitwise(void const* haystack, size_t haystack_length, void const* needle, size_t needle_length); - -} - -template -ALWAYS_INLINE Optional memmem(HaystackIterT const& haystack_begin, HaystackIterT const& haystack_end, Span needle) requires(requires { (*haystack_begin).data(); (*haystack_begin).size(); }); - -ALWAYS_INLINE Optional memmem_optional(void const* haystack, size_t haystack_length, void const* needle, size_t needle_length); - -ALWAYS_INLINE void const* memmem(void const* haystack, size_t haystack_length, void const* needle, size_t needle_length); - -} - +/* + * Copyright (c) 2020-2022, the SerenityOS developers. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include "Array.h" +#include "Assertions.h" +#include "Span.h" +#include "Types.h" +#include "Vector.h" + +namespace AK { + +namespace Detail { + +constexpr void const* bitap_bitwise(void const* haystack, size_t haystack_length, void const* needle, size_t needle_length); + +} + +template +ALWAYS_INLINE Optional memmem(HaystackIterT const& haystack_begin, HaystackIterT const& haystack_end, Span needle) requires(requires { (*haystack_begin).data(); (*haystack_begin).size(); }); + +ALWAYS_INLINE Optional memmem_optional(void const* haystack, size_t haystack_length, void const* needle, size_t needle_length); + +ALWAYS_INLINE void const* memmem(void const* haystack, size_t haystack_length, void const* needle, size_t needle_length); + +} + diff --git a/AK/AK/Memory.h b/LibC-Shim/AK/Memory.h similarity index 85% rename from AK/AK/Memory.h rename to LibC-Shim/AK/Memory.h index 4b56e15..e63be6f 100644 --- a/AK/AK/Memory.h +++ b/LibC-Shim/AK/Memory.h @@ -1,10 +1,10 @@ -/* - * Copyright (c) 2020, Andreas Kling - * Copyright (c) 2021-2022, Brian Gianforcaro - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include "./AK/Types.h" \ No newline at end of file +/* + * Copyright (c) 2020, Andreas Kling + * Copyright (c) 2021-2022, Brian Gianforcaro + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include "Types.h" diff --git a/AK/AK/Noncopyable.h b/LibC-Shim/AK/Noncopyable.h similarity index 95% rename from AK/AK/Noncopyable.h rename to LibC-Shim/AK/Noncopyable.h index b585071..6463865 100644 --- a/AK/AK/Noncopyable.h +++ b/LibC-Shim/AK/Noncopyable.h @@ -1,17 +1,17 @@ -/* - * Copyright (c) 2018-2020, Andreas Kling - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#define AK_MAKE_NONCOPYABLE(c) \ -private: \ - c(c const&) = delete; \ - c& operator=(c const&) = delete - -#define AK_MAKE_NONMOVABLE(c) \ -private: \ - c(c&&) = delete; \ - c& operator=(c&&) = delete +/* + * Copyright (c) 2018-2020, Andreas Kling + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#define AK_MAKE_NONCOPYABLE(c) \ +private: \ + c(c const&) = delete; \ + c& operator=(c const&) = delete + +#define AK_MAKE_NONMOVABLE(c) \ +private: \ + c(c&&) = delete; \ + c& operator=(c&&) = delete diff --git a/AK/AK/NonnullOwnPtr.h b/LibC-Shim/AK/NonnullOwnPtr.h similarity index 91% rename from AK/AK/NonnullOwnPtr.h rename to LibC-Shim/AK/NonnullOwnPtr.h index ba18b2b..e0aa8ed 100644 --- a/AK/AK/NonnullOwnPtr.h +++ b/LibC-Shim/AK/NonnullOwnPtr.h @@ -1,124 +1,124 @@ -#pragma once - -#include "./AK/Assertions.h" -#include "./AK/Format.h" -#include "./AK/RefCounted.h" -#include "./AK/StdLibExtras.h" -#include "./AK/Traits.h" -#include "./AK/Types.h" - -namespace AK { - -template -class WeakPtr; - -template -class NonnullOwnPtr { -public: - using ElementType = T; - - enum AdoptTag { Adopt }; - - // FIXME: this shouldn't exist - NonnullOwnPtr() - { - } - - NonnullOwnPtr(AdoptTag, T& ptr) - : m_ptr(&ptr) - { - } - NonnullOwnPtr(NonnullOwnPtr&& other) - : m_ptr(other.leak_ptr()) - { - } - template - NonnullOwnPtr(NonnullOwnPtr&& other) - : m_ptr(other.leak_ptr()) - { - } - - T* leak_ptr(); - ALWAYS_INLINE T* ptr(); - - NonnullOwnPtr(NonnullOwnPtr const&) = delete; - template - NonnullOwnPtr(NonnullOwnPtr const&) = delete; - NonnullOwnPtr& operator=(NonnullOwnPtr const&) = delete; - template - NonnullOwnPtr& operator=(NonnullOwnPtr const&) = delete; - - template - NonnullOwnPtr(RefPtr const&) = delete; - template - NonnullOwnPtr(NonnullRefPtr const&) = delete; - template - NonnullOwnPtr(WeakPtr const&) = delete; - template - NonnullOwnPtr& operator=(RefPtr const&) = delete; - template - NonnullOwnPtr& operator=(NonnullRefPtr const&) = delete; - template - NonnullOwnPtr& operator=(WeakPtr const&) = delete; - - ALWAYS_INLINE T* operator->(); - ALWAYS_INLINE const T* operator->() const; - - ALWAYS_INLINE T& operator*(); - ALWAYS_INLINE const T& operator*() const; - - ALWAYS_INLINE operator const T* () const; - ALWAYS_INLINE operator T* (); - - operator bool() const = delete; - bool operator!() const = delete; - -private: - T* m_ptr = nullptr; -}; - -template -ALWAYS_INLINE NonnullOwnPtr adopt_own(T& object) -{ - return NonnullOwnPtr(NonnullOwnPtr::Adopt, object); -} - -template - requires(IsConstructible) ALWAYS_INLINE NonnullOwnPtr make(Args&&... args) -{ - return NonnullOwnPtr(NonnullOwnPtr::Adopt, *new T(forward(args)...)); -} - -template -ALWAYS_INLINE NonnullOwnPtr make(Args&&... args) -{ - return NonnullOwnPtr(NonnullOwnPtr::Adopt, *new T{ forward(args)... }); -} - -template -struct Traits> : public GenericTraits> { - using PeekType = T*; - using ConstPeekType = const T*; - static unsigned hash(NonnullOwnPtr const& p) { return ptr_hash((FlatPtr)p.ptr()); } - static bool equals(NonnullOwnPtr const& a, NonnullOwnPtr const& b) { return a.ptr() == b.ptr(); } -}; - -template -ALWAYS_INLINE void swap(NonnullOwnPtr& a, NonnullOwnPtr& b) -{ - a.swap(b); -} - -template -struct Formatter> : Formatter { - ErrorOr format(FormatBuilder& builder, NonnullOwnPtr const& value) - { - return Formatter::format(builder, value.ptr()); - } -}; - -} - -using AK::adopt_own; -using AK::make; -using AK::NonnullOwnPtr; +#pragma once + +#include "Assertions.h" +#include "Format.h" +#include "RefCounted.h" +#include "StdLibExtras.h" +#include "Traits.h" +#include "Types.h" + +namespace AK { + +template +class WeakPtr; + +template +class NonnullOwnPtr { +public: + using ElementType = T; + + enum AdoptTag { Adopt }; + + // FIXME: this shouldn't exist + NonnullOwnPtr() + { + } + + NonnullOwnPtr(AdoptTag, T& ptr) + : m_ptr(&ptr) + { + } + NonnullOwnPtr(NonnullOwnPtr&& other) + : m_ptr(other.leak_ptr()) + { + } + template + NonnullOwnPtr(NonnullOwnPtr&& other) + : m_ptr(other.leak_ptr()) + { + } + + T* leak_ptr(); + ALWAYS_INLINE T* ptr(); + + NonnullOwnPtr(NonnullOwnPtr const&) = delete; + template + NonnullOwnPtr(NonnullOwnPtr const&) = delete; + NonnullOwnPtr& operator=(NonnullOwnPtr const&) = delete; + template + NonnullOwnPtr& operator=(NonnullOwnPtr const&) = delete; + + template + NonnullOwnPtr(RefPtr const&) = delete; + template + NonnullOwnPtr(NonnullRefPtr const&) = delete; + template + NonnullOwnPtr(WeakPtr const&) = delete; + template + NonnullOwnPtr& operator=(RefPtr const&) = delete; + template + NonnullOwnPtr& operator=(NonnullRefPtr const&) = delete; + template + NonnullOwnPtr& operator=(WeakPtr const&) = delete; + + ALWAYS_INLINE T* operator->(); + ALWAYS_INLINE const T* operator->() const; + + ALWAYS_INLINE T& operator*(); + ALWAYS_INLINE const T& operator*() const; + + ALWAYS_INLINE operator const T* () const; + ALWAYS_INLINE operator T* (); + + operator bool() const = delete; + bool operator!() const = delete; + +private: + T* m_ptr = nullptr; +}; + +template +ALWAYS_INLINE NonnullOwnPtr adopt_own(T& object) +{ + return NonnullOwnPtr(NonnullOwnPtr::Adopt, object); +} + +template + requires(IsConstructible) ALWAYS_INLINE NonnullOwnPtr make(Args&&... args) +{ + return NonnullOwnPtr(NonnullOwnPtr::Adopt, *new T(forward(args)...)); +} + +template +ALWAYS_INLINE NonnullOwnPtr make(Args&&... args) +{ + return NonnullOwnPtr(NonnullOwnPtr::Adopt, *new T{ forward(args)... }); +} + +template +struct Traits> : public GenericTraits> { + using PeekType = T*; + using ConstPeekType = const T*; + static unsigned hash(NonnullOwnPtr const& p) { return ptr_hash((FlatPtr)p.ptr()); } + static bool equals(NonnullOwnPtr const& a, NonnullOwnPtr const& b) { return a.ptr() == b.ptr(); } +}; + +template +ALWAYS_INLINE void swap(NonnullOwnPtr& a, NonnullOwnPtr& b) +{ + a.swap(b); +} + +template +struct Formatter> : Formatter { + ErrorOr format(FormatBuilder& builder, NonnullOwnPtr const& value) + { + return Formatter::format(builder, value.ptr()); + } +}; + +} + +using AK::adopt_own; +using AK::make; +using AK::NonnullOwnPtr; diff --git a/AK/AK/NonnullOwnPtrVector.h b/LibC-Shim/AK/NonnullOwnPtrVector.h similarity index 78% rename from AK/AK/NonnullOwnPtrVector.h rename to LibC-Shim/AK/NonnullOwnPtrVector.h index 13d7cff..2c5ef24 100644 --- a/AK/AK/NonnullOwnPtrVector.h +++ b/LibC-Shim/AK/NonnullOwnPtrVector.h @@ -1,20 +1,20 @@ -/* - * Copyright (c) 2018-2020, Andreas Kling - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include "./AK/NonnullOwnPtr.h" -#include "./AK/NonnullPtrVector.h" - -namespace AK { - -template -class NonnullOwnPtrVector : public NonnullPtrVector, inline_capacity> { -}; - -} - -using AK::NonnullOwnPtrVector; +/* + * Copyright (c) 2018-2020, Andreas Kling + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include "NonnullOwnPtr.h" +#include "NonnullPtrVector.h" + +namespace AK { + +template +class NonnullOwnPtrVector : public NonnullPtrVector, inline_capacity> { +}; + +} + +using AK::NonnullOwnPtrVector; diff --git a/AK/AK/NonnullPtrVector.h b/LibC-Shim/AK/NonnullPtrVector.h similarity index 94% rename from AK/AK/NonnullPtrVector.h rename to LibC-Shim/AK/NonnullPtrVector.h index 4213e5a..257aa1d 100644 --- a/AK/AK/NonnullPtrVector.h +++ b/LibC-Shim/AK/NonnullPtrVector.h @@ -1,71 +1,71 @@ -/* - * Copyright (c) 2018-2021, Andreas Kling - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include "./AK/Vector.h" -#include "./AK/NonnullPtrVector.h" - -namespace AK { - -template -class NonnullPtrVector : public Vector { - using T = typename PtrType::ElementType; - using Base = Vector; - -public: - NonnullPtrVector() = default; - - NonnullPtrVector(Vector&& other) - : Base(static_cast(other)) - { - } - NonnullPtrVector(Vector const& other) - : Base(static_cast(other)) - { - } - - using Base::size; - - using ConstIterator = SimpleIterator; - using Iterator = SimpleIterator; - using ReverseIterator = SimpleReverseIterator; - using ReverseConstIterator = SimpleReverseIterator; - - ALWAYS_INLINE constexpr ConstIterator begin() const; - ALWAYS_INLINE constexpr Iterator begin(); - ALWAYS_INLINE constexpr ReverseIterator rbegin(); - ALWAYS_INLINE constexpr ReverseConstIterator rbegin() const; - - ALWAYS_INLINE constexpr ConstIterator end() const; - ALWAYS_INLINE constexpr Iterator end(); - ALWAYS_INLINE constexpr ReverseIterator rend(); - ALWAYS_INLINE constexpr ReverseConstIterator rend() const; - - ALWAYS_INLINE constexpr auto in_reverse(); - - Optional find_first_index(T const& value) const; - - ALWAYS_INLINE PtrType& ptr_at(size_t index); - ALWAYS_INLINE PtrType const& ptr_at(size_t index) const { return Base::at(index); } - - ALWAYS_INLINE T& at(size_t index) { return *Base::at(index); } - ALWAYS_INLINE const T& at(size_t index) const { return *Base::at(index); } - ALWAYS_INLINE T& operator[](size_t index) { return at(index); } - ALWAYS_INLINE const T& operator[](size_t index) const { return at(index); } - ALWAYS_INLINE T& first() { return at(0); } - ALWAYS_INLINE const T& first() const { return at(0); } - ALWAYS_INLINE T& last() { return at(size() - 1); } - ALWAYS_INLINE const T& last() const { return at(size() - 1); } - -private: - // NOTE: You can't use resize() on a NonnullFooPtrVector since making the vector - // bigger would require being able to default-construct NonnullFooPtrs. - // Instead, use shrink(new_size). - void resize(size_t) = delete; -}; - -} +/* + * Copyright (c) 2018-2021, Andreas Kling + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include "Vector.h" +#include "NonnullPtrVector.h" + +namespace AK { + +template +class NonnullPtrVector : public Vector { + using T = typename PtrType::ElementType; + using Base = Vector; + +public: + NonnullPtrVector() = default; + + NonnullPtrVector(Vector&& other) + : Base(static_cast(other)) + { + } + NonnullPtrVector(Vector const& other) + : Base(static_cast(other)) + { + } + + using Base::size; + + using ConstIterator = SimpleIterator; + using Iterator = SimpleIterator; + using ReverseIterator = SimpleReverseIterator; + using ReverseConstIterator = SimpleReverseIterator; + + ALWAYS_INLINE constexpr ConstIterator begin() const; + ALWAYS_INLINE constexpr Iterator begin(); + ALWAYS_INLINE constexpr ReverseIterator rbegin(); + ALWAYS_INLINE constexpr ReverseConstIterator rbegin() const; + + ALWAYS_INLINE constexpr ConstIterator end() const; + ALWAYS_INLINE constexpr Iterator end(); + ALWAYS_INLINE constexpr ReverseIterator rend(); + ALWAYS_INLINE constexpr ReverseConstIterator rend() const; + + ALWAYS_INLINE constexpr auto in_reverse(); + + Optional find_first_index(T const& value) const; + + ALWAYS_INLINE PtrType& ptr_at(size_t index); + ALWAYS_INLINE PtrType const& ptr_at(size_t index) const { return Base::at(index); } + + ALWAYS_INLINE T& at(size_t index) { return *Base::at(index); } + ALWAYS_INLINE const T& at(size_t index) const { return *Base::at(index); } + ALWAYS_INLINE T& operator[](size_t index) { return at(index); } + ALWAYS_INLINE const T& operator[](size_t index) const { return at(index); } + ALWAYS_INLINE T& first() { return at(0); } + ALWAYS_INLINE const T& first() const { return at(0); } + ALWAYS_INLINE T& last() { return at(size() - 1); } + ALWAYS_INLINE const T& last() const { return at(size() - 1); } + +private: + // NOTE: You can't use resize() on a NonnullFooPtrVector since making the vector + // bigger would require being able to default-construct NonnullFooPtrs. + // Instead, use shrink(new_size). + void resize(size_t) = delete; +}; + +} diff --git a/AK/AK/NonnullRefPtr.h b/LibC-Shim/AK/NonnullRefPtr.h similarity index 92% rename from AK/AK/NonnullRefPtr.h rename to LibC-Shim/AK/NonnullRefPtr.h index c1929d1..20fb1f0 100644 --- a/AK/AK/NonnullRefPtr.h +++ b/LibC-Shim/AK/NonnullRefPtr.h @@ -1,274 +1,282 @@ -/* - * Copyright (c) 2018-2020, Andreas Kling - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#define NONNULLREFPTR_SCRUB_BYTE 0xe1 - -#include "./AK/Assertions.h" -#include "./AK/Atomic.h" -#include "./AK/Format.h" -#include "./AK/Traits.h" -#include "./AK/Types.h" - -namespace AK { - -template -class OwnPtr; -template -class RefPtr; - -template -ALWAYS_INLINE void ref_if_not_null(T* ptr); - -template -ALWAYS_INLINE void unref_if_not_null(T* ptr); - -template -class NonnullRefPtr { - template - friend class RefPtr; - template - friend class NonnullRefPtr; - template - friend class WeakPtr; - -public: - using ElementType = T; - - enum AdoptTag { Adopt }; - - // FIXME: Don't do this - NonnullRefPtr() - { - } - - ALWAYS_INLINE NonnullRefPtr(T const& object) - : m_ptr(const_cast(&object)) - { - m_ptr->ref(); - } - - template - ALWAYS_INLINE NonnullRefPtr(U const& object) requires(IsConvertible) - : m_ptr(const_cast(static_cast(&object))) - { - m_ptr->ref(); - } - - ALWAYS_INLINE NonnullRefPtr(AdoptTag, T& object) - : m_ptr(&object) - { - } - - ALWAYS_INLINE NonnullRefPtr(NonnullRefPtr&& other) - : m_ptr(&other.leak_ref()) - { - } - - template - ALWAYS_INLINE NonnullRefPtr(NonnullRefPtr&& other) requires(IsConvertible) - : m_ptr(static_cast(&other.leak_ref())) - { - } - - ALWAYS_INLINE NonnullRefPtr(NonnullRefPtr const& other) - : m_ptr(const_cast(other.ptr())) - { - m_ptr->ref(); - } - - template - ALWAYS_INLINE NonnullRefPtr(NonnullRefPtr const& other) requires(IsConvertible) - : m_ptr(const_cast(static_cast(other.ptr()))) - { - m_ptr->ref(); - } - - ALWAYS_INLINE ~NonnullRefPtr() - { - unref_if_not_null(m_ptr); - m_ptr = nullptr; - } - - template - NonnullRefPtr(OwnPtr const&) = delete; - template - NonnullRefPtr& operator=(OwnPtr const&) = delete; - - template - NonnullRefPtr(RefPtr const&) = delete; - template - NonnullRefPtr& operator=(RefPtr const&) = delete; - NonnullRefPtr(RefPtr const&) = delete; - NonnullRefPtr& operator=(RefPtr const&) = delete; - - NonnullRefPtr& operator=(NonnullRefPtr const& other) - { - NonnullRefPtr tmp{ other }; - swap(tmp); - return *this; - } - - template - NonnullRefPtr& operator=(NonnullRefPtr const& other) requires(IsConvertible) - { - NonnullRefPtr tmp{ other }; - swap(tmp); - return *this; - } - - ALWAYS_INLINE NonnullRefPtr& operator=(NonnullRefPtr&& other) - { - NonnullRefPtr tmp{ move(other) }; - swap(tmp); - return *this; - } - - template - NonnullRefPtr& operator=(NonnullRefPtr&& other) requires(IsConvertible) - { - NonnullRefPtr tmp{ move(other) }; - swap(tmp); - return *this; - } - - NonnullRefPtr& operator=(T const& object) - { - NonnullRefPtr tmp{ object }; - swap(tmp); - return *this; - } - - ALWAYS_INLINE T& leak_ref() - { - T* ptr = exchange(m_ptr, nullptr); - VERIFY(ptr); - return *ptr; - } - - ALWAYS_INLINE T* ptr() - { - return as_nonnull_ptr(); - } - ALWAYS_INLINE const T* ptr() const - { - return as_nonnull_ptr(); - } - - ALWAYS_INLINE T* operator->() - { - return as_nonnull_ptr(); - } - ALWAYS_INLINE const T* operator->() const - { - return as_nonnull_ptr(); - } - - ALWAYS_INLINE T& operator*() - { - return *as_nonnull_ptr(); - } - ALWAYS_INLINE const T& operator*() const - { - return *as_nonnull_ptr(); - } - - ALWAYS_INLINE operator T* () - { - return as_nonnull_ptr(); - } - ALWAYS_INLINE operator const T* () const - { - return as_nonnull_ptr(); - } - - ALWAYS_INLINE operator T& () - { - return *as_nonnull_ptr(); - } - ALWAYS_INLINE operator const T& () const - { - return *as_nonnull_ptr(); - } - - operator bool() const = delete; - bool operator!() const = delete; - - void swap(NonnullRefPtr& other) - { - AK::swap(m_ptr, other.m_ptr); - } - - template - void swap(NonnullRefPtr& other) requires(IsConvertible) - { - AK::swap(m_ptr, other.m_ptr); - } - - bool operator==(NonnullRefPtr const& other) const { return m_ptr == other.m_ptr; } - bool operator!=(NonnullRefPtr const& other) const { return m_ptr != other.m_ptr; } - - bool operator==(NonnullRefPtr& other) { return m_ptr == other.m_ptr; } - bool operator!=(NonnullRefPtr& other) { return m_ptr != other.m_ptr; } - -private: - //NonnullRefPtr() = delete; - - ALWAYS_INLINE T* as_nonnull_ptr() const - { - VERIFY(m_ptr); - return m_ptr; - } - - T* m_ptr{ nullptr }; -}; - -template -ALWAYS_INLINE NonnullRefPtr adopt_ref(T& object) -{ - return NonnullRefPtr(NonnullRefPtr::Adopt, object); -} - -template -struct Formatter> : Formatter { - ErrorOr format(FormatBuilder& builder, NonnullRefPtr const& value) - { - return Formatter::format(builder, value.ptr()); - } -}; - -template -ALWAYS_INLINE void swap(NonnullRefPtr& a, NonnullRefPtr& b) requires(IsConvertible) -{ - a.swap(b); -} - -template - requires(IsConstructible) ALWAYS_INLINE NonnullRefPtr make_ref_counted(Args&&... args) -{ - return NonnullRefPtr(NonnullRefPtr::Adopt, *new T(forward(args)...)); -} - -// FIXME: Remove once P0960R3 is available in Clang. -template -ALWAYS_INLINE NonnullRefPtr make_ref_counted(Args&&... args) -{ - return NonnullRefPtr(NonnullRefPtr::Adopt, *new T{ forward(args)... }); -} -} - -template -struct Traits> : public GenericTraits> { - using PeekType = T*; - using ConstPeekType = const T*; - static unsigned hash(NonnullRefPtr const& p) { return ptr_hash(p.ptr()); } - static bool equals(NonnullRefPtr const& a, NonnullRefPtr const& b) { return a.ptr() == b.ptr(); } -}; - -using AK::adopt_ref; -using AK::make_ref_counted; -using AK::NonnullRefPtr; +/* + * Copyright (c) 2018-2020, Andreas Kling + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#define NONNULLREFPTR_SCRUB_BYTE 0xe1 + +#include "Assertions.h" +#include "Atomic.h" +#include "Format.h" +#include "Traits.h" +#include "Types.h" + +namespace AK { + +template +class OwnPtr; +template +class RefPtr; + +template +ALWAYS_INLINE void ref_if_not_null(T* ptr) +{ + // FIXME: Impl this. + VERIFY_NOT_REACHED(); +} + +template +ALWAYS_INLINE void unref_if_not_null(T* ptr) +{ + // FIXME: Impl this. + VERIFY_NOT_REACHED(); +} + +template +class NonnullRefPtr { + template + friend class RefPtr; + template + friend class NonnullRefPtr; + template + friend class WeakPtr; + +public: + using ElementType = T; + + enum AdoptTag { Adopt }; + + // FIXME: Don't do this + NonnullRefPtr() + { + } + + ALWAYS_INLINE NonnullRefPtr(T const& object) + : m_ptr(const_cast(&object)) + { + m_ptr->ref(); + } + + template + ALWAYS_INLINE NonnullRefPtr(U const& object) requires(IsConvertible) + : m_ptr(const_cast(static_cast(&object))) + { + m_ptr->ref(); + } + + ALWAYS_INLINE NonnullRefPtr(AdoptTag, T& object) + : m_ptr(&object) + { + } + + ALWAYS_INLINE NonnullRefPtr(NonnullRefPtr&& other) + : m_ptr(&other.leak_ref()) + { + } + + template + ALWAYS_INLINE NonnullRefPtr(NonnullRefPtr&& other) requires(IsConvertible) + : m_ptr(static_cast(&other.leak_ref())) + { + } + + ALWAYS_INLINE NonnullRefPtr(NonnullRefPtr const& other) + : m_ptr(const_cast(other.ptr())) + { + m_ptr->ref(); + } + + template + ALWAYS_INLINE NonnullRefPtr(NonnullRefPtr const& other) requires(IsConvertible) + : m_ptr(const_cast(static_cast(other.ptr()))) + { + m_ptr->ref(); + } + + ALWAYS_INLINE ~NonnullRefPtr() + { + unref_if_not_null(m_ptr); + m_ptr = nullptr; + } + + template + NonnullRefPtr(OwnPtr const&) = delete; + template + NonnullRefPtr& operator=(OwnPtr const&) = delete; + + template + NonnullRefPtr(RefPtr const&) = delete; + template + NonnullRefPtr& operator=(RefPtr const&) = delete; + NonnullRefPtr(RefPtr const&) = delete; + NonnullRefPtr& operator=(RefPtr const&) = delete; + + NonnullRefPtr& operator=(NonnullRefPtr const& other) + { + NonnullRefPtr tmp{ other }; + swap(tmp); + return *this; + } + + template + NonnullRefPtr& operator=(NonnullRefPtr const& other) requires(IsConvertible) + { + NonnullRefPtr tmp{ other }; + swap(tmp); + return *this; + } + + ALWAYS_INLINE NonnullRefPtr& operator=(NonnullRefPtr&& other) + { + NonnullRefPtr tmp{ move(other) }; + swap(tmp); + return *this; + } + + template + NonnullRefPtr& operator=(NonnullRefPtr&& other) requires(IsConvertible) + { + NonnullRefPtr tmp{ move(other) }; + swap(tmp); + return *this; + } + + NonnullRefPtr& operator=(T const& object) + { + NonnullRefPtr tmp{ object }; + swap(tmp); + return *this; + } + + ALWAYS_INLINE T& leak_ref() + { + T* ptr = exchange(m_ptr, nullptr); + VERIFY(ptr); + return *ptr; + } + + ALWAYS_INLINE T* ptr() + { + return as_nonnull_ptr(); + } + ALWAYS_INLINE const T* ptr() const + { + return as_nonnull_ptr(); + } + + ALWAYS_INLINE T* operator->() + { + return as_nonnull_ptr(); + } + ALWAYS_INLINE const T* operator->() const + { + return as_nonnull_ptr(); + } + + ALWAYS_INLINE T& operator*() + { + return *as_nonnull_ptr(); + } + ALWAYS_INLINE const T& operator*() const + { + return *as_nonnull_ptr(); + } + + ALWAYS_INLINE operator T* () + { + return as_nonnull_ptr(); + } + ALWAYS_INLINE operator const T* () const + { + return as_nonnull_ptr(); + } + + ALWAYS_INLINE operator T& () + { + return *as_nonnull_ptr(); + } + ALWAYS_INLINE operator const T& () const + { + return *as_nonnull_ptr(); + } + + operator bool() const = delete; + bool operator!() const = delete; + + void swap(NonnullRefPtr& other) + { + AK::swap(m_ptr, other.m_ptr); + } + + template + void swap(NonnullRefPtr& other) requires(IsConvertible) + { + AK::swap(m_ptr, other.m_ptr); + } + + bool operator==(NonnullRefPtr const& other) const { return m_ptr == other.m_ptr; } + bool operator!=(NonnullRefPtr const& other) const { return m_ptr != other.m_ptr; } + + bool operator==(NonnullRefPtr& other) { return m_ptr == other.m_ptr; } + bool operator!=(NonnullRefPtr& other) { return m_ptr != other.m_ptr; } + +private: + //NonnullRefPtr() = delete; + + ALWAYS_INLINE T* as_nonnull_ptr() const + { + VERIFY(m_ptr); + return m_ptr; + } + + T* m_ptr{ nullptr }; +}; + +template +ALWAYS_INLINE NonnullRefPtr adopt_ref(T& object) +{ + return NonnullRefPtr(NonnullRefPtr::Adopt, object); +} + +template +struct Formatter> : Formatter { + ErrorOr format(FormatBuilder& builder, NonnullRefPtr const& value) + { + return Formatter::format(builder, value.ptr()); + } +}; + +template +ALWAYS_INLINE void swap(NonnullRefPtr& a, NonnullRefPtr& b) requires(IsConvertible) +{ + a.swap(b); +} + +template + requires(IsConstructible) ALWAYS_INLINE NonnullRefPtr make_ref_counted(Args&&... args) +{ + return NonnullRefPtr(NonnullRefPtr::Adopt, *new T(forward(args)...)); +} + +// FIXME: Remove once P0960R3 is available in Clang. +template +ALWAYS_INLINE NonnullRefPtr make_ref_counted(Args&&... args) +{ + return NonnullRefPtr(NonnullRefPtr::Adopt, *new T{ forward(args)... }); +} +} + +template +struct Traits> : public GenericTraits> { + using PeekType = T*; + using ConstPeekType = const T*; + static unsigned hash(NonnullRefPtr const& p) { return ptr_hash(p.ptr()); } + static bool equals(NonnullRefPtr const& a, NonnullRefPtr const& b) { return a.ptr() == b.ptr(); } +}; + +using AK::adopt_ref; +using AK::make_ref_counted; +using AK::NonnullRefPtr; diff --git a/AK/AK/NonnullRefPtrVector.h b/LibC-Shim/AK/NonnullRefPtrVector.h similarity index 82% rename from AK/AK/NonnullRefPtrVector.h rename to LibC-Shim/AK/NonnullRefPtrVector.h index b757ec6..baa4e8a 100644 --- a/AK/AK/NonnullRefPtrVector.h +++ b/LibC-Shim/AK/NonnullRefPtrVector.h @@ -1,21 +1,21 @@ -/* - * Copyright (c) 2018-2020, Andreas Kling - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include "./AK/NonnullPtrVector.h" -#include "./AK/NonnullRefPtr.h" - -namespace AK { - -template -class NonnullRefPtrVector : public NonnullPtrVector, inline_capacity> { - using NonnullPtrVector, inline_capacity>::NonnullPtrVector; -}; - -} - -using AK::NonnullRefPtrVector; +/* + * Copyright (c) 2018-2020, Andreas Kling + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include "NonnullPtrVector.h" +#include "NonnullRefPtr.h" + +namespace AK { + +template +class NonnullRefPtrVector : public NonnullPtrVector, inline_capacity> { + using NonnullPtrVector, inline_capacity>::NonnullPtrVector; +}; + +} + +using AK::NonnullRefPtrVector; diff --git a/AK/AK/NumericLimits.h b/LibC-Shim/AK/NumericLimits.h similarity index 96% rename from AK/AK/NumericLimits.h rename to LibC-Shim/AK/NumericLimits.h index 25489f4..987b2f6 100644 --- a/AK/AK/NumericLimits.h +++ b/LibC-Shim/AK/NumericLimits.h @@ -1,128 +1,128 @@ -#pragma once -#undef min -#undef max - -#include -#include -#include "./AK/Types.h" - -namespace AK { - -template -struct NumericLimits { -}; - -template<> -struct NumericLimits { - static constexpr bool min() { return false; } - static constexpr bool max() { return true; } - static constexpr bool is_signed() { return false; } -}; - -template<> -struct NumericLimits { - static constexpr signed char min() { return -SCHAR_MAX - 1; } - static constexpr signed char max() { return SCHAR_MAX; } - static constexpr bool is_signed() { return true; } -}; - -template<> -struct NumericLimits { - static constexpr char min() { return -SCHAR_MAX - 1; } - static constexpr char max() { return SCHAR_MAX; } - static constexpr bool is_signed() { return true; } -}; - -template<> -struct NumericLimits { - static constexpr short min() { return -SHRT_MAX - 1; } - static constexpr short max() { return SHRT_MAX; } - static constexpr bool is_signed() { return true; } -}; - -template<> -struct NumericLimits { - static constexpr int min() { return -INT_MAX - 1; } - static constexpr int max() { return INT_MAX; } - static constexpr bool is_signed() { return true; } -}; - -template<> -struct NumericLimits { - static constexpr long min() { return -LONG_MAX - 1; } - static constexpr long max() { return LONG_MAX; } - static constexpr bool is_signed() { return true; } -}; - -template<> -struct NumericLimits { - static constexpr long long min() { return -LLONG_MAX - 1; } - static constexpr long long max() { return LLONG_MAX; } - static constexpr bool is_signed() { return true; } -}; - -template<> -struct NumericLimits { - static constexpr unsigned char min() { return 0; } - static constexpr unsigned char max() { return SCHAR_MAX * 2u + 1; } - static constexpr bool is_signed() { return false; } -}; - -template<> -struct NumericLimits { - static constexpr unsigned short min() { return 0; } - static constexpr unsigned short max() { return SHRT_MAX * 2u + 1; } - static constexpr bool is_signed() { return false; } -}; - -template<> -struct NumericLimits { - static constexpr unsigned min() { return 0; } - static constexpr unsigned max() { return INT_MAX * 2u + 1; } - static constexpr bool is_signed() { return false; } -}; - -template<> -struct NumericLimits { - static constexpr unsigned long min() { return 0; } - static constexpr unsigned long max() { return LONG_MAX * 2ul + 1; } - static constexpr bool is_signed() { return false; } -}; - -template<> -struct NumericLimits { - static constexpr unsigned long long min() { return 0; } - static constexpr unsigned long long max() { return LLONG_MAX * 2ull + 1; } - static constexpr bool is_signed() { return false; } -}; - -template<> -struct NumericLimits { - static constexpr float lowest() { return -FLT_MAX; } - static constexpr float min() { return FLT_MIN; } - static constexpr float max() { return FLT_MAX; } - static constexpr float epsilon() { return FLT_EPSILON; } - static constexpr bool is_signed() { return true; } -}; - -template<> -struct NumericLimits { - static constexpr double lowest() { return -DBL_MAX; } - static constexpr double min() { return DBL_MIN; } - static constexpr double max() { return DBL_MAX; } - static constexpr double epsilon() { return DBL_EPSILON; } - static constexpr bool is_signed() { return true; } -}; - -template<> -struct NumericLimits { - static constexpr long double lowest() { return -LDBL_MAX; } - static constexpr long double min() { return LDBL_MIN; } - static constexpr long double max() { return LDBL_MAX; } - static constexpr long double epsilon() { return LDBL_EPSILON; } - static constexpr bool is_signed() { return true; } -}; - -} - -using AK::NumericLimits; +#pragma once +#undef min +#undef max + +#include +#include +#include "Types.h" + +namespace AK { + +template +struct NumericLimits { +}; + +template<> +struct NumericLimits { + static constexpr bool min() { return false; } + static constexpr bool max() { return true; } + static constexpr bool is_signed() { return false; } +}; + +template<> +struct NumericLimits { + static constexpr signed char min() { return -SCHAR_MAX - 1; } + static constexpr signed char max() { return SCHAR_MAX; } + static constexpr bool is_signed() { return true; } +}; + +template<> +struct NumericLimits { + static constexpr char min() { return -SCHAR_MAX - 1; } + static constexpr char max() { return SCHAR_MAX; } + static constexpr bool is_signed() { return true; } +}; + +template<> +struct NumericLimits { + static constexpr short min() { return -SHRT_MAX - 1; } + static constexpr short max() { return SHRT_MAX; } + static constexpr bool is_signed() { return true; } +}; + +template<> +struct NumericLimits { + static constexpr int min() { return -INT_MAX - 1; } + static constexpr int max() { return INT_MAX; } + static constexpr bool is_signed() { return true; } +}; + +template<> +struct NumericLimits { + static constexpr long min() { return -LONG_MAX - 1; } + static constexpr long max() { return LONG_MAX; } + static constexpr bool is_signed() { return true; } +}; + +template<> +struct NumericLimits { + static constexpr long long min() { return -LLONG_MAX - 1; } + static constexpr long long max() { return LLONG_MAX; } + static constexpr bool is_signed() { return true; } +}; + +template<> +struct NumericLimits { + static constexpr unsigned char min() { return 0; } + static constexpr unsigned char max() { return SCHAR_MAX * 2u + 1; } + static constexpr bool is_signed() { return false; } +}; + +template<> +struct NumericLimits { + static constexpr unsigned short min() { return 0; } + static constexpr unsigned short max() { return SHRT_MAX * 2u + 1; } + static constexpr bool is_signed() { return false; } +}; + +template<> +struct NumericLimits { + static constexpr unsigned min() { return 0; } + static constexpr unsigned max() { return INT_MAX * 2u + 1; } + static constexpr bool is_signed() { return false; } +}; + +template<> +struct NumericLimits { + static constexpr unsigned long min() { return 0; } + static constexpr unsigned long max() { return LONG_MAX * 2ul + 1; } + static constexpr bool is_signed() { return false; } +}; + +template<> +struct NumericLimits { + static constexpr unsigned long long min() { return 0; } + static constexpr unsigned long long max() { return LLONG_MAX * 2ull + 1; } + static constexpr bool is_signed() { return false; } +}; + +template<> +struct NumericLimits { + static constexpr float lowest() { return -FLT_MAX; } + static constexpr float min() { return FLT_MIN; } + static constexpr float max() { return FLT_MAX; } + static constexpr float epsilon() { return FLT_EPSILON; } + static constexpr bool is_signed() { return true; } +}; + +template<> +struct NumericLimits { + static constexpr double lowest() { return -DBL_MAX; } + static constexpr double min() { return DBL_MIN; } + static constexpr double max() { return DBL_MAX; } + static constexpr double epsilon() { return DBL_EPSILON; } + static constexpr bool is_signed() { return true; } +}; + +template<> +struct NumericLimits { + static constexpr long double lowest() { return -LDBL_MAX; } + static constexpr long double min() { return LDBL_MIN; } + static constexpr long double max() { return LDBL_MAX; } + static constexpr long double epsilon() { return LDBL_EPSILON; } + static constexpr bool is_signed() { return true; } +}; + +} + +using AK::NumericLimits; diff --git a/AK/AK/Optional.h b/LibC-Shim/AK/Optional.h similarity index 95% rename from AK/AK/Optional.h rename to LibC-Shim/AK/Optional.h index f97413e..2f056a8 100644 --- a/AK/AK/Optional.h +++ b/LibC-Shim/AK/Optional.h @@ -1,344 +1,344 @@ -#pragma once -/* - * Copyright (c) 2018-2021, Andreas Kling - * Copyright (c) 2021, Daniel Bertalan - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include "./AK/Assertions.h" -#include "./AK/StdLibExtras.h" -#include "./AK/Types.h" - - -namespace AK { - -// NOTE: If you're here because of an internal compiler error in GCC 10.3.0+, -// it's because of the following bug: -// -// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96745 -// -// Make sure you didn't accidentally make your destructor private before -// you start bug hunting. :^) - -template -class Optional; - -template -requires(!IsLvalueReference) class Optional { -template -friend class Optional; - -static_assert(!IsLvalueReference && !IsRvalueReference); - -public: - using ValueType = T; - - ALWAYS_INLINE Optional() = default; - - ALWAYS_INLINE Optional(Optional const& other) - : m_has_value(other.m_has_value) - { - if (other.has_value()) - new (&m_storage) T(other.value()); - } - - ALWAYS_INLINE Optional(Optional&& other) - : m_has_value(other.m_has_value) - { - if (other.has_value()) - new (&m_storage) T(other.release_value()); - } - - template - requires(IsConstructible && !IsSpecializationOf && !IsSpecializationOf) ALWAYS_INLINE explicit Optional(Optional const& other) - : m_has_value(other.m_has_value) - { - if (other.has_value()) - new (&m_storage) T(other.value()); - } - - template - requires(IsConstructible && !IsSpecializationOf && !IsSpecializationOf) ALWAYS_INLINE explicit Optional(Optional&& other) - : m_has_value(other.m_has_value) - { - if (other.has_value()) - new (&m_storage) T(other.release_value()); - } - - template - ALWAYS_INLINE explicit(!IsConvertible) Optional(U&& value) requires(!IsSame, Optional>&& IsConstructible) - : m_has_value(true) - { - new (&m_storage) T(forward(value)); - } - - ALWAYS_INLINE Optional& operator=(Optional const& other) - { - if (this != &other) { - clear(); - m_has_value = other.m_has_value; - if (other.has_value()) { - new (&m_storage) T(other.value()); - } - } - return *this; - } - - ALWAYS_INLINE Optional& operator=(Optional&& other) - { - if (this != &other) { - clear(); - m_has_value = other.m_has_value; - if (other.has_value()) { - new (&m_storage) T(other.release_value()); - } - } - return *this; - } - - template - ALWAYS_INLINE bool operator==(Optional const& other) const - { - return has_value() == other.has_value() && (!has_value() || value() == other.value()); - } - - template - ALWAYS_INLINE bool operator==(O const& other) const - { - return has_value() && value() == other; - } - - ALWAYS_INLINE ~Optional() - { - clear(); - } - - ALWAYS_INLINE void clear() - { - if (m_has_value) { - value().~T(); - m_has_value = false; - } - } - - template - ALWAYS_INLINE void emplace(Parameters&&... parameters) - { - clear(); - m_has_value = true; - new (&m_storage) T(forward(parameters)...); - } - - ALWAYS_INLINE bool has_value() const { return m_has_value; } - - ALWAYS_INLINE T& value()& - { - VERIFY(m_has_value); - return *__builtin_launder(reinterpret_cast(&m_storage)); - } - - ALWAYS_INLINE T const& value() const& - { - VERIFY(m_has_value); - return *__builtin_launder(reinterpret_cast(&m_storage)); - } - - ALWAYS_INLINE T value()&& - { - return release_value(); - } - - ALWAYS_INLINE T release_value() - { - VERIFY(m_has_value); - T released_value = move(value()); - value().~T(); - m_has_value = false; - return released_value; - } - - ALWAYS_INLINE T value_or(T const& fallback) const& - { - if (m_has_value) - return value(); - return fallback; - } - - ALWAYS_INLINE T value_or(T&& fallback)&& - { - if (m_has_value) - return move(value()); - return move(fallback); - } - - ALWAYS_INLINE T const& operator*() const { return value(); } - ALWAYS_INLINE T& operator*() { return value(); } - - ALWAYS_INLINE T const* operator->() const { return &value(); } - ALWAYS_INLINE T* operator->() { return &value(); } - -private: - alignas(T) u8 m_storage[sizeof(T)]; - bool m_has_value{ false }; -}; - -template -requires(IsLvalueReference) class Optional { -template -friend class Optional; - -template -constexpr static bool CanBePlacedInOptional = IsSame, RemoveReference>> && (IsBaseOf, RemoveCVReference> || IsSame, RemoveCVReference>); - -public: - using ValueType = T; - - ALWAYS_INLINE Optional() = default; - - template - ALWAYS_INLINE Optional(U& value) requires(CanBePlacedInOptional) - : m_pointer(&value) - { - } - - ALWAYS_INLINE Optional(RemoveReference& value) - : m_pointer(&value) - { - } - - ALWAYS_INLINE Optional(Optional const& other) - : m_pointer(other.m_pointer) - { - } - - ALWAYS_INLINE Optional(Optional&& other) - : m_pointer(other.m_pointer) - { - other.m_pointer = nullptr; - } - - template - ALWAYS_INLINE Optional(Optional const& other) requires(CanBePlacedInOptional) - : m_pointer(other.m_pointer) - { - } - - template - ALWAYS_INLINE Optional(Optional&& other) requires(CanBePlacedInOptional) - : m_pointer(other.m_pointer) - { - other.m_pointer = nullptr; - } - - ALWAYS_INLINE Optional& operator=(Optional const& other) - { - m_pointer = other.m_pointer; - return *this; - } - - ALWAYS_INLINE Optional& operator=(Optional&& other) - { - m_pointer = other.m_pointer; - other.m_pointer = nullptr; - return *this; - } - - template - ALWAYS_INLINE Optional& operator=(Optional const& other) requires(CanBePlacedInOptional) - { - m_pointer = other.m_pointer; - return *this; - } - - template - ALWAYS_INLINE Optional& operator=(Optional&& other) requires(CanBePlacedInOptional) - { - m_pointer = other.m_pointer; - other.m_pointer = nullptr; - return *this; - } - - // Note: Disallows assignment from a temporary as this does not do any lifetime extension. - template - ALWAYS_INLINE Optional& operator=(U&& value) requires(CanBePlacedInOptional&& IsLvalueReference) - { - m_pointer = &value; - return *this; - } - - ALWAYS_INLINE void clear() - { - m_pointer = nullptr; - } - - ALWAYS_INLINE bool has_value() const { return m_pointer != nullptr; } - - ALWAYS_INLINE T value() - { - VERIFY(m_pointer); - return *m_pointer; - } - - ALWAYS_INLINE AddConstToReferencedType value() const - { - VERIFY(m_pointer); - return *m_pointer; - } - - template - requires(IsBaseOf, U>) ALWAYS_INLINE AddConstToReferencedType value_or(U& fallback) const - { - if (m_pointer) - return value(); - return fallback; - } - - // Note that this ends up copying the value. - ALWAYS_INLINE RemoveCVReference value_or(RemoveCVReference fallback) const - { - if (m_pointer) - return value(); - return fallback; - } - - ALWAYS_INLINE T release_value() - { - return *exchange(m_pointer, nullptr); - } - - template - ALWAYS_INLINE bool operator==(Optional const& other) const - { - return has_value() == other.has_value() && (!has_value() || value() == other.value()); - } - - template - ALWAYS_INLINE bool operator==(U const& other) const - { - return has_value() && value() == other; - } - - ALWAYS_INLINE AddConstToReferencedType operator*() const { return value(); } - ALWAYS_INLINE T operator*() { return value(); } - - ALWAYS_INLINE RawPtr>> operator->() const { return &value(); } - ALWAYS_INLINE RawPtr> operator->() { return &value(); } - - // Conversion operators from Optional -> Optional - ALWAYS_INLINE operator Optional>() const - { - if (has_value()) - return Optional>(value()); - return {}; - } - -private: - RemoveReference* m_pointer{ nullptr }; -}; - -} - -using AK::Optional; +#pragma once +/* + * Copyright (c) 2018-2021, Andreas Kling + * Copyright (c) 2021, Daniel Bertalan + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include "Assertions.h" +#include "StdLibExtras.h" +#include "Types.h" + + +namespace AK { + +// NOTE: If you're here because of an internal compiler error in GCC 10.3.0+, +// it's because of the following bug: +// +// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96745 +// +// Make sure you didn't accidentally make your destructor private before +// you start bug hunting. :^) + +template +class Optional; + +template +requires(!IsLvalueReference) class Optional { +template +friend class Optional; + +static_assert(!IsLvalueReference && !IsRvalueReference); + +public: + using ValueType = T; + + ALWAYS_INLINE Optional() = default; + + ALWAYS_INLINE Optional(Optional const& other) + : m_has_value(other.m_has_value) + { + if (other.has_value()) + new (&m_storage) T(other.value()); + } + + ALWAYS_INLINE Optional(Optional&& other) + : m_has_value(other.m_has_value) + { + if (other.has_value()) + new (&m_storage) T(other.release_value()); + } + + template + requires(IsConstructible && !IsSpecializationOf && !IsSpecializationOf) ALWAYS_INLINE explicit Optional(Optional const& other) + : m_has_value(other.m_has_value) + { + if (other.has_value()) + new (&m_storage) T(other.value()); + } + + template + requires(IsConstructible && !IsSpecializationOf && !IsSpecializationOf) ALWAYS_INLINE explicit Optional(Optional&& other) + : m_has_value(other.m_has_value) + { + if (other.has_value()) + new (&m_storage) T(other.release_value()); + } + + template + ALWAYS_INLINE explicit(!IsConvertible) Optional(U&& value) requires(!IsSame, Optional>&& IsConstructible) + : m_has_value(true) + { + new (&m_storage) T(forward(value)); + } + + ALWAYS_INLINE Optional& operator=(Optional const& other) + { + if (this != &other) { + clear(); + m_has_value = other.m_has_value; + if (other.has_value()) { + new (&m_storage) T(other.value()); + } + } + return *this; + } + + ALWAYS_INLINE Optional& operator=(Optional&& other) + { + if (this != &other) { + clear(); + m_has_value = other.m_has_value; + if (other.has_value()) { + new (&m_storage) T(other.release_value()); + } + } + return *this; + } + + template + ALWAYS_INLINE bool operator==(Optional const& other) const + { + return has_value() == other.has_value() && (!has_value() || value() == other.value()); + } + + template + ALWAYS_INLINE bool operator==(O const& other) const + { + return has_value() && value() == other; + } + + ALWAYS_INLINE ~Optional() + { + clear(); + } + + ALWAYS_INLINE void clear() + { + if (m_has_value) { + value().~T(); + m_has_value = false; + } + } + + template + ALWAYS_INLINE void emplace(Parameters&&... parameters) + { + clear(); + m_has_value = true; + new (&m_storage) T(forward(parameters)...); + } + + ALWAYS_INLINE bool has_value() const { return m_has_value; } + + ALWAYS_INLINE T& value()& + { + VERIFY(m_has_value); + return *__builtin_launder(reinterpret_cast(&m_storage)); + } + + ALWAYS_INLINE T const& value() const& + { + VERIFY(m_has_value); + return *__builtin_launder(reinterpret_cast(&m_storage)); + } + + ALWAYS_INLINE T value()&& + { + return release_value(); + } + + ALWAYS_INLINE T release_value() + { + VERIFY(m_has_value); + T released_value = move(value()); + value().~T(); + m_has_value = false; + return released_value; + } + + ALWAYS_INLINE T value_or(T const& fallback) const& + { + if (m_has_value) + return value(); + return fallback; + } + + ALWAYS_INLINE T value_or(T&& fallback)&& + { + if (m_has_value) + return move(value()); + return move(fallback); + } + + ALWAYS_INLINE T const& operator*() const { return value(); } + ALWAYS_INLINE T& operator*() { return value(); } + + ALWAYS_INLINE T const* operator->() const { return &value(); } + ALWAYS_INLINE T* operator->() { return &value(); } + +private: + alignas(T) u8 m_storage[sizeof(T)]; + bool m_has_value{ false }; +}; + +template +requires(IsLvalueReference) class Optional { +template +friend class Optional; + +template +constexpr static bool CanBePlacedInOptional = IsSame, RemoveReference>> && (IsBaseOf, RemoveCVReference> || IsSame, RemoveCVReference>); + +public: + using ValueType = T; + + ALWAYS_INLINE Optional() = default; + + template + ALWAYS_INLINE Optional(U& value) requires(CanBePlacedInOptional) + : m_pointer(&value) + { + } + + ALWAYS_INLINE Optional(RemoveReference& value) + : m_pointer(&value) + { + } + + ALWAYS_INLINE Optional(Optional const& other) + : m_pointer(other.m_pointer) + { + } + + ALWAYS_INLINE Optional(Optional&& other) + : m_pointer(other.m_pointer) + { + other.m_pointer = nullptr; + } + + template + ALWAYS_INLINE Optional(Optional const& other) requires(CanBePlacedInOptional) + : m_pointer(other.m_pointer) + { + } + + template + ALWAYS_INLINE Optional(Optional&& other) requires(CanBePlacedInOptional) + : m_pointer(other.m_pointer) + { + other.m_pointer = nullptr; + } + + ALWAYS_INLINE Optional& operator=(Optional const& other) + { + m_pointer = other.m_pointer; + return *this; + } + + ALWAYS_INLINE Optional& operator=(Optional&& other) + { + m_pointer = other.m_pointer; + other.m_pointer = nullptr; + return *this; + } + + template + ALWAYS_INLINE Optional& operator=(Optional const& other) requires(CanBePlacedInOptional) + { + m_pointer = other.m_pointer; + return *this; + } + + template + ALWAYS_INLINE Optional& operator=(Optional&& other) requires(CanBePlacedInOptional) + { + m_pointer = other.m_pointer; + other.m_pointer = nullptr; + return *this; + } + + // Note: Disallows assignment from a temporary as this does not do any lifetime extension. + template + ALWAYS_INLINE Optional& operator=(U&& value) requires(CanBePlacedInOptional&& IsLvalueReference) + { + m_pointer = &value; + return *this; + } + + ALWAYS_INLINE void clear() + { + m_pointer = nullptr; + } + + ALWAYS_INLINE bool has_value() const { return m_pointer != nullptr; } + + ALWAYS_INLINE T value() + { + VERIFY(m_pointer); + return *m_pointer; + } + + ALWAYS_INLINE AddConstToReferencedType value() const + { + VERIFY(m_pointer); + return *m_pointer; + } + + template + requires(IsBaseOf, U>) ALWAYS_INLINE AddConstToReferencedType value_or(U& fallback) const + { + if (m_pointer) + return value(); + return fallback; + } + + // Note that this ends up copying the value. + ALWAYS_INLINE RemoveCVReference value_or(RemoveCVReference fallback) const + { + if (m_pointer) + return value(); + return fallback; + } + + ALWAYS_INLINE T release_value() + { + return *exchange(m_pointer, nullptr); + } + + template + ALWAYS_INLINE bool operator==(Optional const& other) const + { + return has_value() == other.has_value() && (!has_value() || value() == other.value()); + } + + template + ALWAYS_INLINE bool operator==(U const& other) const + { + return has_value() && value() == other; + } + + ALWAYS_INLINE AddConstToReferencedType operator*() const { return value(); } + ALWAYS_INLINE T operator*() { return value(); } + + ALWAYS_INLINE RawPtr>> operator->() const { return &value(); } + ALWAYS_INLINE RawPtr> operator->() { return &value(); } + + // Conversion operators from Optional -> Optional + ALWAYS_INLINE operator Optional>() const + { + if (has_value()) + return Optional>(value()); + return {}; + } + +private: + RemoveReference* m_pointer{ nullptr }; +}; + +} + +using AK::Optional; diff --git a/AK/AK/OwnPtr.h b/LibC-Shim/AK/OwnPtr.h similarity index 95% rename from AK/AK/OwnPtr.h rename to LibC-Shim/AK/OwnPtr.h index 6fcc8df..72331a9 100644 --- a/AK/AK/OwnPtr.h +++ b/LibC-Shim/AK/OwnPtr.h @@ -1,241 +1,241 @@ -/* - * Copyright (c) 2018-2020, Andreas Kling - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include -#include -#include - -#define OWNPTR_SCRUB_BYTE 0xf0 - -namespace AK { - -template -class OwnPtr { -public: - OwnPtr() = default; - - OwnPtr(decltype(nullptr)) - : m_ptr(nullptr) - { - } - - OwnPtr(OwnPtr&& other) - : m_ptr(other.leak_ptr()) - { - } - - template - OwnPtr(NonnullOwnPtr&& other) - : m_ptr(other.leak_ptr()) - { - } - template - OwnPtr(OwnPtr&& other) - : m_ptr(other.leak_ptr()) - { - } - ~OwnPtr() - { - clear(); - } - - OwnPtr(OwnPtr const&) = delete; - template - OwnPtr(OwnPtr const&) = delete; - OwnPtr& operator=(OwnPtr const&) = delete; - template - OwnPtr& operator=(OwnPtr const&) = delete; - - template - OwnPtr(NonnullOwnPtr const&) = delete; - template - OwnPtr& operator=(NonnullOwnPtr const&) = delete; - template - OwnPtr(RefPtr const&) = delete; - template - OwnPtr(NonnullRefPtr const&) = delete; - template - OwnPtr(WeakPtr const&) = delete; - template - OwnPtr& operator=(RefPtr const&) = delete; - template - OwnPtr& operator=(NonnullRefPtr const&) = delete; - template - OwnPtr& operator=(WeakPtr const&) = delete; - - OwnPtr& operator=(OwnPtr&& other) - { - OwnPtr ptr(move(other)); - swap(ptr); - return *this; - } - - template - OwnPtr& operator=(OwnPtr&& other) - { - OwnPtr ptr(move(other)); - swap(ptr); - return *this; - } - - template - OwnPtr& operator=(NonnullOwnPtr&& other) - { - OwnPtr ptr(move(other)); - swap(ptr); - VERIFY(m_ptr); - return *this; - } - - OwnPtr& operator=(T* ptr) = delete; - - OwnPtr& operator=(std::nullptr_t) - { - clear(); - return *this; - } - - void clear() - { - delete m_ptr; - m_ptr = nullptr; - } - - bool operator!() const { return !m_ptr; } - - T* leak_ptr() - { - T* leaked_ptr = m_ptr; - m_ptr = nullptr; - return leaked_ptr; - } - - NonnullOwnPtr release_nonnull() - { - VERIFY(m_ptr); - return NonnullOwnPtr(NonnullOwnPtr::Adopt, *leak_ptr()); - } - - template - NonnullOwnPtr release_nonnull() - { - VERIFY(m_ptr); - return NonnullOwnPtr(NonnullOwnPtr::Adopt, static_cast(*leak_ptr())); - } - - T* ptr() { return m_ptr; } - const T* ptr() const { return m_ptr; } - - T* operator->() - { - VERIFY(m_ptr); - return m_ptr; - } - - const T* operator->() const - { - VERIFY(m_ptr); - return m_ptr; - } - - T& operator*() - { - VERIFY(m_ptr); - return *m_ptr; - } - - const T& operator*() const - { - VERIFY(m_ptr); - return *m_ptr; - } - - operator const T* () const { return m_ptr; } - operator T* () { return m_ptr; } - - operator bool() { return !!m_ptr; } - - void swap(OwnPtr& other) - { - ::swap(m_ptr, other.m_ptr); - } - - template - void swap(OwnPtr& other) - { - ::swap(m_ptr, other.m_ptr); - } - - static OwnPtr lift(T* ptr) - { - return OwnPtr{ ptr }; - } - -protected: - explicit OwnPtr(T* ptr) - : m_ptr(ptr) - { - static_assert( - requires { requires typename T::AllowOwnPtr()(); } || !requires { requires !typename T::AllowOwnPtr()(); declval().ref(); declval().unref(); }, "Use RefPtr<> for RefCounted types"); - } - -private: - T* m_ptr = nullptr; -}; - -template -ALWAYS_INLINE void swap(OwnPtr& a, OwnPtr& b) -{ - a.swap(b); -} - -template -ALWAYS_INLINE OwnPtr adopt_own_if_nonnull(T* object) -{ - if (object) - return OwnPtr::lift(object); - return {}; -} - -template -ALWAYS_INLINE ErrorOr> adopt_nonnull_own_or_enomem(T* object) -{ - auto result = adopt_own_if_nonnull(object); - if (!result) - return Error::from_errno(ENOMEM); - return result.release_nonnull(); -} - -template - requires(IsConstructible) ALWAYS_INLINE ErrorOr> try_make(Args&&... args) -{ - return adopt_nonnull_own_or_enomem(new (nothrow) T(forward(args)...)); -} - -// FIXME: Remove once P0960R3 is available in Clang. -template -ALWAYS_INLINE ErrorOr> try_make(Args&&... args) - -{ - return adopt_nonnull_own_or_enomem(new (nothrow) T{ forward(args)... }); -} - -template -struct Traits> : public GenericTraits> { - using PeekType = T*; - using ConstPeekType = const T*; - static unsigned hash(OwnPtr const& p) { return ptr_hash(p.ptr()); } - static bool equals(OwnPtr const& a, OwnPtr const& b) { return a.ptr() == b.ptr(); } -}; - -} - -using AK::adopt_nonnull_own_or_enomem; -using AK::adopt_own_if_nonnull; -using AK::OwnPtr; -using AK::try_make; +/* + * Copyright (c) 2018-2020, Andreas Kling + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include +#include + +#define OWNPTR_SCRUB_BYTE 0xf0 + +namespace AK { + +template +class OwnPtr { +public: + OwnPtr() = default; + + OwnPtr(decltype(nullptr)) + : m_ptr(nullptr) + { + } + + OwnPtr(OwnPtr&& other) + : m_ptr(other.leak_ptr()) + { + } + + template + OwnPtr(NonnullOwnPtr&& other) + : m_ptr(other.leak_ptr()) + { + } + template + OwnPtr(OwnPtr&& other) + : m_ptr(other.leak_ptr()) + { + } + ~OwnPtr() + { + clear(); + } + + OwnPtr(OwnPtr const&) = delete; + template + OwnPtr(OwnPtr const&) = delete; + OwnPtr& operator=(OwnPtr const&) = delete; + template + OwnPtr& operator=(OwnPtr const&) = delete; + + template + OwnPtr(NonnullOwnPtr const&) = delete; + template + OwnPtr& operator=(NonnullOwnPtr const&) = delete; + template + OwnPtr(RefPtr const&) = delete; + template + OwnPtr(NonnullRefPtr const&) = delete; + template + OwnPtr(WeakPtr const&) = delete; + template + OwnPtr& operator=(RefPtr const&) = delete; + template + OwnPtr& operator=(NonnullRefPtr const&) = delete; + template + OwnPtr& operator=(WeakPtr const&) = delete; + + OwnPtr& operator=(OwnPtr&& other) + { + OwnPtr ptr(move(other)); + swap(ptr); + return *this; + } + + template + OwnPtr& operator=(OwnPtr&& other) + { + OwnPtr ptr(move(other)); + swap(ptr); + return *this; + } + + template + OwnPtr& operator=(NonnullOwnPtr&& other) + { + OwnPtr ptr(move(other)); + swap(ptr); + VERIFY(m_ptr); + return *this; + } + + OwnPtr& operator=(T* ptr) = delete; + + OwnPtr& operator=(std::nullptr_t) + { + clear(); + return *this; + } + + void clear() + { + delete m_ptr; + m_ptr = nullptr; + } + + bool operator!() const { return !m_ptr; } + + T* leak_ptr() + { + T* leaked_ptr = m_ptr; + m_ptr = nullptr; + return leaked_ptr; + } + + NonnullOwnPtr release_nonnull() + { + VERIFY(m_ptr); + return NonnullOwnPtr(NonnullOwnPtr::Adopt, *leak_ptr()); + } + + template + NonnullOwnPtr release_nonnull() + { + VERIFY(m_ptr); + return NonnullOwnPtr(NonnullOwnPtr::Adopt, static_cast(*leak_ptr())); + } + + T* ptr() { return m_ptr; } + const T* ptr() const { return m_ptr; } + + T* operator->() + { + VERIFY(m_ptr); + return m_ptr; + } + + const T* operator->() const + { + VERIFY(m_ptr); + return m_ptr; + } + + T& operator*() + { + VERIFY(m_ptr); + return *m_ptr; + } + + const T& operator*() const + { + VERIFY(m_ptr); + return *m_ptr; + } + + operator const T* () const { return m_ptr; } + operator T* () { return m_ptr; } + + operator bool() { return !!m_ptr; } + + void swap(OwnPtr& other) + { + ::swap(m_ptr, other.m_ptr); + } + + template + void swap(OwnPtr& other) + { + ::swap(m_ptr, other.m_ptr); + } + + static OwnPtr lift(T* ptr) + { + return OwnPtr{ ptr }; + } + +protected: + explicit OwnPtr(T* ptr) + : m_ptr(ptr) + { + static_assert( + requires { requires typename T::AllowOwnPtr()(); } || !requires { requires !typename T::AllowOwnPtr()(); declval().ref(); declval().unref(); }, "Use RefPtr<> for RefCounted types"); + } + +private: + T* m_ptr = nullptr; +}; + +template +ALWAYS_INLINE void swap(OwnPtr& a, OwnPtr& b) +{ + a.swap(b); +} + +template +ALWAYS_INLINE OwnPtr adopt_own_if_nonnull(T* object) +{ + if (object) + return OwnPtr::lift(object); + return {}; +} + +template +ALWAYS_INLINE ErrorOr> adopt_nonnull_own_or_enomem(T* object) +{ + auto result = adopt_own_if_nonnull(object); + if (!result) + return Error::from_errno(ENOMEM); + return result.release_nonnull(); +} + +template + requires(IsConstructible) ALWAYS_INLINE ErrorOr> try_make(Args&&... args) +{ + return adopt_nonnull_own_or_enomem(new (nothrow) T(forward(args)...)); +} + +// FIXME: Remove once P0960R3 is available in Clang. +template +ALWAYS_INLINE ErrorOr> try_make(Args&&... args) + +{ + return adopt_nonnull_own_or_enomem(new (nothrow) T{ forward(args)... }); +} + +template +struct Traits> : public GenericTraits> { + using PeekType = T*; + using ConstPeekType = const T*; + static unsigned hash(OwnPtr const& p) { return ptr_hash(p.ptr()); } + static bool equals(OwnPtr const& a, OwnPtr const& b) { return a.ptr() == b.ptr(); } +}; + +} + +using AK::adopt_nonnull_own_or_enomem; +using AK::adopt_own_if_nonnull; +using AK::OwnPtr; +using AK::try_make; diff --git a/AK/AK/Platform.h b/LibC-Shim/AK/Platform.h similarity index 95% rename from AK/AK/Platform.h rename to LibC-Shim/AK/Platform.h index 01f7729..0facfeb 100644 --- a/AK/AK/Platform.h +++ b/LibC-Shim/AK/Platform.h @@ -1,109 +1,109 @@ -#pragma once - -#pragma warning(disable: 4146) -#pragma warning(disable: 4390) // FIXME: Need to fix verify, then remove this -#pragma warning(disable: 34716) - -#undef _USE_MATH_DEFINES -#define _USE_MATH_DEFINES - -#include -#include -#include - -#ifdef _M_IX86 -# define AK_ARCH_I386 1 -#endif - -#ifdef _M_AMD64 -# define AK_ARCH_X86_64 1 -#endif - -#ifdef _M_ARM -# define AK_ARCH_AARCH32 1 -#endif - -#ifdef _M_ARM64 -# define AK_ARCH_AARCH64 1 -#endif - -#define AK_OS_WINRT - -#ifdef ALWAYS_INLINE -# undef ALWAYS_INLINE -#endif -#define ALWAYS_INLINE __forceinline - -#ifdef NEVER_INLINE -# undef NEVER_INLINE -#endif -#define NEVER_INLINE __declspec(noinline) - -#ifdef FLATTEN -# undef FLATTEN -#endif -#define FLATTEN //__attribute__((flatten)) - -#ifdef RETURNS_NONNULL -# undef RETURNS_NONNULL -#endif -#define RETURNS_NONNULL //__attribute__((returns_nonnull)) - -#ifdef NO_SANITIZE_ADDRESS -# undef NO_SANITIZE_ADDRESS -#endif -#define NO_SANITIZE_ADDRESS //__attribute__((no_sanitize_address)) - -#ifdef NORETURN -# undef NORETURN -#endif -#define NORETURN __declspec(noreturn) - -#ifdef NAKED -# undef NAKED -#endif -#define NAKED __declspec(naked) - -#define ASAN_POISON_MEMORY_REGION(addr, size) -#define ASAN_UNPOISON_MEMORY_REGION(addr, size) - -#undef __BEGIN_DECLS -#undef __END_DECLS -#ifdef __cplusplus -# define __BEGIN_DECLS extern "C" { -# define __END_DECLS } -#else -# define __BEGIN_DECLS /* empty */ -# define __END_DECLS /* empty */ -#endif - -// built-ins -#define __builtin_isnan isnan -#define __builtin_isinf isinf -#define __builtin_isinf_sign isinf -#define __builtin_launder std::launder -#define __builtin_exp2 exp2 -#define __builtin_add_overflow(a, b, c) (a += b) -#define __builtin_sub_overflow(a, b, c) (a -= b) -#define __builtin_mul_overflow(a, b, c) (a *= b) -#define ssize_t __int64 -#define suseconds_t long int -#define pid_t int - -// gcc -#define __attribute__(expression) - -#ifndef __ORDER_LITTLE_ENDIAN__ -#define __ORDER_LITTLE_ENDIAN__ 1234 // FIXME: -#endif -#ifndef __BYTE_ORDER__ -#define __BYTE_ORDER__ 1234 // FIXME: -#endif - -// msvc quirks -#undef Yield -#undef _CRT_NO_TIME_T - -// FIXME: We need to figure out why the LibJS macro fails under msvc -#define __TRY_OR_REJECT(global_object, capability, expression, CALL_CHECK) (expression.release_value()) -#define TRY_OR_REJECT_WITH_VALUE(global_object, capability, expression) (expression.release_value()) +#pragma once + +#pragma warning(disable: 4146) +#pragma warning(disable: 4390) // FIXME: Need to fix verify, then remove this +#pragma warning(disable: 34716) + +#undef _USE_MATH_DEFINES +#define _USE_MATH_DEFINES + +#include +#include +#include + +#ifdef _M_IX86 +# define AK_ARCH_I386 1 +#endif + +#ifdef _M_AMD64 +# define AK_ARCH_X86_64 1 +#endif + +#ifdef _M_ARM +# define AK_ARCH_AARCH32 1 +#endif + +#ifdef _M_ARM64 +# define AK_ARCH_AARCH64 1 +#endif + +#define AK_OS_WINRT + +#ifdef ALWAYS_INLINE +# undef ALWAYS_INLINE +#endif +#define ALWAYS_INLINE __forceinline + +#ifdef NEVER_INLINE +# undef NEVER_INLINE +#endif +#define NEVER_INLINE __declspec(noinline) + +#ifdef FLATTEN +# undef FLATTEN +#endif +#define FLATTEN //__attribute__((flatten)) + +#ifdef RETURNS_NONNULL +# undef RETURNS_NONNULL +#endif +#define RETURNS_NONNULL //__attribute__((returns_nonnull)) + +#ifdef NO_SANITIZE_ADDRESS +# undef NO_SANITIZE_ADDRESS +#endif +#define NO_SANITIZE_ADDRESS //__attribute__((no_sanitize_address)) + +#ifdef NORETURN +# undef NORETURN +#endif +#define NORETURN __declspec(noreturn) + +#ifdef NAKED +# undef NAKED +#endif +#define NAKED __declspec(naked) + +#define ASAN_POISON_MEMORY_REGION(addr, size) +#define ASAN_UNPOISON_MEMORY_REGION(addr, size) + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +// built-ins +#define __builtin_isnan isnan +#define __builtin_isinf isinf +#define __builtin_isinf_sign isinf +#define __builtin_launder std::launder +#define __builtin_exp2 exp2 +#define __builtin_add_overflow(a, b, c) (a += b) +#define __builtin_sub_overflow(a, b, c) (a -= b) +#define __builtin_mul_overflow(a, b, c) (a *= b) +#define ssize_t __int64 +#define suseconds_t long int +#define pid_t int + +// gcc +#define __attribute__(expression) + +#ifndef __ORDER_LITTLE_ENDIAN__ +#define __ORDER_LITTLE_ENDIAN__ 1234 // FIXME: +#endif +#ifndef __BYTE_ORDER__ +#define __BYTE_ORDER__ 1234 // FIXME: +#endif + +// msvc quirks +#undef Yield +#undef _CRT_NO_TIME_T + +// FIXME: We need to figure out why the LibJS macro fails under msvc +#define __TRY_OR_REJECT(global_object, capability, expression, CALL_CHECK) (expression.release_value()) +#define TRY_OR_REJECT_WITH_VALUE(global_object, capability, expression) (expression.release_value()) diff --git a/AK/AK/QuickSort.h b/LibC-Shim/AK/QuickSort.h similarity index 92% rename from AK/AK/QuickSort.h rename to LibC-Shim/AK/QuickSort.h index 1abb796..68c8271 100644 --- a/AK/AK/QuickSort.h +++ b/LibC-Shim/AK/QuickSort.h @@ -1,33 +1,33 @@ -/* - * Copyright (c) 2018-2020, Andreas Kling - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include "./AK/StdLibExtras.h" - -namespace AK { - -template -void dual_pivot_quick_sort(Collection& col, int start, int end, LessThan less_than); - -template -void single_pivot_quick_sort(Iterator start, Iterator end, LessThan less_than); - -template -void quick_sort(Iterator start, Iterator end); - -template -void quick_sort(Iterator start, Iterator end, LessThan less_than); - -template -void quick_sort(Collection& collection, LessThan less_than); - -template -void quick_sort(Collection& collection); - -} - -using AK::quick_sort; +/* + * Copyright (c) 2018-2020, Andreas Kling + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include "StdLibExtras.h" + +namespace AK { + +template +void dual_pivot_quick_sort(Collection& col, int start, int end, LessThan less_than); + +template +void single_pivot_quick_sort(Iterator start, Iterator end, LessThan less_than); + +template +void quick_sort(Iterator start, Iterator end); + +template +void quick_sort(Iterator start, Iterator end, LessThan less_than); + +template +void quick_sort(Collection& collection, LessThan less_than); + +template +void quick_sort(Collection& collection); + +} + +using AK::quick_sort; diff --git a/AK/AK/Random.h b/LibC-Shim/AK/Random.h similarity index 84% rename from AK/AK/Random.h rename to LibC-Shim/AK/Random.h index 9ce822f..8cbb8b3 100644 --- a/AK/AK/Random.h +++ b/LibC-Shim/AK/Random.h @@ -1,33 +1,33 @@ -/* - * Copyright (c) 2020, Andreas Kling - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include -#include "./AK/Platform.h" -#include "./AK/Types.h" - -namespace AK { - -ALWAYS_INLINE void fill_with_random(void* buffer, size_t length) -{ -} - -template -ALWAYS_INLINE T get_random() -{ - T t; - fill_with_random(&t, sizeof(T)); - return t; -} - -u32 get_random_uniform(u32 max_bounds); - -} - -using AK::fill_with_random; -using AK::get_random; -using AK::get_random_uniform; +/* + * Copyright (c) 2020, Andreas Kling + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include "Platform.h" +#include "Types.h" + +namespace AK { + +ALWAYS_INLINE void fill_with_random(void* buffer, size_t length) +{ +} + +template +ALWAYS_INLINE T get_random() +{ + T t; + fill_with_random(&t, sizeof(T)); + return t; +} + +u32 get_random_uniform(u32 max_bounds); + +} + +using AK::fill_with_random; +using AK::get_random; +using AK::get_random_uniform; diff --git a/AK/AK/RedBlackTree.h b/LibC-Shim/AK/RedBlackTree.h similarity index 93% rename from AK/AK/RedBlackTree.h rename to LibC-Shim/AK/RedBlackTree.h index 77d0866..ee315d3 100644 --- a/AK/AK/RedBlackTree.h +++ b/LibC-Shim/AK/RedBlackTree.h @@ -1,173 +1,173 @@ -/* - * Copyright (c) 2021, Idan Horowitz - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include "./AK/Concepts.h" -#include "./AK/Error.h" -#include "./AK/Noncopyable.h" -#include "./AK/kmalloc.h" - -namespace AK { - -template -class BaseRedBlackTree { - AK_MAKE_NONCOPYABLE(BaseRedBlackTree); - AK_MAKE_NONMOVABLE(BaseRedBlackTree); - -public: - size_t size() const; - bool is_empty() const; - - enum class Color : bool { - Red, - Black - }; - struct Node { - Node* left_child { nullptr }; - Node* right_child { nullptr }; - Node* parent { nullptr }; - - Color color { Color::Red }; - - K key; - - Node(K key) - : key(key) - { - } - Node() - { - } - virtual ~Node() {}; - }; - -protected: - BaseRedBlackTree() = default; // These are protected to ensure no one instantiates the leaky base red black tree directly - virtual ~BaseRedBlackTree() = default; - - void rotate_left(Node* subtree_root); - - void rotate_right(Node* subtree_root); - - static Node* find(Node* node, K key); - - static Node* find_largest_not_above(Node* node, K key); - - static Node* find_smallest_not_below(Node* node, K key); - - void insert(Node* node); - - void insert_fixups(Node* node); - - void remove(Node* node); - - // We maintain parent as a separate argument since node might be null - void remove_fixups(Node* node, Node* parent); - - static Node* successor(Node* node); - - static Node* predecessor(Node* node); - - Node* m_root { nullptr }; - size_t m_size { 0 }; - Node* m_minimum { nullptr }; // maintained for O(1) begin() -}; - -template -class RedBlackTreeIterator { -public: - RedBlackTreeIterator() = default; - bool operator!=(RedBlackTreeIterator const& other) const; - RedBlackTreeIterator& operator++(); - RedBlackTreeIterator& operator--(); - ElementType& operator*(); - ElementType* operator->(); - bool is_end() const; - bool is_begin() const; - - auto key() const { return m_node->key; } - -private: - friend TreeType; - explicit RedBlackTreeIterator(typename TreeType::Node* node, typename TreeType::Node* prev = nullptr) - : m_node(node) - , m_prev(prev) - { - } - typename TreeType::Node* m_node { nullptr }; - typename TreeType::Node* m_prev { nullptr }; -}; - -template -class RedBlackTree final : public BaseRedBlackTree { -public: - RedBlackTree() = default; - virtual ~RedBlackTree() override - { - clear(); - } - - using BaseTree = BaseRedBlackTree; - - V* find(K key); - - V* find_largest_not_above(K key); - - V* find_smallest_not_below(K key); - - ErrorOr try_insert(K key, V const& value); - - void insert(K key, V const& value); - - ErrorOr try_insert(K key, V&& value); - - void insert(K key, V&& value); - - using Iterator = RedBlackTreeIterator; - friend Iterator; - Iterator begin(); - Iterator end(); - Iterator begin_from(K key); - - using ConstIterator = RedBlackTreeIterator; - friend ConstIterator; - ConstIterator begin() const; - ConstIterator end() const; - ConstIterator begin_from(K key) const; - - ConstIterator find_largest_not_above_iterator(K key) const; - - ConstIterator find_smallest_not_below_iterator(K key) const; - - V unsafe_remove(K key); - - bool remove(K key); - - void clear(); - -private: - struct Node : BaseRedBlackTree::Node { - - V value; - - Node(K key, V value) - : BaseRedBlackTree::Node(key) - , value(move(value)) - { - } - - ~Node() - { - delete this->left_child; - delete this->right_child; - } - }; -}; - -} - -using AK::RedBlackTree; +/* + * Copyright (c) 2021, Idan Horowitz + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include "Concepts.h" +#include "Error.h" +#include "Noncopyable.h" +#include "kmalloc.h" + +namespace AK { + +template +class BaseRedBlackTree { + AK_MAKE_NONCOPYABLE(BaseRedBlackTree); + AK_MAKE_NONMOVABLE(BaseRedBlackTree); + +public: + size_t size() const; + bool is_empty() const; + + enum class Color : bool { + Red, + Black + }; + struct Node { + Node* left_child { nullptr }; + Node* right_child { nullptr }; + Node* parent { nullptr }; + + Color color { Color::Red }; + + K key; + + Node(K key) + : key(key) + { + } + Node() + { + } + virtual ~Node() {}; + }; + +protected: + BaseRedBlackTree() = default; // These are protected to ensure no one instantiates the leaky base red black tree directly + virtual ~BaseRedBlackTree() = default; + + void rotate_left(Node* subtree_root); + + void rotate_right(Node* subtree_root); + + static Node* find(Node* node, K key); + + static Node* find_largest_not_above(Node* node, K key); + + static Node* find_smallest_not_below(Node* node, K key); + + void insert(Node* node); + + void insert_fixups(Node* node); + + void remove(Node* node); + + // We maintain parent as a separate argument since node might be null + void remove_fixups(Node* node, Node* parent); + + static Node* successor(Node* node); + + static Node* predecessor(Node* node); + + Node* m_root { nullptr }; + size_t m_size { 0 }; + Node* m_minimum { nullptr }; // maintained for O(1) begin() +}; + +template +class RedBlackTreeIterator { +public: + RedBlackTreeIterator() = default; + bool operator!=(RedBlackTreeIterator const& other) const; + RedBlackTreeIterator& operator++(); + RedBlackTreeIterator& operator--(); + ElementType& operator*(); + ElementType* operator->(); + bool is_end() const; + bool is_begin() const; + + auto key() const { return m_node->key; } + +private: + friend TreeType; + explicit RedBlackTreeIterator(typename TreeType::Node* node, typename TreeType::Node* prev = nullptr) + : m_node(node) + , m_prev(prev) + { + } + typename TreeType::Node* m_node { nullptr }; + typename TreeType::Node* m_prev { nullptr }; +}; + +template +class RedBlackTree final : public BaseRedBlackTree { +public: + RedBlackTree() = default; + virtual ~RedBlackTree() override + { + clear(); + } + + using BaseTree = BaseRedBlackTree; + + V* find(K key); + + V* find_largest_not_above(K key); + + V* find_smallest_not_below(K key); + + ErrorOr try_insert(K key, V const& value); + + void insert(K key, V const& value); + + ErrorOr try_insert(K key, V&& value); + + void insert(K key, V&& value); + + using Iterator = RedBlackTreeIterator; + friend Iterator; + Iterator begin(); + Iterator end(); + Iterator begin_from(K key); + + using ConstIterator = RedBlackTreeIterator; + friend ConstIterator; + ConstIterator begin() const; + ConstIterator end() const; + ConstIterator begin_from(K key) const; + + ConstIterator find_largest_not_above_iterator(K key) const; + + ConstIterator find_smallest_not_below_iterator(K key) const; + + V unsafe_remove(K key); + + bool remove(K key); + + void clear(); + +private: + struct Node : BaseRedBlackTree::Node { + + V value; + + Node(K key, V value) + : BaseRedBlackTree::Node(key) + , value(move(value)) + { + } + + ~Node() + { + delete this->left_child; + delete this->right_child; + } + }; +}; + +} + +using AK::RedBlackTree; diff --git a/AK/AK/RefCounted.h b/LibC-Shim/AK/RefCounted.h similarity index 87% rename from AK/AK/RefCounted.h rename to LibC-Shim/AK/RefCounted.h index 53fcb11..09e8afb 100644 --- a/AK/AK/RefCounted.h +++ b/LibC-Shim/AK/RefCounted.h @@ -1,76 +1,76 @@ -/* - * Copyright (c) 2018-2020, Andreas Kling - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include "./AK/Assertions.h" -#include "./AK/Checked.h" -#include "./AK/Noncopyable.h" -#include "./AK/Platform.h" -#include "./AK/StdLibExtras.h" - -namespace AK { - -class RefCountedBase { - AK_MAKE_NONCOPYABLE(RefCountedBase); - AK_MAKE_NONMOVABLE(RefCountedBase); - -public: - using RefCountType = unsigned int; - using AllowOwnPtr = FalseType; - - ALWAYS_INLINE void ref() const - { - //VERIFY(m_ref_count > 0); - //VERIFY(!Checked::addition_would_overflow(m_ref_count, 1)); - ++m_ref_count; - } - - bool try_ref() const - { - if (m_ref_count == 0) - return false; - ref(); - return true; - } - - RefCountType ref_count() const { return m_ref_count; } - -protected: - RefCountedBase() = default; - ~RefCountedBase() { /*VERIFY(!m_ref_count);*/ } - - ALWAYS_INLINE RefCountType deref_base() const - { - //VERIFY(m_ref_count); - return --m_ref_count; - } - - RefCountType mutable m_ref_count{ 1 }; -}; - -template -class RefCounted : public RefCountedBase { -public: - bool unref() const - { - auto* that = const_cast(static_cast(this)); - - auto new_ref_count = deref_base(); - if (new_ref_count == 0) { - if constexpr (requires { that->will_be_destroyed(); }) - that->will_be_destroyed(); - delete static_cast(this); - return true; - } - return false; - } -}; - -} - -using AK::RefCounted; -using AK::RefCountedBase; +/* + * Copyright (c) 2018-2020, Andreas Kling + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include "Assertions.h" +#include "Checked.h" +#include "Noncopyable.h" +#include "Platform.h" +#include "StdLibExtras.h" + +namespace AK { + +class RefCountedBase { + AK_MAKE_NONCOPYABLE(RefCountedBase); + AK_MAKE_NONMOVABLE(RefCountedBase); + +public: + using RefCountType = unsigned int; + using AllowOwnPtr = FalseType; + + ALWAYS_INLINE void ref() const + { + //VERIFY(m_ref_count > 0); + //VERIFY(!Checked::addition_would_overflow(m_ref_count, 1)); + ++m_ref_count; + } + + bool try_ref() const + { + if (m_ref_count == 0) + return false; + ref(); + return true; + } + + RefCountType ref_count() const { return m_ref_count; } + +protected: + RefCountedBase() = default; + ~RefCountedBase() { /*VERIFY(!m_ref_count);*/ } + + ALWAYS_INLINE RefCountType deref_base() const + { + //VERIFY(m_ref_count); + return --m_ref_count; + } + + RefCountType mutable m_ref_count{ 1 }; +}; + +template +class RefCounted : public RefCountedBase { +public: + bool unref() const + { + auto* that = const_cast(static_cast(this)); + + auto new_ref_count = deref_base(); + if (new_ref_count == 0) { + if constexpr (requires { that->will_be_destroyed(); }) + that->will_be_destroyed(); + delete static_cast(this); + return true; + } + return false; + } +}; + +} + +using AK::RefCounted; +using AK::RefCountedBase; diff --git a/AK/AK/RefPtr.h b/LibC-Shim/AK/RefPtr.h similarity index 93% rename from AK/AK/RefPtr.h rename to LibC-Shim/AK/RefPtr.h index 04702c1..c5bb555 100644 --- a/AK/AK/RefPtr.h +++ b/LibC-Shim/AK/RefPtr.h @@ -1,373 +1,373 @@ -/* - * Copyright (c) 2018-2020, Andreas Kling - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#define REFPTR_SCRUB_BYTE 0xe0 - -#include "./AK/Assertions.h" -#include "./AK/Atomic.h" -#include "./AK/Error.h" -#include "./AK/Format.h" -#include "./AK/NonnullRefPtr.h" -#include "./AK/StdLibExtras.h" -#include "./AK/Traits.h" -#include "./AK/Types.h" - -namespace AK { - -template -class OwnPtr; - -template -class RefPtr { - template - friend class RefPtr; - template - friend class WeakPtr; - template - friend class NonnullRefPtr; - -public: - enum AdoptTag { - Adopt - }; - - RefPtr() - { - } - - RefPtr(T const* ptr) - : m_ptr(const_cast(ptr)) - { - ref_if_not_null(m_ptr); - } - - RefPtr(T const& object) - : m_ptr(const_cast(&object)) - { - m_ptr->ref(); - } - - RefPtr(AdoptTag, T& object) - : m_ptr(&object) - { - } - - RefPtr(RefPtr&& other) - : m_ptr(other.leak_ref()) - { - } - - ALWAYS_INLINE RefPtr(NonnullRefPtr const& other) - : m_ptr(const_cast(other.ptr())) - { - m_ptr->ref(); - } - - template - ALWAYS_INLINE RefPtr(NonnullRefPtr const& other) requires(IsConvertible) - : m_ptr(const_cast(static_cast(other.ptr()))) - { - m_ptr->ref(); - } - - template - ALWAYS_INLINE RefPtr(NonnullRefPtr&& other) requires(IsConvertible) - : m_ptr(static_cast(&other.leak_ref())) - { - } - - template - RefPtr(RefPtr&& other) requires(IsConvertible) - : m_ptr(static_cast(other.leak_ref())) - { - } - - RefPtr(RefPtr const& other) - : m_ptr(other.m_ptr) - { - ref_if_not_null(m_ptr); - } - - template - RefPtr(RefPtr const& other) requires(IsConvertible) - : m_ptr(const_cast(static_cast(other.ptr()))) - { - ref_if_not_null(m_ptr); - } - - ALWAYS_INLINE ~RefPtr() - { - clear(); - } - - template - RefPtr(OwnPtr const&) = delete; - template - RefPtr& operator=(OwnPtr const&) = delete; - - void swap(RefPtr& other) - { - AK::swap(m_ptr, other.m_ptr); - } - - template - void swap(RefPtr& other) requires(IsConvertible) - { - AK::swap(m_ptr, other.m_ptr); - } - - ALWAYS_INLINE RefPtr& operator=(RefPtr&& other) - { - RefPtr tmp{ move(other) }; - swap(tmp); - return *this; - } - - template - ALWAYS_INLINE RefPtr& operator=(RefPtr&& other) requires(IsConvertible) - { - RefPtr tmp{ move(other) }; - swap(tmp); - return *this; - } - - template - ALWAYS_INLINE RefPtr& operator=(NonnullRefPtr&& other) requires(IsConvertible) - { - RefPtr tmp{ move(other) }; - swap(tmp); - return *this; - } - - ALWAYS_INLINE RefPtr& operator=(NonnullRefPtr const& other) - { - RefPtr tmp{ other }; - swap(tmp); - return *this; - } - - template - ALWAYS_INLINE RefPtr& operator=(NonnullRefPtr const& other) requires(IsConvertible) - { - RefPtr tmp{ other }; - swap(tmp); - return *this; - } - - ALWAYS_INLINE RefPtr& operator=(RefPtr const& other) - { - RefPtr tmp{ other }; - swap(tmp); - return *this; - } - - template - ALWAYS_INLINE RefPtr& operator=(RefPtr const& other) requires(IsConvertible) - { - RefPtr tmp{ other }; - swap(tmp); - return *this; - } - - ALWAYS_INLINE RefPtr& operator=(T const* ptr) - { - RefPtr tmp{ ptr }; - swap(tmp); - return *this; - } - - ALWAYS_INLINE RefPtr& operator=(T const& object) - { - RefPtr tmp{ object }; - swap(tmp); - return *this; - } - - RefPtr& operator=(std::nullptr_t) - { - clear(); - return *this; - } - - ALWAYS_INLINE bool assign_if_null(RefPtr&& other) - { - if (this == &other) - return is_null(); - *this = move(other); - return true; - } - - template - ALWAYS_INLINE bool assign_if_null(RefPtr&& other) - { - if (this == &other) - return is_null(); - *this = move(other); - return true; - } - - ALWAYS_INLINE void clear() - { - unref_if_not_null(m_ptr); - m_ptr = nullptr; - } - - bool operator!() const { return !m_ptr; } - - T* leak_ref() - { - return exchange(m_ptr, nullptr); - } - - NonnullRefPtr release_nonnull() - { - auto* ptr = leak_ref(); - VERIFY(ptr); - return NonnullRefPtr(NonnullRefPtr::Adopt, *ptr); - } - - ALWAYS_INLINE T* ptr() { return as_ptr(); } - ALWAYS_INLINE const T* ptr() const { return as_ptr(); } - - ALWAYS_INLINE T* operator->() - { - return as_nonnull_ptr(); - } - - ALWAYS_INLINE const T* operator->() const - { - return as_nonnull_ptr(); - } - - ALWAYS_INLINE T& operator*() - { - return *as_nonnull_ptr(); - } - - ALWAYS_INLINE const T& operator*() const - { - return *as_nonnull_ptr(); - } - - ALWAYS_INLINE operator const T* () const { return as_ptr(); } - ALWAYS_INLINE operator T* () { return as_ptr(); } - - ALWAYS_INLINE operator bool() { return !is_null(); } - - bool operator==(std::nullptr_t) const { return is_null(); } - bool operator!=(std::nullptr_t) const { return !is_null(); } - - bool operator==(RefPtr const& other) const { return as_ptr() == other.as_ptr(); } - bool operator!=(RefPtr const& other) const { return as_ptr() != other.as_ptr(); } - - bool operator==(RefPtr& other) { return as_ptr() == other.as_ptr(); } - bool operator!=(RefPtr& other) { return as_ptr() != other.as_ptr(); } - - template - bool operator==(NonnullRefPtr const& other) const { return as_ptr() == other.m_ptr; } - template - bool operator!=(NonnullRefPtr const& other) const { return as_ptr() != other.m_ptr; } - - template - bool operator==(NonnullRefPtr& other) { return as_ptr() == other.m_ptr; } - template - bool operator!=(NonnullRefPtr& other) { return as_ptr() != other.m_ptr; } - - bool operator==(const T* other) const { return as_ptr() == other; } - bool operator!=(const T* other) const { return as_ptr() != other; } - - bool operator==(T* other) { return as_ptr() == other; } - bool operator!=(T* other) { return as_ptr() != other; } - - ALWAYS_INLINE bool is_null() const { return !m_ptr; } - -private: - ALWAYS_INLINE T* as_ptr() const - { - return m_ptr; - } - - ALWAYS_INLINE T* as_nonnull_ptr() const - { - VERIFY(m_ptr); - return m_ptr; - } - - T* m_ptr{ nullptr }; -}; - -template -struct Formatter> : Formatter { - ErrorOr format(FormatBuilder& builder, RefPtr const& value) - { - return Formatter::format(builder, value.ptr()); - } -}; - -template -struct Traits> : public GenericTraits> { - using PeekType = T*; - using ConstPeekType = const T*; - static unsigned hash(RefPtr const& p) { return ptr_hash(p.ptr()); } - static bool equals(RefPtr const& a, RefPtr const& b) { return a.ptr() == b.ptr(); } -}; - -template -ALWAYS_INLINE NonnullRefPtr static_ptr_cast(NonnullRefPtr const& ptr) -{ - return NonnullRefPtr(static_cast(*ptr)); -} - -template -ALWAYS_INLINE RefPtr static_ptr_cast(RefPtr const& ptr) -{ - return RefPtr(static_cast(ptr.ptr())); -} - -template -ALWAYS_INLINE void swap(RefPtr& a, RefPtr& b) requires(IsConvertible) -{ - a.swap(b); -} - -template -ALWAYS_INLINE RefPtr adopt_ref_if_nonnull(T* object) -{ - if (object) - return RefPtr(RefPtr::Adopt, *object); - return {}; -} - -template - requires(IsConstructible) ALWAYS_INLINE ErrorOr> try_make_ref_counted(Args&&... args) -{ - return adopt_nonnull_ref_or_enomem(new T(forward(args)...)); -} - -// FIXME: Remove once P0960R3 is available in Clang. -template -ALWAYS_INLINE ErrorOr> try_make_ref_counted(Args&&... args) -{ - return adopt_nonnull_ref_or_enomem(new T{ forward(args)... }); -} - -template -ALWAYS_INLINE ErrorOr> adopt_nonnull_ref_or_enomem(T* object) -{ - auto result = adopt_ref_if_nonnull(object); - if (!result) - return Error::from_errno(ENOMEM); - return result.release_nonnull(); -} - -} - -using AK::adopt_ref_if_nonnull; -using AK::RefPtr; -using AK::static_ptr_cast; -using AK::try_make_ref_counted; +/* + * Copyright (c) 2018-2020, Andreas Kling + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#define REFPTR_SCRUB_BYTE 0xe0 + +#include "Assertions.h" +#include "Atomic.h" +#include "Error.h" +#include "Format.h" +#include "NonnullRefPtr.h" +#include "StdLibExtras.h" +#include "Traits.h" +#include "Types.h" + +namespace AK { + +template +class OwnPtr; + +template +class RefPtr { + template + friend class RefPtr; + template + friend class WeakPtr; + template + friend class NonnullRefPtr; + +public: + enum AdoptTag { + Adopt + }; + + RefPtr() + { + } + + RefPtr(T const* ptr) + : m_ptr(const_cast(ptr)) + { + ref_if_not_null(m_ptr); + } + + RefPtr(T const& object) + : m_ptr(const_cast(&object)) + { + m_ptr->ref(); + } + + RefPtr(AdoptTag, T& object) + : m_ptr(&object) + { + } + + RefPtr(RefPtr&& other) + : m_ptr(other.leak_ref()) + { + } + + ALWAYS_INLINE RefPtr(NonnullRefPtr const& other) + : m_ptr(const_cast(other.ptr())) + { + m_ptr->ref(); + } + + template + ALWAYS_INLINE RefPtr(NonnullRefPtr const& other) requires(IsConvertible) + : m_ptr(const_cast(static_cast(other.ptr()))) + { + m_ptr->ref(); + } + + template + ALWAYS_INLINE RefPtr(NonnullRefPtr&& other) requires(IsConvertible) + : m_ptr(static_cast(&other.leak_ref())) + { + } + + template + RefPtr(RefPtr&& other) requires(IsConvertible) + : m_ptr(static_cast(other.leak_ref())) + { + } + + RefPtr(RefPtr const& other) + : m_ptr(other.m_ptr) + { + ref_if_not_null(m_ptr); + } + + template + RefPtr(RefPtr const& other) requires(IsConvertible) + : m_ptr(const_cast(static_cast(other.ptr()))) + { + ref_if_not_null(m_ptr); + } + + ALWAYS_INLINE ~RefPtr() + { + clear(); + } + + template + RefPtr(OwnPtr const&) = delete; + template + RefPtr& operator=(OwnPtr const&) = delete; + + void swap(RefPtr& other) + { + AK::swap(m_ptr, other.m_ptr); + } + + template + void swap(RefPtr& other) requires(IsConvertible) + { + AK::swap(m_ptr, other.m_ptr); + } + + ALWAYS_INLINE RefPtr& operator=(RefPtr&& other) + { + RefPtr tmp{ move(other) }; + swap(tmp); + return *this; + } + + template + ALWAYS_INLINE RefPtr& operator=(RefPtr&& other) requires(IsConvertible) + { + RefPtr tmp{ move(other) }; + swap(tmp); + return *this; + } + + template + ALWAYS_INLINE RefPtr& operator=(NonnullRefPtr&& other) requires(IsConvertible) + { + RefPtr tmp{ move(other) }; + swap(tmp); + return *this; + } + + ALWAYS_INLINE RefPtr& operator=(NonnullRefPtr const& other) + { + RefPtr tmp{ other }; + swap(tmp); + return *this; + } + + template + ALWAYS_INLINE RefPtr& operator=(NonnullRefPtr const& other) requires(IsConvertible) + { + RefPtr tmp{ other }; + swap(tmp); + return *this; + } + + ALWAYS_INLINE RefPtr& operator=(RefPtr const& other) + { + RefPtr tmp{ other }; + swap(tmp); + return *this; + } + + template + ALWAYS_INLINE RefPtr& operator=(RefPtr const& other) requires(IsConvertible) + { + RefPtr tmp{ other }; + swap(tmp); + return *this; + } + + ALWAYS_INLINE RefPtr& operator=(T const* ptr) + { + RefPtr tmp{ ptr }; + swap(tmp); + return *this; + } + + ALWAYS_INLINE RefPtr& operator=(T const& object) + { + RefPtr tmp{ object }; + swap(tmp); + return *this; + } + + RefPtr& operator=(std::nullptr_t) + { + clear(); + return *this; + } + + ALWAYS_INLINE bool assign_if_null(RefPtr&& other) + { + if (this == &other) + return is_null(); + *this = move(other); + return true; + } + + template + ALWAYS_INLINE bool assign_if_null(RefPtr&& other) + { + if (this == &other) + return is_null(); + *this = move(other); + return true; + } + + ALWAYS_INLINE void clear() + { + unref_if_not_null(m_ptr); + m_ptr = nullptr; + } + + bool operator!() const { return !m_ptr; } + + T* leak_ref() + { + return exchange(m_ptr, nullptr); + } + + NonnullRefPtr release_nonnull() + { + auto* ptr = leak_ref(); + VERIFY(ptr); + return NonnullRefPtr(NonnullRefPtr::Adopt, *ptr); + } + + ALWAYS_INLINE T* ptr() { return as_ptr(); } + ALWAYS_INLINE const T* ptr() const { return as_ptr(); } + + ALWAYS_INLINE T* operator->() + { + return as_nonnull_ptr(); + } + + ALWAYS_INLINE const T* operator->() const + { + return as_nonnull_ptr(); + } + + ALWAYS_INLINE T& operator*() + { + return *as_nonnull_ptr(); + } + + ALWAYS_INLINE const T& operator*() const + { + return *as_nonnull_ptr(); + } + + ALWAYS_INLINE operator const T* () const { return as_ptr(); } + ALWAYS_INLINE operator T* () { return as_ptr(); } + + ALWAYS_INLINE operator bool() { return !is_null(); } + + bool operator==(std::nullptr_t) const { return is_null(); } + bool operator!=(std::nullptr_t) const { return !is_null(); } + + bool operator==(RefPtr const& other) const { return as_ptr() == other.as_ptr(); } + bool operator!=(RefPtr const& other) const { return as_ptr() != other.as_ptr(); } + + bool operator==(RefPtr& other) { return as_ptr() == other.as_ptr(); } + bool operator!=(RefPtr& other) { return as_ptr() != other.as_ptr(); } + + template + bool operator==(NonnullRefPtr const& other) const { return as_ptr() == other.m_ptr; } + template + bool operator!=(NonnullRefPtr const& other) const { return as_ptr() != other.m_ptr; } + + template + bool operator==(NonnullRefPtr& other) { return as_ptr() == other.m_ptr; } + template + bool operator!=(NonnullRefPtr& other) { return as_ptr() != other.m_ptr; } + + bool operator==(const T* other) const { return as_ptr() == other; } + bool operator!=(const T* other) const { return as_ptr() != other; } + + bool operator==(T* other) { return as_ptr() == other; } + bool operator!=(T* other) { return as_ptr() != other; } + + ALWAYS_INLINE bool is_null() const { return !m_ptr; } + +private: + ALWAYS_INLINE T* as_ptr() const + { + return m_ptr; + } + + ALWAYS_INLINE T* as_nonnull_ptr() const + { + VERIFY(m_ptr); + return m_ptr; + } + + T* m_ptr{ nullptr }; +}; + +template +struct Formatter> : Formatter { + ErrorOr format(FormatBuilder& builder, RefPtr const& value) + { + return Formatter::format(builder, value.ptr()); + } +}; + +template +struct Traits> : public GenericTraits> { + using PeekType = T*; + using ConstPeekType = const T*; + static unsigned hash(RefPtr const& p) { return ptr_hash(p.ptr()); } + static bool equals(RefPtr const& a, RefPtr const& b) { return a.ptr() == b.ptr(); } +}; + +template +ALWAYS_INLINE NonnullRefPtr static_ptr_cast(NonnullRefPtr const& ptr) +{ + return NonnullRefPtr(static_cast(*ptr)); +} + +template +ALWAYS_INLINE RefPtr static_ptr_cast(RefPtr const& ptr) +{ + return RefPtr(static_cast(ptr.ptr())); +} + +template +ALWAYS_INLINE void swap(RefPtr& a, RefPtr& b) requires(IsConvertible) +{ + a.swap(b); +} + +template +ALWAYS_INLINE RefPtr adopt_ref_if_nonnull(T* object) +{ + if (object) + return RefPtr(RefPtr::Adopt, *object); + return {}; +} + +template + requires(IsConstructible) ALWAYS_INLINE ErrorOr> try_make_ref_counted(Args&&... args) +{ + return adopt_nonnull_ref_or_enomem(new T(forward(args)...)); +} + +// FIXME: Remove once P0960R3 is available in Clang. +template +ALWAYS_INLINE ErrorOr> try_make_ref_counted(Args&&... args) +{ + return adopt_nonnull_ref_or_enomem(new T{ forward(args)... }); +} + +template +ALWAYS_INLINE ErrorOr> adopt_nonnull_ref_or_enomem(T* object) +{ + auto result = adopt_ref_if_nonnull(object); + if (!result) + return Error::from_errno(ENOMEM); + return result.release_nonnull(); +} + +} + +using AK::adopt_ref_if_nonnull; +using AK::RefPtr; +using AK::static_ptr_cast; +using AK::try_make_ref_counted; diff --git a/AK/AK/Result.h b/LibC-Shim/AK/Result.h similarity index 90% rename from AK/AK/Result.h rename to LibC-Shim/AK/Result.h index 8e9979f..c113e0a 100644 --- a/AK/AK/Result.h +++ b/LibC-Shim/AK/Result.h @@ -1,90 +1,90 @@ -/* - * Copyright (c) 2018-2020, Andreas Kling - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include "./AK/Assertions.h" -#include "./AK/Optional.h" - -namespace AK { - -template -class Result { -public: - using ValueType = ValueT; - using ErrorType = ErrorT; - - Result(ValueType const& res) - { - } - - Result(ErrorType const& error) - { - } - - Result() - { - } - - Result(Result&& other) = default; - Result(Result const& other) = default; - ~Result() = default; - - ValueType& value(); - - ErrorType& error(); - - bool is_error() const; - - ValueType release_value(); - - ErrorType release_error(); - -private: - ValueType m_result; - ErrorType m_error; -}; - -// Partial specialization for void value type -template -class Result { -public: - using ValueType = void; - using ErrorType = ErrorT; - - Result(ErrorType const& error) - { - } - - Result(ErrorType&& error) - { - } - - Result() - { - } - - Result(Result&& other) = default; - Result(Result const& other) = default; - ~Result() = default; - - // For compatibility with TRY(). - void value() {}; - void release_value() {}; - - ErrorType& error(); - - bool is_error() const; - - ErrorType release_error(); - -private: - Optional m_error; -}; - -} - -using AK::Result; +/* + * Copyright (c) 2018-2020, Andreas Kling + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include "Assertions.h" +#include "Optional.h" + +namespace AK { + +template +class Result { +public: + using ValueType = ValueT; + using ErrorType = ErrorT; + + Result(ValueType const& res) + { + } + + Result(ErrorType const& error) + { + } + + Result() + { + } + + Result(Result&& other) = default; + Result(Result const& other) = default; + ~Result() = default; + + ValueType& value(); + + ErrorType& error(); + + bool is_error() const; + + ValueType release_value(); + + ErrorType release_error(); + +private: + ValueType m_result; + ErrorType m_error; +}; + +// Partial specialization for void value type +template +class Result { +public: + using ValueType = void; + using ErrorType = ErrorT; + + Result(ErrorType const& error) + { + } + + Result(ErrorType&& error) + { + } + + Result() + { + } + + Result(Result&& other) = default; + Result(Result const& other) = default; + ~Result() = default; + + // For compatibility with TRY(). + void value() {}; + void release_value() {}; + + ErrorType& error(); + + bool is_error() const; + + ErrorType release_error(); + +private: + Optional m_error; +}; + +} + +using AK::Result; diff --git a/AK/AK/ReverseIterator.h b/LibC-Shim/AK/ReverseIterator.h similarity index 96% rename from AK/AK/ReverseIterator.h rename to LibC-Shim/AK/ReverseIterator.h index 3f7721d..0455313 100644 --- a/AK/AK/ReverseIterator.h +++ b/LibC-Shim/AK/ReverseIterator.h @@ -1,108 +1,108 @@ -/* - * Copyright (c) 2022, the SerenityOS developers. - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include "./AK/Forward.h" - -namespace AK { - -template -class SimpleReverseIterator { -public: - friend Container; - - constexpr bool is_end() const { return m_index == SimpleReverseIterator::rend(m_container).m_index; } - constexpr int index() const { return m_index; } - - constexpr bool operator==(SimpleReverseIterator other) const { return m_index == other.m_index; } - constexpr bool operator!=(SimpleReverseIterator other) const { return m_index != other.m_index; } - constexpr bool operator<(SimpleReverseIterator other) const { return m_index < other.m_index; } - constexpr bool operator>(SimpleReverseIterator other) const { return m_index > other.m_index; } - constexpr bool operator<=(SimpleReverseIterator other) const { return m_index <= other.m_index; } - constexpr bool operator>=(SimpleReverseIterator other) const { return m_index >= other.m_index; } - - constexpr SimpleReverseIterator operator+(int delta) const { return SimpleReverseIterator{ m_container, m_index - delta }; } - constexpr SimpleReverseIterator operator-(int delta) const { return SimpleReverseIterator{ m_container, m_index + delta }; } - - constexpr SimpleReverseIterator operator++() - { - --m_index; - return *this; - } - constexpr SimpleReverseIterator operator++(int) - { - --m_index; - return SimpleReverseIterator{ m_container, m_index + 1 }; - } - constexpr SimpleReverseIterator operator--() - { - ++m_index; - return *this; - } - constexpr SimpleReverseIterator operator--(int) - { - ++m_index; - return SimpleReverseIterator{ m_container, m_index - 1 }; - } - - ALWAYS_INLINE constexpr ValueType const& operator*() const { return m_container[m_index]; } - ALWAYS_INLINE constexpr ValueType& operator*() { return m_container[m_index]; } - - ALWAYS_INLINE constexpr ValueType const* operator->() const { return &m_container[m_index]; } - ALWAYS_INLINE constexpr ValueType* operator->() { return &m_container[m_index]; } - - SimpleReverseIterator& operator=(SimpleReverseIterator const& other) - { - m_index = other.m_index; - return *this; - } - SimpleReverseIterator(SimpleReverseIterator const& obj) = default; - -private: - static constexpr SimpleReverseIterator rbegin(Container& container) - { - using RawContainerType = RemoveCV; - if constexpr (IsSame || IsSame) - return { container, static_cast(container.length()) - 1 }; - else - return { container, static_cast(container.size()) - 1 }; - } - - static constexpr SimpleReverseIterator rend(Container& container) - { - return { container, -1 }; - } - - constexpr SimpleReverseIterator(Container& container, int index) - : m_container(container) - , m_index(index) - { - } - - Container& m_container; - int m_index{ 0 }; -}; - -namespace ReverseWrapper { - - template - struct ReverseWrapper { - Container& container; - }; - - template - auto begin(ReverseWrapper wrapper) { return wrapper.container.rbegin(); } - - template - auto end(ReverseWrapper wrapper) { return wrapper.container.rend(); } - - template - ReverseWrapper in_reverse(Container&& container) { return { container }; } - -} - -} +/* + * Copyright (c) 2022, the SerenityOS developers. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include "Forward.h" + +namespace AK { + +template +class SimpleReverseIterator { +public: + friend Container; + + constexpr bool is_end() const { return m_index == SimpleReverseIterator::rend(m_container).m_index; } + constexpr int index() const { return m_index; } + + constexpr bool operator==(SimpleReverseIterator other) const { return m_index == other.m_index; } + constexpr bool operator!=(SimpleReverseIterator other) const { return m_index != other.m_index; } + constexpr bool operator<(SimpleReverseIterator other) const { return m_index < other.m_index; } + constexpr bool operator>(SimpleReverseIterator other) const { return m_index > other.m_index; } + constexpr bool operator<=(SimpleReverseIterator other) const { return m_index <= other.m_index; } + constexpr bool operator>=(SimpleReverseIterator other) const { return m_index >= other.m_index; } + + constexpr SimpleReverseIterator operator+(int delta) const { return SimpleReverseIterator{ m_container, m_index - delta }; } + constexpr SimpleReverseIterator operator-(int delta) const { return SimpleReverseIterator{ m_container, m_index + delta }; } + + constexpr SimpleReverseIterator operator++() + { + --m_index; + return *this; + } + constexpr SimpleReverseIterator operator++(int) + { + --m_index; + return SimpleReverseIterator{ m_container, m_index + 1 }; + } + constexpr SimpleReverseIterator operator--() + { + ++m_index; + return *this; + } + constexpr SimpleReverseIterator operator--(int) + { + ++m_index; + return SimpleReverseIterator{ m_container, m_index - 1 }; + } + + ALWAYS_INLINE constexpr ValueType const& operator*() const { return m_container[m_index]; } + ALWAYS_INLINE constexpr ValueType& operator*() { return m_container[m_index]; } + + ALWAYS_INLINE constexpr ValueType const* operator->() const { return &m_container[m_index]; } + ALWAYS_INLINE constexpr ValueType* operator->() { return &m_container[m_index]; } + + SimpleReverseIterator& operator=(SimpleReverseIterator const& other) + { + m_index = other.m_index; + return *this; + } + SimpleReverseIterator(SimpleReverseIterator const& obj) = default; + +private: + static constexpr SimpleReverseIterator rbegin(Container& container) + { + using RawContainerType = RemoveCV; + if constexpr (IsSame || IsSame) + return { container, static_cast(container.length()) - 1 }; + else + return { container, static_cast(container.size()) - 1 }; + } + + static constexpr SimpleReverseIterator rend(Container& container) + { + return { container, -1 }; + } + + constexpr SimpleReverseIterator(Container& container, int index) + : m_container(container) + , m_index(index) + { + } + + Container& m_container; + int m_index{ 0 }; +}; + +namespace ReverseWrapper { + + template + struct ReverseWrapper { + Container& container; + }; + + template + auto begin(ReverseWrapper wrapper) { return wrapper.container.rbegin(); } + + template + auto end(ReverseWrapper wrapper) { return wrapper.container.rend(); } + + template + ReverseWrapper in_reverse(Container&& container) { return { container }; } + +} + +} diff --git a/AK/AK/SIMD.h b/LibC-Shim/AK/SIMD.h similarity index 61% rename from AK/AK/SIMD.h rename to LibC-Shim/AK/SIMD.h index 5c9fc39..08df8b1 100644 --- a/AK/AK/SIMD.h +++ b/LibC-Shim/AK/SIMD.h @@ -1,6 +1,6 @@ #pragma once -#include "./AK/Types.h" +#include "Types.h" namespace AK::SIMD { diff --git a/AK/AK/ScopeGuard.h b/LibC-Shim/AK/ScopeGuard.h similarity index 90% rename from AK/AK/ScopeGuard.h rename to LibC-Shim/AK/ScopeGuard.h index 0e8572e..7e402ef 100644 --- a/AK/AK/ScopeGuard.h +++ b/LibC-Shim/AK/ScopeGuard.h @@ -1,54 +1,54 @@ -/* - * Copyright (c) 2018-2020, Andreas Kling - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include "./AK/StdLibExtras.h" - -namespace AK { - -template -class ScopeGuard { -public: - ScopeGuard(Callback callback) - : m_callback(move(callback)) - { - } - - ~ScopeGuard() - { - m_callback(); - } - -private: - Callback m_callback; -}; - -template -class ArmedScopeGuard { -public: - ArmedScopeGuard(Callback callback) - : m_callback(move(callback)) - { - } - - ~ArmedScopeGuard() - { - if (m_armed) - m_callback(); - } - - void disarm() { m_armed = false; } - -private: - Callback m_callback; - bool m_armed { true }; -}; - -} - -using AK::ArmedScopeGuard; -using AK::ScopeGuard; +/* + * Copyright (c) 2018-2020, Andreas Kling + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include "StdLibExtras.h" + +namespace AK { + +template +class ScopeGuard { +public: + ScopeGuard(Callback callback) + : m_callback(move(callback)) + { + } + + ~ScopeGuard() + { + m_callback(); + } + +private: + Callback m_callback; +}; + +template +class ArmedScopeGuard { +public: + ArmedScopeGuard(Callback callback) + : m_callback(move(callback)) + { + } + + ~ArmedScopeGuard() + { + if (m_armed) + m_callback(); + } + + void disarm() { m_armed = false; } + +private: + Callback m_callback; + bool m_armed { true }; +}; + +} + +using AK::ArmedScopeGuard; +using AK::ScopeGuard; diff --git a/AK/AK/SinglyLinkedList.h b/LibC-Shim/AK/SinglyLinkedList.h similarity index 92% rename from AK/AK/SinglyLinkedList.h rename to LibC-Shim/AK/SinglyLinkedList.h index a903785..e055cd7 100644 --- a/AK/AK/SinglyLinkedList.h +++ b/LibC-Shim/AK/SinglyLinkedList.h @@ -1,134 +1,134 @@ -/* - * Copyright (c) 2018-2020, Andreas Kling - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include "./AK/Assertions.h" -#include "./AK/Find.h" -#include "./AK/StdLibExtras.h" -#include "./AK/Traits.h" -#include "./AK/Types.h" - -namespace AK { - -template -class SinglyLinkedListIterator { -public: - SinglyLinkedListIterator() = default; - bool operator!=(SinglyLinkedListIterator const& other) const; - SinglyLinkedListIterator& operator++(); - ElementType& operator*(); - ElementType* operator->(); - bool is_end() const { return !m_node; } - bool is_begin() const { return !m_prev; } - void remove(ListType& list); - -private: - friend ListType; - explicit SinglyLinkedListIterator(typename ListType::Node* node, typename ListType::Node* prev = nullptr) - : m_node(node) - , m_prev(prev) - , m_next(node ? node->next : nullptr) - { - } - typename ListType::Node* m_node { nullptr }; - typename ListType::Node* m_prev { nullptr }; - typename ListType::Node* m_next { nullptr }; - bool m_removed { false }; -}; - -template -class SinglyLinkedList { -private: - struct Node { - explicit Node(T&& v) - : value(move(v)) - { - } - explicit Node(const T& v) - : value(v) - { - } - T value; - Node* next { nullptr }; - }; - -public: - SinglyLinkedList() = default; - SinglyLinkedList(SinglyLinkedList const& other) = delete; - SinglyLinkedList(SinglyLinkedList&& other) - : m_head(other.m_head) - , m_tail(other.m_tail) - { - other.m_head = nullptr; - other.m_tail = nullptr; - } - SinglyLinkedList& operator=(SinglyLinkedList const& other) = delete; - SinglyLinkedList& operator=(SinglyLinkedList&&) = delete; - - ~SinglyLinkedList() { clear(); } - - bool is_empty() const { return !head(); } - - ALWAYS_INLINE size_t size_slow() const; - - void clear(); - - T& first(); - T& last(); - - T take_first(); - - template - void append(U&& value); - - template - void prepend(U&& value); - - bool contains_slow(const T& value) const; - - using Iterator = SinglyLinkedListIterator; - friend Iterator; - Iterator begin() { return Iterator(m_head); } - Iterator end() { return {}; } - - using ConstIterator = SinglyLinkedListIterator; - friend ConstIterator; - ConstIterator begin() const { return ConstIterator(m_head); } - ConstIterator end() const { return {}; } - - template - ConstIterator find_if(TUnaryPredicate&& pred) const; - - template - Iterator find_if(TUnaryPredicate&& pred); - - ConstIterator find(const T& value) const; - - Iterator find(const T& value); - - template - void insert_before(Iterator iterator, U&& value); - - template - void insert_after(Iterator iterator, U&& value); - - void remove(Iterator& iterator); - -private: - Node* head() { return m_head; } - Node const* head() const { return m_head; } - - Node* tail() { return m_tail; } - Node const* tail() const { return m_tail; } - - Node* m_head { nullptr }; - Node* m_tail { nullptr }; -}; - -} - -using AK::SinglyLinkedList; +/* + * Copyright (c) 2018-2020, Andreas Kling + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include "Assertions.h" +#include "Find.h" +#include "StdLibExtras.h" +#include "Traits.h" +#include "Types.h" + +namespace AK { + +template +class SinglyLinkedListIterator { +public: + SinglyLinkedListIterator() = default; + bool operator!=(SinglyLinkedListIterator const& other) const; + SinglyLinkedListIterator& operator++(); + ElementType& operator*(); + ElementType* operator->(); + bool is_end() const { return !m_node; } + bool is_begin() const { return !m_prev; } + void remove(ListType& list); + +private: + friend ListType; + explicit SinglyLinkedListIterator(typename ListType::Node* node, typename ListType::Node* prev = nullptr) + : m_node(node) + , m_prev(prev) + , m_next(node ? node->next : nullptr) + { + } + typename ListType::Node* m_node { nullptr }; + typename ListType::Node* m_prev { nullptr }; + typename ListType::Node* m_next { nullptr }; + bool m_removed { false }; +}; + +template +class SinglyLinkedList { +private: + struct Node { + explicit Node(T&& v) + : value(move(v)) + { + } + explicit Node(const T& v) + : value(v) + { + } + T value; + Node* next { nullptr }; + }; + +public: + SinglyLinkedList() = default; + SinglyLinkedList(SinglyLinkedList const& other) = delete; + SinglyLinkedList(SinglyLinkedList&& other) + : m_head(other.m_head) + , m_tail(other.m_tail) + { + other.m_head = nullptr; + other.m_tail = nullptr; + } + SinglyLinkedList& operator=(SinglyLinkedList const& other) = delete; + SinglyLinkedList& operator=(SinglyLinkedList&&) = delete; + + ~SinglyLinkedList() { clear(); } + + bool is_empty() const { return !head(); } + + ALWAYS_INLINE size_t size_slow() const; + + void clear(); + + T& first(); + T& last(); + + T take_first(); + + template + void append(U&& value); + + template + void prepend(U&& value); + + bool contains_slow(const T& value) const; + + using Iterator = SinglyLinkedListIterator; + friend Iterator; + Iterator begin() { return Iterator(m_head); } + Iterator end() { return {}; } + + using ConstIterator = SinglyLinkedListIterator; + friend ConstIterator; + ConstIterator begin() const { return ConstIterator(m_head); } + ConstIterator end() const { return {}; } + + template + ConstIterator find_if(TUnaryPredicate&& pred) const; + + template + Iterator find_if(TUnaryPredicate&& pred); + + ConstIterator find(const T& value) const; + + Iterator find(const T& value); + + template + void insert_before(Iterator iterator, U&& value); + + template + void insert_after(Iterator iterator, U&& value); + + void remove(Iterator& iterator); + +private: + Node* head() { return m_head; } + Node const* head() const { return m_head; } + + Node* tail() { return m_tail; } + Node const* tail() const { return m_tail; } + + Node* m_head { nullptr }; + Node* m_tail { nullptr }; +}; + +} + +using AK::SinglyLinkedList; diff --git a/AK/AK/Span.h b/LibC-Shim/AK/Span.h similarity index 93% rename from AK/AK/Span.h rename to LibC-Shim/AK/Span.h index e3be6c1..05df382 100644 --- a/AK/AK/Span.h +++ b/LibC-Shim/AK/Span.h @@ -1,168 +1,168 @@ -#pragma once - -#include "./AK/Array.h" -#include "./AK/Assertions.h" -#include "./AK/Iterator.h" -#include "./AK/TypedTransfer.h" -#include "./AK/Types.h" - -namespace AK { - -namespace Detail { - -template -class Span { -public: - ALWAYS_INLINE constexpr Span() = default; - - ALWAYS_INLINE constexpr Span(T* values, size_t size) - : m_values(values) - , m_size(size) - { - } - - template - ALWAYS_INLINE constexpr Span(T(&values)[size]) - : m_values(values) - , m_size(size) - { - } - - template - ALWAYS_INLINE constexpr Span(Array& array) - : m_values(array.data()) - , m_size(size) - { - } - - template - requires(IsConst) - ALWAYS_INLINE constexpr Span(Array const& array) - : m_values(array.data()) - , m_size(size) - { - } - -protected: - T* m_values{ nullptr }; - size_t m_size{ 0 }; -}; - -template<> -class Span { -public: - ALWAYS_INLINE constexpr Span() = default; - - ALWAYS_INLINE constexpr Span(u8* values, size_t size) - : m_values(values) - , m_size(size) - { - } - ALWAYS_INLINE Span(void* values, size_t size) - : m_values(reinterpret_cast(values)) - , m_size(size) - { - } - -protected: - u8* m_values{ nullptr }; - size_t m_size{ 0 }; -}; - -template<> -class Span { -public: - ALWAYS_INLINE constexpr Span() = default; - - ALWAYS_INLINE constexpr Span(u8 const* values, size_t size) - : m_values(values) - , m_size(size) - { - } - ALWAYS_INLINE Span(void const* values, size_t size) - : m_values(reinterpret_cast(values)) - , m_size(size) - { - } - ALWAYS_INLINE Span(char const* values, size_t size) - : m_values(reinterpret_cast(values)) - , m_size(size) - { - } - -protected: - u8 const* m_values{ nullptr }; - size_t m_size{ 0 }; -}; - -} - -template -class Span : public Detail::Span { -public: - using Detail::Span::Span; - - constexpr Span() = default; - - ALWAYS_INLINE constexpr T const* data() const { return this->m_values; } - ALWAYS_INLINE constexpr T* data() { return this->m_values; } - - ALWAYS_INLINE constexpr T* offset_pointer(size_t offset); - - using ConstIterator = SimpleIterator; - using Iterator = SimpleIterator; - - constexpr ConstIterator begin() const { return ConstIterator::begin(*this); } - constexpr Iterator begin() { return Iterator::begin(*this); } - - constexpr ConstIterator end() const { return ConstIterator::end(*this); } - constexpr Iterator end() { return Iterator::end(*this); } - - ALWAYS_INLINE constexpr size_t size() const { return this->m_size; } - ALWAYS_INLINE constexpr bool is_null() const { return this->m_values == nullptr; } - ALWAYS_INLINE constexpr bool is_empty() const { return this->m_size == 0; } - - ALWAYS_INLINE constexpr Span slice(size_t start, size_t length) const; - ALWAYS_INLINE constexpr Span slice(size_t start) const; - ALWAYS_INLINE constexpr Span slice_from_end(size_t count) const; - - ALWAYS_INLINE constexpr Span trim(size_t length) const; - - ALWAYS_INLINE constexpr T* offset(size_t start) const; - - ALWAYS_INLINE constexpr void overwrite(size_t offset, void const* data, size_t data_size); - - ALWAYS_INLINE constexpr size_t copy_to(Span> other) const; - - ALWAYS_INLINE constexpr size_t copy_trimmed_to(Span> other) const; - - ALWAYS_INLINE constexpr size_t fill(T const& value); - - bool constexpr contains_slow(T const& value) const; - - bool constexpr starts_with(Span other) const; - - ALWAYS_INLINE constexpr T& at(size_t index); - - ALWAYS_INLINE constexpr T& last(); - - ALWAYS_INLINE constexpr T& operator[](size_t index); - - constexpr bool operator==(Span const& other) const; - - constexpr operator Span() const; -}; - -/*template -struct Traits> : public GenericTraits> { - static unsigned hash(Span const& span); -};*/ - -using ReadonlyBytes = Span; -using Bytes = Span; - -} - -using AK::Bytes; -using AK::ReadonlyBytes; -using AK::Span; +#pragma once + +#include "Array.h" +#include "Assertions.h" +#include "Iterator.h" +#include "TypedTransfer.h" +#include "Types.h" + +namespace AK { + +namespace Detail { + +template +class Span { +public: + ALWAYS_INLINE constexpr Span() = default; + + ALWAYS_INLINE constexpr Span(T* values, size_t size) + : m_values(values) + , m_size(size) + { + } + + template + ALWAYS_INLINE constexpr Span(T(&values)[size]) + : m_values(values) + , m_size(size) + { + } + + template + ALWAYS_INLINE constexpr Span(Array& array) + : m_values(array.data()) + , m_size(size) + { + } + + template + requires(IsConst) + ALWAYS_INLINE constexpr Span(Array const& array) + : m_values(array.data()) + , m_size(size) + { + } + +protected: + T* m_values{ nullptr }; + size_t m_size{ 0 }; +}; + +template<> +class Span { +public: + ALWAYS_INLINE constexpr Span() = default; + + ALWAYS_INLINE constexpr Span(u8* values, size_t size) + : m_values(values) + , m_size(size) + { + } + ALWAYS_INLINE Span(void* values, size_t size) + : m_values(reinterpret_cast(values)) + , m_size(size) + { + } + +protected: + u8* m_values{ nullptr }; + size_t m_size{ 0 }; +}; + +template<> +class Span { +public: + ALWAYS_INLINE constexpr Span() = default; + + ALWAYS_INLINE constexpr Span(u8 const* values, size_t size) + : m_values(values) + , m_size(size) + { + } + ALWAYS_INLINE Span(void const* values, size_t size) + : m_values(reinterpret_cast(values)) + , m_size(size) + { + } + ALWAYS_INLINE Span(char const* values, size_t size) + : m_values(reinterpret_cast(values)) + , m_size(size) + { + } + +protected: + u8 const* m_values{ nullptr }; + size_t m_size{ 0 }; +}; + +} + +template +class Span : public Detail::Span { +public: + using Detail::Span::Span; + + constexpr Span() = default; + + ALWAYS_INLINE constexpr T const* data() const { return this->m_values; } + ALWAYS_INLINE constexpr T* data() { return this->m_values; } + + ALWAYS_INLINE constexpr T* offset_pointer(size_t offset); + + using ConstIterator = SimpleIterator; + using Iterator = SimpleIterator; + + constexpr ConstIterator begin() const { return ConstIterator::begin(*this); } + constexpr Iterator begin() { return Iterator::begin(*this); } + + constexpr ConstIterator end() const { return ConstIterator::end(*this); } + constexpr Iterator end() { return Iterator::end(*this); } + + ALWAYS_INLINE constexpr size_t size() const { return this->m_size; } + ALWAYS_INLINE constexpr bool is_null() const { return this->m_values == nullptr; } + ALWAYS_INLINE constexpr bool is_empty() const { return this->m_size == 0; } + + ALWAYS_INLINE constexpr Span slice(size_t start, size_t length) const; + ALWAYS_INLINE constexpr Span slice(size_t start) const; + ALWAYS_INLINE constexpr Span slice_from_end(size_t count) const; + + ALWAYS_INLINE constexpr Span trim(size_t length) const; + + ALWAYS_INLINE constexpr T* offset(size_t start) const; + + ALWAYS_INLINE constexpr void overwrite(size_t offset, void const* data, size_t data_size); + + ALWAYS_INLINE constexpr size_t copy_to(Span> other) const; + + ALWAYS_INLINE constexpr size_t copy_trimmed_to(Span> other) const; + + ALWAYS_INLINE constexpr size_t fill(T const& value); + + bool constexpr contains_slow(T const& value) const; + + bool constexpr starts_with(Span other) const; + + ALWAYS_INLINE constexpr T& at(size_t index); + + ALWAYS_INLINE constexpr T& last(); + + ALWAYS_INLINE constexpr T& operator[](size_t index); + + constexpr bool operator==(Span const& other) const; + + constexpr operator Span() const; +}; + +/*template +struct Traits> : public GenericTraits> { + static unsigned hash(Span const& span); +};*/ + +using ReadonlyBytes = Span; +using Bytes = Span; + +} + +using AK::Bytes; +using AK::ReadonlyBytes; +using AK::Span; diff --git a/AK/AK/StackInfo.h b/LibC-Shim/AK/StackInfo.h similarity index 90% rename from AK/AK/StackInfo.h rename to LibC-Shim/AK/StackInfo.h index 19666b1..bd8649a 100644 --- a/AK/AK/StackInfo.h +++ b/LibC-Shim/AK/StackInfo.h @@ -1,34 +1,34 @@ -/* - * Copyright (c) 2020, the SerenityOS developers. - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include "./AK/Types.h" - -namespace AK { - -class StackInfo { -public: - StackInfo() = default; - - FlatPtr base() const { return m_base; } - FlatPtr top() const { return m_top; } - size_t size() const { return m_size; } - size_t size_free() const - { - FlatPtr dummy; - return reinterpret_cast(&dummy) - m_base; - } - -private: - FlatPtr m_base; - FlatPtr m_top; - size_t m_size; -}; - -} - -using AK::StackInfo; +/* + * Copyright (c) 2020, the SerenityOS developers. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include "Types.h" + +namespace AK { + +class StackInfo { +public: + StackInfo() = default; + + FlatPtr base() const { return m_base; } + FlatPtr top() const { return m_top; } + size_t size() const { return m_size; } + size_t size_free() const + { + FlatPtr dummy; + return reinterpret_cast(&dummy) - m_base; + } + +private: + FlatPtr m_base; + FlatPtr m_top; + size_t m_size; +}; + +} + +using AK::StackInfo; diff --git a/AK/AK/StdLibExtraDetails.h b/LibC-Shim/AK/StdLibExtraDetails.h similarity index 96% rename from AK/AK/StdLibExtraDetails.h rename to LibC-Shim/AK/StdLibExtraDetails.h index 3e246c6..afc165c 100644 --- a/AK/AK/StdLibExtraDetails.h +++ b/LibC-Shim/AK/StdLibExtraDetails.h @@ -1,669 +1,669 @@ -/* - * Copyright (c) 2018-2021, Andreas Kling - * Copyright (c) 2021, Ali Mohammad Pur - * Copyright (c) 2021, Daniel Bertalan - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include - -namespace AK::Detail { - -template -struct IntegralConstant { - static constexpr T value = v; - using ValueType = T; - using Type = IntegralConstant; - constexpr operator ValueType() const { return value; } - constexpr ValueType operator()() const { return value; } -}; - -using FalseType = IntegralConstant; -using TrueType = IntegralConstant; - -template -using AddConst = const T; - -template -struct __AddConstToReferencedType { - using Type = T; -}; - -template -struct __AddConstToReferencedType { - using Type = AddConst&; -}; - -template -struct __AddConstToReferencedType { - using Type = AddConst&&; -}; - -template -using AddConstToReferencedType = typename __AddConstToReferencedType::Type; - -template -struct __RemoveConst { - using Type = T; -}; -template -struct __RemoveConst { - using Type = T; -}; -template -using RemoveConst = typename __RemoveConst::Type; - -template -struct __RemoveVolatile { - using Type = T; -}; - -template -struct __RemoveVolatile { - using Type = T; -}; - -template -using RemoveVolatile = typename __RemoveVolatile::Type; - -template -using RemoveCV = RemoveVolatile>; - -template -using VoidType = void; - -template -inline constexpr bool IsLvalueReference = false; - -template -inline constexpr bool IsLvalueReference = true; - -template -inline constexpr bool __IsPointerHelper = false; - -template -inline constexpr bool __IsPointerHelper = true; - -template -inline constexpr bool IsPointer = __IsPointerHelper>; - -template -inline constexpr bool IsFunction = false; -template -inline constexpr bool IsFunction = true; -template -inline constexpr bool IsFunction = true; -template -inline constexpr bool IsFunction = true; -template -inline constexpr bool IsFunction = true; -template -inline constexpr bool IsFunction = true; -template -inline constexpr bool IsFunction = true; -template -inline constexpr bool IsFunction = true; -template -inline constexpr bool IsFunction = true; -template -inline constexpr bool IsFunction = true; -template -inline constexpr bool IsFunction = true; -template -inline constexpr bool IsFunction = true; -template -inline constexpr bool IsFunction = true; -template -inline constexpr bool IsFunction = true; -template -inline constexpr bool IsFunction = true; -template -inline constexpr bool IsFunction = true; -template -inline constexpr bool IsFunction = true; -template -inline constexpr bool IsFunction = true; -template -inline constexpr bool IsFunction = true; -template -inline constexpr bool IsFunction = true; -template -inline constexpr bool IsFunction = true; -template -inline constexpr bool IsFunction = true; -template -inline constexpr bool IsFunction = true; -template -inline constexpr bool IsFunction = true; -template -inline constexpr bool IsFunction = true; - -template -inline constexpr bool IsRvalueReference = false; -template -inline constexpr bool IsRvalueReference = true; - -template -struct __RemovePointer { - using Type = T; -}; -template -struct __RemovePointer { - using Type = T; -}; -template -struct __RemovePointer { - using Type = T; -}; -template -struct __RemovePointer { - using Type = T; -}; -template -struct __RemovePointer { - using Type = T; -}; -template -using RemovePointer = typename __RemovePointer::Type; - -template -inline constexpr bool IsSame = false; - -template -inline constexpr bool IsSame = true; - -template -struct __Conditional { - using Type = TrueType; -}; - -template -struct __Conditional { - using Type = FalseType; -}; - -template -using Conditional = typename __Conditional::Type; - -template -inline constexpr bool IsNullPointer = IsSame>; - -template -struct __RemoveReference { - using Type = T; -}; -template -struct __RemoveReference { - using Type = T; -}; -template -struct __RemoveReference { - using Type = T; -}; - -template -using RemoveReference = typename __RemoveReference::Type; - -template -using RemoveCVReference = RemoveCV>; - -template -struct __MakeUnsigned { - using Type = void; -}; -template<> -struct __MakeUnsigned { - using Type = unsigned char; -}; -template<> -struct __MakeUnsigned { - using Type = unsigned short; -}; -template<> -struct __MakeUnsigned { - using Type = unsigned int; -}; -template<> -struct __MakeUnsigned { - using Type = unsigned long; -}; -template<> -struct __MakeUnsigned { - using Type = unsigned long long; -}; -template<> -struct __MakeUnsigned { - using Type = unsigned char; -}; -template<> -struct __MakeUnsigned { - using Type = unsigned short; -}; -template<> -struct __MakeUnsigned { - using Type = unsigned int; -}; -template<> -struct __MakeUnsigned { - using Type = unsigned long; -}; -template<> -struct __MakeUnsigned { - using Type = unsigned long long; -}; -template<> -struct __MakeUnsigned { - using Type = unsigned char; -}; -template<> -struct __MakeUnsigned { - using Type = char8_t; -}; -template<> -struct __MakeUnsigned { - using Type = char16_t; -}; -template<> -struct __MakeUnsigned { - using Type = char32_t; -}; -template<> -struct __MakeUnsigned { - using Type = bool; -}; - -template -using MakeUnsigned = typename __MakeUnsigned::Type; - -template -struct __MakeSigned { - using Type = void; -}; -template<> -struct __MakeSigned { - using Type = signed char; -}; -template<> -struct __MakeSigned { - using Type = short; -}; -template<> -struct __MakeSigned { - using Type = int; -}; -template<> -struct __MakeSigned { - using Type = long; -}; -template<> -struct __MakeSigned { - using Type = long long; -}; -template<> -struct __MakeSigned { - using Type = char; -}; -template<> -struct __MakeSigned { - using Type = short; -}; -template<> -struct __MakeSigned { - using Type = int; -}; -template<> -struct __MakeSigned { - using Type = long; -}; -template<> -struct __MakeSigned { - using Type = long long; -}; -template<> -struct __MakeSigned { - using Type = char; -}; - -template -using MakeSigned = typename __MakeSigned::Type; - -template -auto declval()->T; - -template -struct __CommonType; - -template -struct __CommonType { - using Type = T; -}; - -template -struct __CommonType { - using Type = decltype(true ? declval() : declval()); -}; - -template -struct __CommonType { - using Type = typename __CommonType::Type, Ts...>::Type; -}; - -template -using CommonType = typename __CommonType::Type; - -template -inline constexpr bool IsVoid = IsSame>; - -template -inline constexpr bool IsConst = false; - -template -inline constexpr bool IsConst = true; - -template -inline constexpr bool IsEnum = __is_enum(T); - -template -inline constexpr bool IsUnion = __is_union(T); - -template -inline constexpr bool IsClass = __is_class(T); - -template -inline constexpr bool IsBaseOf = false; // FIXME: __is_base_of(Base, Derived); - -template -inline constexpr bool __IsIntegral = false; - -template<> -inline constexpr bool __IsIntegral = true; -template<> -inline constexpr bool __IsIntegral = true; -template<> -inline constexpr bool __IsIntegral = true; -template<> -inline constexpr bool __IsIntegral = true; -template<> -inline constexpr bool __IsIntegral = true; -template<> -inline constexpr bool __IsIntegral = true; -template<> -inline constexpr bool __IsIntegral = true; -template<> -inline constexpr bool __IsIntegral = true; -template<> -inline constexpr bool __IsIntegral = true; - -template -inline constexpr bool IsIntegral = __IsIntegral>>; - -template -inline constexpr bool __IsFloatingPoint = false; -template<> -inline constexpr bool __IsFloatingPoint = true; -template<> -inline constexpr bool __IsFloatingPoint = true; -template<> -inline constexpr bool __IsFloatingPoint = true; - -template -inline constexpr bool IsFloatingPoint = __IsFloatingPoint>; - -template -using CopyConst = Conditional, AddConst, RemoveConst>; - -template -using Void = void; - -template -constexpr auto DependentFalse = false; - -template -inline constexpr bool IsSigned = IsSame>; - -template -inline constexpr bool IsUnsigned = IsSame>; - -template -inline constexpr bool IsArithmetic = IsIntegral || IsFloatingPoint; - -template -inline constexpr bool IsFundamental = IsArithmetic || IsVoid || IsNullPointer; - -template -struct IntegerSequence { - using Type = T; - static constexpr unsigned size() noexcept { return sizeof...(Ts); }; -}; - -template -using IndexSequence = IntegerSequence; - -template -auto make_integer_sequence_impl() -{ - if constexpr (N == 0) - return IntegerSequence {}; - else - return make_integer_sequence_impl(); -} - -template -using MakeIntegerSequence = decltype(make_integer_sequence_impl()); - -template -using MakeIndexSequence = MakeIntegerSequence; - -template -struct __IdentityType { - using Type = T; -}; - -template -using IdentityType = typename __IdentityType::Type; - -template -struct __AddReference { - using LvalueType = T; - using TvalueType = T; -}; - -template -struct __AddReference> { - using LvalueType = T&; - using RvalueType = T&&; -}; - -template -using AddLvalueReference = typename __AddReference::LvalueType; - -template -using AddRvalueReference = typename __AddReference::RvalueType; - -template - requires(IsEnum) using UnderlyingType = __underlying_type(T); - -template -struct __AssertSize : TrueType { - static_assert(ActualSize == ExpectedSize, - "actual size does not match expected size"); - - consteval explicit operator bool() const { return value; } -}; - -// Note: This type is useful, as the sizes will be visible in the -// compiler error messages, as they will be part of the -// template parameters. This is not possible with a -// static_assert on the sizeof a type. -template -using AssertSize = __AssertSize; - -template -inline constexpr bool IsPOD = __is_pod(T); - -template -inline constexpr bool IsTrivial = __is_trivial(T); - -template -inline constexpr bool IsTriviallyCopyable = __is_trivially_copyable(T); - -template -inline constexpr bool IsCallableWithArguments = requires(T t) { t(declval()...); }; - -template -inline constexpr bool IsConstructible = requires { ::new T(declval()...); }; - -template -inline constexpr bool IsTriviallyConstructible = __is_trivially_constructible(T, Args...); - -template -inline constexpr bool IsConvertible = requires { declval()(declval()); }; - -template -inline constexpr bool IsAssignable = requires { declval() = declval(); }; - -template -inline constexpr bool IsTriviallyAssignable = __is_trivially_assignable(T, U); - -template -inline constexpr bool IsDestructible = requires { declval().~T(); }; - -template -inline constexpr bool IsTriviallyDestructible = __is_trivially_destructible(T); - -template -inline constexpr bool IsCopyConstructible = IsConstructible>>; - -template -inline constexpr bool IsTriviallyCopyConstructible = IsTriviallyConstructible>>; - -template -inline constexpr bool IsCopyAssignable = IsAssignable, AddLvalueReference>>; - -template -inline constexpr bool IsTriviallyCopyAssignable = IsTriviallyAssignable, AddLvalueReference>>; - -template -inline constexpr bool IsMoveConstructible = IsConstructible>; - -template -inline constexpr bool IsTriviallyMoveConstructible = IsTriviallyConstructible>; - -template -inline constexpr bool IsMoveAssignable = IsAssignable, AddRvalueReference>; - -template -inline constexpr bool IsTriviallyMoveAssignable = IsTriviallyAssignable, AddRvalueReference>; - -template typename U> -inline constexpr bool IsSpecializationOf = false; - -template typename U, typename... Us> -inline constexpr bool IsSpecializationOf, U> = true; - -template -struct __decay { - typedef Detail::RemoveCVReference type; -}; -template -struct __decay { - typedef T* type; -}; -/*template -struct __decay { - typedef T* type; -};*/ -// FIXME: Function decay -template -using Decay = typename __decay::type; - -template -inline constexpr bool IsPointerOfType = IsPointer> && IsSame>>>; - -template -inline constexpr bool IsHashCompatible = false; -template -inline constexpr bool IsHashCompatible = true; - -template -inline constexpr bool IsOneOf = (IsSame || ...); - -template -inline constexpr bool IsSameIgnoringCV = IsSame, RemoveCV>; - -template -inline constexpr bool IsOneOfIgnoringCV = (IsSameIgnoringCV || ...); - -} -using AK::Detail::AddConst; -using AK::Detail::AddConstToReferencedType; -using AK::Detail::AddLvalueReference; -using AK::Detail::AddRvalueReference; -using AK::Detail::AssertSize; -using AK::Detail::CommonType; -using AK::Detail::Conditional; -using AK::Detail::CopyConst; -using AK::Detail::declval; -using AK::Detail::DependentFalse; -using AK::Detail::FalseType; -using AK::Detail::IdentityType; -using AK::Detail::IndexSequence; -using AK::Detail::IntegerSequence; -using AK::Detail::IsArithmetic; -using AK::Detail::IsAssignable; -using AK::Detail::IsBaseOf; -using AK::Detail::IsCallableWithArguments; -using AK::Detail::IsClass; -using AK::Detail::IsConst; -using AK::Detail::IsConstructible; -using AK::Detail::IsConvertible; -using AK::Detail::IsCopyAssignable; -using AK::Detail::IsCopyConstructible; -using AK::Detail::IsDestructible; -using AK::Detail::IsEnum; -using AK::Detail::IsFloatingPoint; -using AK::Detail::IsFunction; -using AK::Detail::IsFundamental; -using AK::Detail::IsHashCompatible; -using AK::Detail::IsIntegral; -using AK::Detail::IsLvalueReference; -using AK::Detail::IsMoveAssignable; -using AK::Detail::IsMoveConstructible; -using AK::Detail::IsNullPointer; -using AK::Detail::IsOneOf; -using AK::Detail::IsOneOfIgnoringCV; -using AK::Detail::IsPOD; -using AK::Detail::IsPointer; -using AK::Detail::IsRvalueReference; -using AK::Detail::IsSame; -using AK::Detail::IsSameIgnoringCV; -using AK::Detail::IsSigned; -using AK::Detail::IsSpecializationOf; -using AK::Detail::IsTrivial; -using AK::Detail::IsTriviallyAssignable; -using AK::Detail::IsTriviallyConstructible; -using AK::Detail::IsTriviallyCopyable; -using AK::Detail::IsTriviallyCopyAssignable; -using AK::Detail::IsTriviallyCopyConstructible; -using AK::Detail::IsTriviallyDestructible; -using AK::Detail::IsTriviallyMoveAssignable; -using AK::Detail::IsTriviallyMoveConstructible; -using AK::Detail::IsUnion; -using AK::Detail::IsUnsigned; -using AK::Detail::IsVoid; -using AK::Detail::MakeIndexSequence; -using AK::Detail::MakeIntegerSequence; -using AK::Detail::MakeSigned; -using AK::Detail::MakeUnsigned; -using AK::Detail::RemoveConst; -using AK::Detail::RemoveCV; -using AK::Detail::RemoveCVReference; -using AK::Detail::RemovePointer; -using AK::Detail::RemoveReference; -using AK::Detail::RemoveVolatile; -using AK::Detail::TrueType; -using AK::Detail::UnderlyingType; -using AK::Detail::Void; +/* + * Copyright (c) 2018-2021, Andreas Kling + * Copyright (c) 2021, Ali Mohammad Pur + * Copyright (c) 2021, Daniel Bertalan + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include + +namespace AK::Detail { + +template +struct IntegralConstant { + static constexpr T value = v; + using ValueType = T; + using Type = IntegralConstant; + constexpr operator ValueType() const { return value; } + constexpr ValueType operator()() const { return value; } +}; + +using FalseType = IntegralConstant; +using TrueType = IntegralConstant; + +template +using AddConst = const T; + +template +struct __AddConstToReferencedType { + using Type = T; +}; + +template +struct __AddConstToReferencedType { + using Type = AddConst&; +}; + +template +struct __AddConstToReferencedType { + using Type = AddConst&&; +}; + +template +using AddConstToReferencedType = typename __AddConstToReferencedType::Type; + +template +struct __RemoveConst { + using Type = T; +}; +template +struct __RemoveConst { + using Type = T; +}; +template +using RemoveConst = typename __RemoveConst::Type; + +template +struct __RemoveVolatile { + using Type = T; +}; + +template +struct __RemoveVolatile { + using Type = T; +}; + +template +using RemoveVolatile = typename __RemoveVolatile::Type; + +template +using RemoveCV = RemoveVolatile>; + +template +using VoidType = void; + +template +inline constexpr bool IsLvalueReference = false; + +template +inline constexpr bool IsLvalueReference = true; + +template +inline constexpr bool __IsPointerHelper = false; + +template +inline constexpr bool __IsPointerHelper = true; + +template +inline constexpr bool IsPointer = __IsPointerHelper>; + +template +inline constexpr bool IsFunction = false; +template +inline constexpr bool IsFunction = true; +template +inline constexpr bool IsFunction = true; +template +inline constexpr bool IsFunction = true; +template +inline constexpr bool IsFunction = true; +template +inline constexpr bool IsFunction = true; +template +inline constexpr bool IsFunction = true; +template +inline constexpr bool IsFunction = true; +template +inline constexpr bool IsFunction = true; +template +inline constexpr bool IsFunction = true; +template +inline constexpr bool IsFunction = true; +template +inline constexpr bool IsFunction = true; +template +inline constexpr bool IsFunction = true; +template +inline constexpr bool IsFunction = true; +template +inline constexpr bool IsFunction = true; +template +inline constexpr bool IsFunction = true; +template +inline constexpr bool IsFunction = true; +template +inline constexpr bool IsFunction = true; +template +inline constexpr bool IsFunction = true; +template +inline constexpr bool IsFunction = true; +template +inline constexpr bool IsFunction = true; +template +inline constexpr bool IsFunction = true; +template +inline constexpr bool IsFunction = true; +template +inline constexpr bool IsFunction = true; +template +inline constexpr bool IsFunction = true; + +template +inline constexpr bool IsRvalueReference = false; +template +inline constexpr bool IsRvalueReference = true; + +template +struct __RemovePointer { + using Type = T; +}; +template +struct __RemovePointer { + using Type = T; +}; +template +struct __RemovePointer { + using Type = T; +}; +template +struct __RemovePointer { + using Type = T; +}; +template +struct __RemovePointer { + using Type = T; +}; +template +using RemovePointer = typename __RemovePointer::Type; + +template +inline constexpr bool IsSame = false; + +template +inline constexpr bool IsSame = true; + +template +struct __Conditional { + using Type = TrueType; +}; + +template +struct __Conditional { + using Type = FalseType; +}; + +template +using Conditional = typename __Conditional::Type; + +template +inline constexpr bool IsNullPointer = IsSame>; + +template +struct __RemoveReference { + using Type = T; +}; +template +struct __RemoveReference { + using Type = T; +}; +template +struct __RemoveReference { + using Type = T; +}; + +template +using RemoveReference = typename __RemoveReference::Type; + +template +using RemoveCVReference = RemoveCV>; + +template +struct __MakeUnsigned { + using Type = void; +}; +template<> +struct __MakeUnsigned { + using Type = unsigned char; +}; +template<> +struct __MakeUnsigned { + using Type = unsigned short; +}; +template<> +struct __MakeUnsigned { + using Type = unsigned int; +}; +template<> +struct __MakeUnsigned { + using Type = unsigned long; +}; +template<> +struct __MakeUnsigned { + using Type = unsigned long long; +}; +template<> +struct __MakeUnsigned { + using Type = unsigned char; +}; +template<> +struct __MakeUnsigned { + using Type = unsigned short; +}; +template<> +struct __MakeUnsigned { + using Type = unsigned int; +}; +template<> +struct __MakeUnsigned { + using Type = unsigned long; +}; +template<> +struct __MakeUnsigned { + using Type = unsigned long long; +}; +template<> +struct __MakeUnsigned { + using Type = unsigned char; +}; +template<> +struct __MakeUnsigned { + using Type = char8_t; +}; +template<> +struct __MakeUnsigned { + using Type = char16_t; +}; +template<> +struct __MakeUnsigned { + using Type = char32_t; +}; +template<> +struct __MakeUnsigned { + using Type = bool; +}; + +template +using MakeUnsigned = typename __MakeUnsigned::Type; + +template +struct __MakeSigned { + using Type = void; +}; +template<> +struct __MakeSigned { + using Type = signed char; +}; +template<> +struct __MakeSigned { + using Type = short; +}; +template<> +struct __MakeSigned { + using Type = int; +}; +template<> +struct __MakeSigned { + using Type = long; +}; +template<> +struct __MakeSigned { + using Type = long long; +}; +template<> +struct __MakeSigned { + using Type = char; +}; +template<> +struct __MakeSigned { + using Type = short; +}; +template<> +struct __MakeSigned { + using Type = int; +}; +template<> +struct __MakeSigned { + using Type = long; +}; +template<> +struct __MakeSigned { + using Type = long long; +}; +template<> +struct __MakeSigned { + using Type = char; +}; + +template +using MakeSigned = typename __MakeSigned::Type; + +template +auto declval()->T; + +template +struct __CommonType; + +template +struct __CommonType { + using Type = T; +}; + +template +struct __CommonType { + using Type = decltype(true ? declval() : declval()); +}; + +template +struct __CommonType { + using Type = typename __CommonType::Type, Ts...>::Type; +}; + +template +using CommonType = typename __CommonType::Type; + +template +inline constexpr bool IsVoid = IsSame>; + +template +inline constexpr bool IsConst = false; + +template +inline constexpr bool IsConst = true; + +template +inline constexpr bool IsEnum = __is_enum(T); + +template +inline constexpr bool IsUnion = __is_union(T); + +template +inline constexpr bool IsClass = __is_class(T); + +template +inline constexpr bool IsBaseOf = false; // FIXME: __is_base_of(Base, Derived); + +template +inline constexpr bool __IsIntegral = false; + +template<> +inline constexpr bool __IsIntegral = true; +template<> +inline constexpr bool __IsIntegral = true; +template<> +inline constexpr bool __IsIntegral = true; +template<> +inline constexpr bool __IsIntegral = true; +template<> +inline constexpr bool __IsIntegral = true; +template<> +inline constexpr bool __IsIntegral = true; +template<> +inline constexpr bool __IsIntegral = true; +template<> +inline constexpr bool __IsIntegral = true; +template<> +inline constexpr bool __IsIntegral = true; + +template +inline constexpr bool IsIntegral = __IsIntegral>>; + +template +inline constexpr bool __IsFloatingPoint = false; +template<> +inline constexpr bool __IsFloatingPoint = true; +template<> +inline constexpr bool __IsFloatingPoint = true; +template<> +inline constexpr bool __IsFloatingPoint = true; + +template +inline constexpr bool IsFloatingPoint = __IsFloatingPoint>; + +template +using CopyConst = Conditional, AddConst, RemoveConst>; + +template +using Void = void; + +template +constexpr auto DependentFalse = false; + +template +inline constexpr bool IsSigned = IsSame>; + +template +inline constexpr bool IsUnsigned = IsSame>; + +template +inline constexpr bool IsArithmetic = IsIntegral || IsFloatingPoint; + +template +inline constexpr bool IsFundamental = IsArithmetic || IsVoid || IsNullPointer; + +template +struct IntegerSequence { + using Type = T; + static constexpr unsigned size() noexcept { return sizeof...(Ts); }; +}; + +template +using IndexSequence = IntegerSequence; + +template +auto make_integer_sequence_impl() +{ + if constexpr (N == 0) + return IntegerSequence {}; + else + return make_integer_sequence_impl(); +} + +template +using MakeIntegerSequence = decltype(make_integer_sequence_impl()); + +template +using MakeIndexSequence = MakeIntegerSequence; + +template +struct __IdentityType { + using Type = T; +}; + +template +using IdentityType = typename __IdentityType::Type; + +template +struct __AddReference { + using LvalueType = T; + using TvalueType = T; +}; + +template +struct __AddReference> { + using LvalueType = T&; + using RvalueType = T&&; +}; + +template +using AddLvalueReference = typename __AddReference::LvalueType; + +template +using AddRvalueReference = typename __AddReference::RvalueType; + +template + requires(IsEnum) using UnderlyingType = __underlying_type(T); + +template +struct __AssertSize : TrueType { + static_assert(ActualSize == ExpectedSize, + "actual size does not match expected size"); + + consteval explicit operator bool() const { return value; } +}; + +// Note: This type is useful, as the sizes will be visible in the +// compiler error messages, as they will be part of the +// template parameters. This is not possible with a +// static_assert on the sizeof a type. +template +using AssertSize = __AssertSize; + +template +inline constexpr bool IsPOD = __is_pod(T); + +template +inline constexpr bool IsTrivial = __is_trivial(T); + +template +inline constexpr bool IsTriviallyCopyable = __is_trivially_copyable(T); + +template +inline constexpr bool IsCallableWithArguments = requires(T t) { t(declval()...); }; + +template +inline constexpr bool IsConstructible = requires { ::new T(declval()...); }; + +template +inline constexpr bool IsTriviallyConstructible = __is_trivially_constructible(T, Args...); + +template +inline constexpr bool IsConvertible = requires { declval()(declval()); }; + +template +inline constexpr bool IsAssignable = requires { declval() = declval(); }; + +template +inline constexpr bool IsTriviallyAssignable = __is_trivially_assignable(T, U); + +template +inline constexpr bool IsDestructible = requires { declval().~T(); }; + +template +inline constexpr bool IsTriviallyDestructible = __is_trivially_destructible(T); + +template +inline constexpr bool IsCopyConstructible = IsConstructible>>; + +template +inline constexpr bool IsTriviallyCopyConstructible = IsTriviallyConstructible>>; + +template +inline constexpr bool IsCopyAssignable = IsAssignable, AddLvalueReference>>; + +template +inline constexpr bool IsTriviallyCopyAssignable = IsTriviallyAssignable, AddLvalueReference>>; + +template +inline constexpr bool IsMoveConstructible = IsConstructible>; + +template +inline constexpr bool IsTriviallyMoveConstructible = IsTriviallyConstructible>; + +template +inline constexpr bool IsMoveAssignable = IsAssignable, AddRvalueReference>; + +template +inline constexpr bool IsTriviallyMoveAssignable = IsTriviallyAssignable, AddRvalueReference>; + +template typename U> +inline constexpr bool IsSpecializationOf = false; + +template typename U, typename... Us> +inline constexpr bool IsSpecializationOf, U> = true; + +template +struct __decay { + typedef Detail::RemoveCVReference type; +}; +template +struct __decay { + typedef T* type; +}; +/*template +struct __decay { + typedef T* type; +};*/ +// FIXME: Function decay +template +using Decay = typename __decay::type; + +template +inline constexpr bool IsPointerOfType = IsPointer> && IsSame>>>; + +template +inline constexpr bool IsHashCompatible = false; +template +inline constexpr bool IsHashCompatible = true; + +template +inline constexpr bool IsOneOf = (IsSame || ...); + +template +inline constexpr bool IsSameIgnoringCV = IsSame, RemoveCV>; + +template +inline constexpr bool IsOneOfIgnoringCV = (IsSameIgnoringCV || ...); + +} +using AK::Detail::AddConst; +using AK::Detail::AddConstToReferencedType; +using AK::Detail::AddLvalueReference; +using AK::Detail::AddRvalueReference; +using AK::Detail::AssertSize; +using AK::Detail::CommonType; +using AK::Detail::Conditional; +using AK::Detail::CopyConst; +using AK::Detail::declval; +using AK::Detail::DependentFalse; +using AK::Detail::FalseType; +using AK::Detail::IdentityType; +using AK::Detail::IndexSequence; +using AK::Detail::IntegerSequence; +using AK::Detail::IsArithmetic; +using AK::Detail::IsAssignable; +using AK::Detail::IsBaseOf; +using AK::Detail::IsCallableWithArguments; +using AK::Detail::IsClass; +using AK::Detail::IsConst; +using AK::Detail::IsConstructible; +using AK::Detail::IsConvertible; +using AK::Detail::IsCopyAssignable; +using AK::Detail::IsCopyConstructible; +using AK::Detail::IsDestructible; +using AK::Detail::IsEnum; +using AK::Detail::IsFloatingPoint; +using AK::Detail::IsFunction; +using AK::Detail::IsFundamental; +using AK::Detail::IsHashCompatible; +using AK::Detail::IsIntegral; +using AK::Detail::IsLvalueReference; +using AK::Detail::IsMoveAssignable; +using AK::Detail::IsMoveConstructible; +using AK::Detail::IsNullPointer; +using AK::Detail::IsOneOf; +using AK::Detail::IsOneOfIgnoringCV; +using AK::Detail::IsPOD; +using AK::Detail::IsPointer; +using AK::Detail::IsRvalueReference; +using AK::Detail::IsSame; +using AK::Detail::IsSameIgnoringCV; +using AK::Detail::IsSigned; +using AK::Detail::IsSpecializationOf; +using AK::Detail::IsTrivial; +using AK::Detail::IsTriviallyAssignable; +using AK::Detail::IsTriviallyConstructible; +using AK::Detail::IsTriviallyCopyable; +using AK::Detail::IsTriviallyCopyAssignable; +using AK::Detail::IsTriviallyCopyConstructible; +using AK::Detail::IsTriviallyDestructible; +using AK::Detail::IsTriviallyMoveAssignable; +using AK::Detail::IsTriviallyMoveConstructible; +using AK::Detail::IsUnion; +using AK::Detail::IsUnsigned; +using AK::Detail::IsVoid; +using AK::Detail::MakeIndexSequence; +using AK::Detail::MakeIntegerSequence; +using AK::Detail::MakeSigned; +using AK::Detail::MakeUnsigned; +using AK::Detail::RemoveConst; +using AK::Detail::RemoveCV; +using AK::Detail::RemoveCVReference; +using AK::Detail::RemovePointer; +using AK::Detail::RemoveReference; +using AK::Detail::RemoveVolatile; +using AK::Detail::TrueType; +using AK::Detail::UnderlyingType; +using AK::Detail::Void; diff --git a/AK/AK/StdLibExtras.h b/LibC-Shim/AK/StdLibExtras.h similarity index 92% rename from AK/AK/StdLibExtras.h rename to LibC-Shim/AK/StdLibExtras.h index 73f79de..5f0bd1c 100644 --- a/AK/AK/StdLibExtras.h +++ b/LibC-Shim/AK/StdLibExtras.h @@ -1,134 +1,134 @@ -/* - * Copyright (c) 2018-2021, Andreas Kling - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include -#include -#include "./AK/Assertions.h" -#include "./AK/StdLibExtraDetails.h" - -template -constexpr auto round_up_to_power_of_two(T value, U power_of_two) requires(IsIntegral&& IsIntegral) -{ - return ((value - 1) & ~(power_of_two - 1)) + power_of_two; -} - -template -constexpr bool is_power_of_two(T value) requires(IsIntegral) -{ - return value && !((value) & (value - 1)); -} - -using std::forward; -using std::move; - -namespace AK::Detail { -template -struct _RawPtr { - using Type = T*; -}; -} - -namespace AK { - -template -constexpr SizeType array_size(T(&)[N]) -{ - return N; -} - -#undef min -template -constexpr T min(const T& a, IdentityType const& b) -{ - return b < a ? b : a; -} - -#undef max -template -constexpr T max(const T& a, IdentityType const& b) -{ - return a < b ? b : a; -} - -// FIXME: -template -T abs(const T& a); - - -template -constexpr T clamp(const T& value, IdentityType const& min, IdentityType const& max) -{ - VERIFY(max >= min); - if (value > max) - return max; - if (value < min) - return min; - return value; -} - -template -constexpr T mix(T const& v1, T const& v2, U const& interpolation) -{ - return v1 + (v2 - v1) * interpolation; -} - -template -constexpr T ceil_div(T a, U b) -{ - static_assert(sizeof(T) == sizeof(U)); - T result = a / b; - if ((a % b) != 0) - ++result; - return result; -} - -template -ALWAYS_INLINE void swap(T& a, U& b) -{ - if (&a == &b) - return; - U tmp = move((U&)a); - a = (T&&)move(b); - b = move(tmp); -} - -template -constexpr T exchange(T& slot, U&& value) -{ - T old_value = move(slot); - slot = forward(value); - return old_value; -} - -template -using RawPtr = typename Detail::_RawPtr::Type; - -template -constexpr decltype(auto) to_underlying(V value) requires(IsEnum) -{ - return static_cast>(value); -} - -constexpr bool is_constant_evaluated() -{ - return false; -} - -} - -using AK::array_size; -using AK::ceil_div; -using AK::clamp; -using AK::exchange; -using AK::is_constant_evaluated; -using AK::max; -using AK::min; -using AK::mix; -using AK::RawPtr; -using AK::swap; -using AK::to_underlying; +/* + * Copyright (c) 2018-2021, Andreas Kling + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include +#include "Assertions.h" +#include "StdLibExtraDetails.h" + +template +constexpr auto round_up_to_power_of_two(T value, U power_of_two) requires(IsIntegral&& IsIntegral) +{ + return ((value - 1) & ~(power_of_two - 1)) + power_of_two; +} + +template +constexpr bool is_power_of_two(T value) requires(IsIntegral) +{ + return value && !((value) & (value - 1)); +} + +using std::forward; +using std::move; + +namespace AK::Detail { +template +struct _RawPtr { + using Type = T*; +}; +} + +namespace AK { + +template +constexpr SizeType array_size(T(&)[N]) +{ + return N; +} + +#undef min +template +constexpr T min(const T& a, IdentityType const& b) +{ + return b < a ? b : a; +} + +#undef max +template +constexpr T max(const T& a, IdentityType const& b) +{ + return a < b ? b : a; +} + +// FIXME: +template +T abs(const T& a); + + +template +constexpr T clamp(const T& value, IdentityType const& min, IdentityType const& max) +{ + VERIFY(max >= min); + if (value > max) + return max; + if (value < min) + return min; + return value; +} + +template +constexpr T mix(T const& v1, T const& v2, U const& interpolation) +{ + return v1 + (v2 - v1) * interpolation; +} + +template +constexpr T ceil_div(T a, U b) +{ + static_assert(sizeof(T) == sizeof(U)); + T result = a / b; + if ((a % b) != 0) + ++result; + return result; +} + +template +ALWAYS_INLINE void swap(T& a, U& b) +{ + if (&a == &b) + return; + U tmp = move((U&)a); + a = (T&&)move(b); + b = move(tmp); +} + +template +constexpr T exchange(T& slot, U&& value) +{ + T old_value = move(slot); + slot = forward(value); + return old_value; +} + +template +using RawPtr = typename Detail::_RawPtr::Type; + +template +constexpr decltype(auto) to_underlying(V value) requires(IsEnum) +{ + return static_cast>(value); +} + +constexpr bool is_constant_evaluated() +{ + return false; +} + +} + +using AK::array_size; +using AK::ceil_div; +using AK::clamp; +using AK::exchange; +using AK::is_constant_evaluated; +using AK::max; +using AK::min; +using AK::mix; +using AK::RawPtr; +using AK::swap; +using AK::to_underlying; diff --git a/AK/AK/String.cpp b/LibC-Shim/AK/String.cpp similarity index 90% rename from AK/AK/String.cpp rename to LibC-Shim/AK/String.cpp index a9c06ab..0ecbcc2 100644 --- a/AK/AK/String.cpp +++ b/LibC-Shim/AK/String.cpp @@ -1,6 +1,6 @@ -#include "pch.h" -#include "String.h" - -namespace AK { - -} \ No newline at end of file +#include "pch.h" +#include "String.h" + +namespace AK { + +} diff --git a/LibC-Shim/AK/String.h b/LibC-Shim/AK/String.h new file mode 100644 index 0000000..7cfc206 --- /dev/null +++ b/LibC-Shim/AK/String.h @@ -0,0 +1,432 @@ +#pragma once + +#include "Format.h" +#include "Forward.h" +#include "RefPtr.h" +//#include "Stream.h" +#include "StringBuilder.h" +#include "StringImpl.h" +#include "StringUtils.h" +#include "Traits.h" + +namespace AK { + +class String { +public: + ~String() = default; + + String() = default; + + String(StringView view) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + } + String(String const& other) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + } + String(String&& other) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + } + String(char const* cstring, ShouldChomp shouldChomp = NoChomp) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + } + String(char const* cstring, size_t length, ShouldChomp shouldChomp = NoChomp) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + } + explicit String(ReadonlyBytes bytes, ShouldChomp shouldChomp = NoChomp) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + } + String(StringImpl const& impl) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + } + String(StringImpl const* impl) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + } + String(RefPtr&& impl) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + } + String(NonnullRefPtr&& impl) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + } + String(FlyString const&) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + } + + static String repeated(char, size_t count) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return String(); + } + static String repeated(StringView, size_t count) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return String(); + } + + static String bijective_base_from(size_t value, unsigned base = 26, StringView map = {}) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return String(); + } + static String roman_number_from(size_t value) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return String(); + } + + template + static String join(SeparatorType const& separator, CollectionType const& collection, StringView fmtstr = "{}"sv) + { + StringBuilder builder; + builder.join(separator, collection, fmtstr); + return builder.build(); + } + + bool matches(StringView mask, CaseSensitivity = CaseSensitivity::CaseInsensitive) const + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return false; + } + bool matches(StringView mask, Vector&, CaseSensitivity = CaseSensitivity::CaseInsensitive) const + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return false; + } + + template + Optional to_int(TrimWhitespace = TrimWhitespace::Yes) const + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return {}; + } + template + Optional to_uint(TrimWhitespace = TrimWhitespace::Yes) const + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return {}; + } + + bool contains(StringView, CaseSensitivity = CaseSensitivity::CaseSensitive) const + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return false; + } + bool contains(char, CaseSensitivity = CaseSensitivity::CaseSensitive) const + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return false; + } + + Vector split_limit(char separator, size_t limit, bool keep_empty = false) const; + Vector split(char separator, bool keep_empty = false) const; + Vector split_view(char separator, bool keep_empty = false) const; + Vector split_view(Function separator, bool keep_empty = false) const; + + Optional find(char needle, size_t start = 0) const; + Optional find(StringView needle, size_t start = 0) const; + Optional find_last(char needle) const; + Vector find_all(StringView needle) const; + using SearchDirection = StringUtils::SearchDirection; + Optional find_any_of(StringView needles, SearchDirection direction) const; + + String substring(size_t start, size_t length) const; + String substring(size_t start) const; + StringView substring_view(size_t start, size_t length) const; + StringView substring_view(size_t start) const; + + ALWAYS_INLINE ReadonlyBytes bytes() const + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return {}; + } + + ALWAYS_INLINE char const& operator[](size_t i) const; + + using ConstIterator = SimpleIterator; + + constexpr ConstIterator begin() const { return ConstIterator::begin(*this); } + constexpr ConstIterator end() const { return ConstIterator::end(*this); } + + bool starts_with(StringView, CaseSensitivity = CaseSensitivity::CaseSensitive) const; + bool ends_with(StringView, CaseSensitivity = CaseSensitivity::CaseSensitive) const; + bool starts_with(char) const + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return false; + } + bool ends_with(char) const + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return false; + } + + bool is_null() const + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return false; + } + ALWAYS_INLINE bool is_empty() const + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return true; + } + ALWAYS_INLINE size_t length() const + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return 0; + } + char* characters() const + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return nullptr; + } + + u32 hash() const { return 0; } + + [[nodiscard]] ByteBuffer to_byte_buffer() const + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return {}; + } + + template + [[nodiscard]] static String copy(BufferType const& buffer, ShouldChomp should_chomp = NoChomp) + { + if (buffer.is_empty()) + return empty(); + return String((char const*)buffer.data(), buffer.size(), should_chomp); + } + + [[nodiscard]] static String vformatted(StringView fmtstr, TypeErasedFormatParams&) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return String(); + } + + template + [[nodiscard]] static String formatted(CheckedFormatString&& fmtstr, Parameters const&... parameters) + { + VariadicFormatParams variadic_format_parameters { parameters... }; + return vformatted(fmtstr.view(), variadic_format_parameters); + } + + template + [[nodiscard]] static String number(T value) requires IsArithmetic + { + return formatted("{}", value); + } + + [[nodiscard]] StringView view() const + { + return { characters(), length() }; + } + + [[nodiscard]] static String empty() + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return String(); + } + + bool operator==(String const&) const + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return false; + } + bool operator!=(String const& other) const { return !(*this == other); } + + bool operator==(StringView) const + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return false; + } + bool operator!=(StringView other) const { return !(*this == other); } + + bool operator==(FlyString const&) const + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return false; + } + bool operator!=(FlyString const& other) const { return !(*this == other); } + + bool operator<(String const&) const + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return false; + } + bool operator<(char const*) const + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return false; + } + bool operator>=(String const& other) const { return !(*this < other); } + bool operator>=(char const* other) const { return !(*this < other); } + + bool operator>(String const&) const + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return false; + } + bool operator>(char const*) const + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return false; + } + bool operator<=(String const& other) const { return !(*this > other); } + bool operator<=(char const* other) const { return !(*this > other); } + + bool operator==(char const* cstring) const + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return false; + } + bool operator!=(char const* cstring) const { return !(*this == cstring); } + + String& operator=(String&& other) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return *this; + } + + String& operator=(String const& other) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return *this; + } + + String& operator=(std::nullptr_t) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return *this; + } + + String& operator=(ReadonlyBytes bytes) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return *this; + } + + String replace(StringView needle, StringView replacement, ReplaceMode replace_mode) const + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return String(); + } + size_t count(StringView needle) const + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return 0; + } + String reverse() const + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return String(); + } + + template + ALWAYS_INLINE constexpr bool is_one_of(Ts&&... strings) const + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return false; + } + + template + ALWAYS_INLINE constexpr bool is_one_of_ignoring_case(Ts&&... strings) const + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return false; + } + +private: + RefPtr m_impl; +}; + +template<> +struct Traits : public GenericTraits { + static unsigned hash(String const& s); +}; + +struct CaseInsensitiveStringTraits : public Traits { + static unsigned hash(String const& s) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return 0; + } + static bool equals(String const& a, String const& b) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return false; + } +}; + +String escape_html_entities(StringView html) +{ + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return String(); +} + +//InputStream& operator>>(InputStream& stream, String& string); + +} + +using AK::escape_html_entities; +using AK::String; diff --git a/LibC-Shim/AK/StringBuilder.cpp b/LibC-Shim/AK/StringBuilder.cpp new file mode 100644 index 0000000..1d8e19d --- /dev/null +++ b/LibC-Shim/AK/StringBuilder.cpp @@ -0,0 +1,16 @@ +#include "pch.h" +#include "String.h" +#include "StringBuilder.h" + +namespace AK { + +String StringBuilder::build() const +{ + return String(); +} +String StringBuilder::to_string() const +{ + return String(); +} + +} \ No newline at end of file diff --git a/LibC-Shim/AK/StringBuilder.h b/LibC-Shim/AK/StringBuilder.h new file mode 100644 index 0000000..9c88d6d --- /dev/null +++ b/LibC-Shim/AK/StringBuilder.h @@ -0,0 +1,164 @@ +#pragma once + +#include "ByteBuffer.h" +#include "Format.h" +#include "Forward.h" +#include "StringView.h" + +namespace AK { + +class StringBuilder { +public: + using OutputType = String; + + explicit StringBuilder(size_t initial_capacity = inline_capacity) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + } + ~StringBuilder() = default; + + ErrorOr try_append(StringView) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return {}; + } + ErrorOr try_append_code_point(u32) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return {}; + } + ErrorOr try_append(char) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return {}; + } + template + ErrorOr try_appendff(CheckedFormatString&& fmtstr, Parameters const&... parameters) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return {}; + } + + void append(StringView) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + } + void append(Utf16View const&) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + } + void append(Utf32View const&) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + } + void append(char) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + } + void append_code_point(u32) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + } + void append(char const*, size_t) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + } + void appendvf(char const*, va_list) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + } + + void append_as_lowercase(char) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + } + void append_escaped_for_json(StringView) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + } + + template + void appendff(CheckedFormatString&& fmtstr, Parameters const&... parameters) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + } + + String build() const; + String to_string() const; + + ByteBuffer to_byte_buffer() const + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return {}; + } + + StringView string_view() const + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return StringView(); + } + + void clear() + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + } + + size_t length() const + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return 0; + } + bool is_empty() const + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return true; + } + void trim(size_t count) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + } + + template + void join(SeparatorType const& separator, CollectionType const& collection, StringView fmtstr = "{}"sv) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + } + +private: + ErrorOr will_append(size_t) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return {}; + } + u8* data() { return m_buffer.data(); } + + static constexpr size_t inline_capacity = 256; + AK::Detail::ByteBuffer m_buffer; +}; + +} + +using AK::StringBuilder; diff --git a/AK/AK/StringHash.h b/LibC-Shim/AK/StringHash.h similarity index 91% rename from AK/AK/StringHash.h rename to LibC-Shim/AK/StringHash.h index 45195e8..1ef1b0b 100644 --- a/AK/AK/StringHash.h +++ b/LibC-Shim/AK/StringHash.h @@ -1,45 +1,45 @@ -#pragma once - -#include -#include "./AK/Types.h" - -namespace AK { - -constexpr u32 string_hash(char const* characters, size_t length, u32 seed = 0) -{ - u32 hash = seed; - for (size_t i = 0; i < length; ++i) { - hash += (u32)characters[i]; - hash += (hash << 10); - hash ^= (hash >> 6); - } - hash += hash << 3; - hash ^= hash >> 11; - hash += hash << 15; - return hash; -} - -constexpr u32 case_insensitive_string_hash(char const* characters, size_t length, u32 seed = 0) -{ - // AK/CharacterTypes.h cannot be included from here. - auto to_lowercase = [](char ch) -> u32 { - if (ch >= 'A' && ch <= 'Z') - return static_cast(ch) + 0x20; - return static_cast(ch); - }; - - u32 hash = seed; - for (size_t i = 0; i < length; ++i) { - hash += to_lowercase(characters[i]); - hash += (hash << 10); - hash ^= (hash >> 6); - } - hash += hash << 3; - hash ^= hash >> 11; - hash += hash << 15; - return hash; -} - -} - -using AK::string_hash; \ No newline at end of file +#pragma once + +#include +#include "Types.h" + +namespace AK { + +constexpr u32 string_hash(char const* characters, size_t length, u32 seed = 0) +{ + u32 hash = seed; + for (size_t i = 0; i < length; ++i) { + hash += (u32)characters[i]; + hash += (hash << 10); + hash ^= (hash >> 6); + } + hash += hash << 3; + hash ^= hash >> 11; + hash += hash << 15; + return hash; +} + +constexpr u32 case_insensitive_string_hash(char const* characters, size_t length, u32 seed = 0) +{ + // AK/CharacterTypes.h cannot be included from here. + auto to_lowercase = [](char ch) -> u32 { + if (ch >= 'A' && ch <= 'Z') + return static_cast(ch) + 0x20; + return static_cast(ch); + }; + + u32 hash = seed; + for (size_t i = 0; i < length; ++i) { + hash += to_lowercase(characters[i]); + hash += (hash << 10); + hash ^= (hash >> 6); + } + hash += hash << 3; + hash ^= hash >> 11; + hash += hash << 15; + return hash; +} + +} + +using AK::string_hash; diff --git a/LibC-Shim/AK/StringImpl.cpp b/LibC-Shim/AK/StringImpl.cpp new file mode 100644 index 0000000..4c38803 --- /dev/null +++ b/LibC-Shim/AK/StringImpl.cpp @@ -0,0 +1,9 @@ +#include "pch.h" +#include "CharacterTypes.h" +#include "FlyString.h" +#include "HashTable.h" +#include "Memory.h" +#include "StdLibExtras.h" +#include "StringHash.h" +#include "StringImpl.h" +#include "kmalloc.h" diff --git a/AK/AK/StringImpl.h b/LibC-Shim/AK/StringImpl.h similarity index 63% rename from AK/AK/StringImpl.h rename to LibC-Shim/AK/StringImpl.h index f198d0e..21f07d9 100644 --- a/AK/AK/StringImpl.h +++ b/LibC-Shim/AK/StringImpl.h @@ -1,27 +1,27 @@ -#pragma once - -#include "./AK/Badge.h" -#include "./AK/RefCounted.h" -#include "./AK/RefPtr.h" -#include "./AK/Span.h" -#include "./AK/Types.h" -#include "./AK/kmalloc.h" - -namespace AK { - -enum ShouldChomp { - NoChomp, - Chomp -}; - -class StringImpl : public RefCounted { -public: - NonnullRefPtr to_lowercase() const; - NonnullRefPtr to_uppercase() const; - - size_t length() const; - - u32 hash() const { return 0; } -}; - -} +#pragma once + +#include "Badge.h" +#include "RefCounted.h" +#include "RefPtr.h" +#include "Span.h" +#include "Types.h" +#include "kmalloc.h" + +namespace AK { + +enum ShouldChomp { + NoChomp, + Chomp +}; + +class StringImpl : public RefCounted { +public: + NonnullRefPtr to_lowercase() const; + NonnullRefPtr to_uppercase() const; + + size_t length() const; + + u32 hash() const { return 0; } +}; + +} diff --git a/LibC-Shim/AK/StringUtils.cpp b/LibC-Shim/AK/StringUtils.cpp new file mode 100644 index 0000000..666cd6a --- /dev/null +++ b/LibC-Shim/AK/StringUtils.cpp @@ -0,0 +1,2 @@ +#include "pch.h" +#include "StringUtils.h" diff --git a/AK/AK/StringUtils.h b/LibC-Shim/AK/StringUtils.h similarity index 88% rename from AK/AK/StringUtils.h rename to LibC-Shim/AK/StringUtils.h index 04a2b2f..091de6f 100644 --- a/AK/AK/StringUtils.h +++ b/LibC-Shim/AK/StringUtils.h @@ -1,62 +1,62 @@ -#pragma once - -#include "./AK/Concepts.h" -#include "./AK/Forward.h" - -namespace AK { - -namespace Detail { -template -inline constexpr bool IsHashCompatible = true; -} - -enum class CaseSensitivity { - CaseInsensitive, - CaseSensitive, -}; - -enum class ReplaceMode { - All, - FirstOnly, -}; - -enum class TrimMode { - Left, - Right, - Both -}; - -enum class TrimWhitespace { - Yes, - No, -}; - -struct MaskSpan { - size_t start; - size_t length; - - bool operator==(MaskSpan const& other) const - { - return start == other.start && length == other.length; - } - bool operator!=(MaskSpan const& other) const - { - return !(*this == other); - } -}; - -namespace StringUtils { - -enum class SearchDirection { - Forward, - Backward -}; - -} - -} - -using AK::CaseSensitivity; -using AK::ReplaceMode; -using AK::TrimMode; -using AK::TrimWhitespace; +#pragma once + +#include "Concepts.h" +#include "Forward.h" + +namespace AK { + +namespace Detail { +template +inline constexpr bool IsHashCompatible = true; +} + +enum class CaseSensitivity { + CaseInsensitive, + CaseSensitive, +}; + +enum class ReplaceMode { + All, + FirstOnly, +}; + +enum class TrimMode { + Left, + Right, + Both +}; + +enum class TrimWhitespace { + Yes, + No, +}; + +struct MaskSpan { + size_t start; + size_t length; + + bool operator==(MaskSpan const& other) const + { + return start == other.start && length == other.length; + } + bool operator!=(MaskSpan const& other) const + { + return !(*this == other); + } +}; + +namespace StringUtils { + +enum class SearchDirection { + Forward, + Backward +}; + +} + +} + +using AK::CaseSensitivity; +using AK::ReplaceMode; +using AK::TrimMode; +using AK::TrimWhitespace; diff --git a/AK/AK/StringBuilder.cpp b/LibC-Shim/AK/StringView.cpp similarity index 52% rename from AK/AK/StringBuilder.cpp rename to LibC-Shim/AK/StringView.cpp index 29415c4..7cfe8dd 100644 --- a/AK/AK/StringBuilder.cpp +++ b/LibC-Shim/AK/StringView.cpp @@ -1,6 +1,6 @@ -#include "pch.h" -#include "StringBuilder.h" - -namespace AK { - +#include "pch.h" +#include "StringView.h" + +namespace AK { + } \ No newline at end of file diff --git a/LibC-Shim/AK/StringView.h b/LibC-Shim/AK/StringView.h new file mode 100644 index 0000000..d8eb583 --- /dev/null +++ b/LibC-Shim/AK/StringView.h @@ -0,0 +1,323 @@ +/* + * Copyright (c) 2018-2021, Andreas Kling + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once +#pragma warning(disable: 4455) + +#include "Assertions.h" +#include "Checked.h" +#include "Forward.h" +#include "Optional.h" +#include "Span.h" +#include "StdLibExtras.h" +#include "StringHash.h" +#include "StringUtils.h" + +namespace AK { + +class StringView { +public: + ALWAYS_INLINE constexpr StringView() = default; + ALWAYS_INLINE constexpr StringView(char const* characters, size_t length) + : m_characters(characters) + , m_length(length) + { + if (!is_constant_evaluated()) + VERIFY(!Checked::addition_would_overflow((uintptr_t)characters, length)); + } + ALWAYS_INLINE StringView(unsigned char const* characters, size_t length) + : m_characters((char const*)characters) + , m_length(length) + { + //VERIFY(!Checked::addition_would_overflow((uintptr_t)characters, length)); + } + ALWAYS_INLINE StringView(ReadonlyBytes bytes) + : m_characters(reinterpret_cast(bytes.data())) + , m_length(bytes.size()) + { + } + + StringView(ByteBuffer const&) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + } + StringView(String const&) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + } + StringView(FlyString const&) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + } + + explicit StringView(ByteBuffer&&) = delete; + explicit StringView(String&&) = delete; + explicit StringView(FlyString&&) = delete; + + constexpr bool is_null() const + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return false; + } + constexpr bool is_empty() const { return m_length == 0; } + + constexpr char const* characters_without_null_termination() const { return m_characters; } + constexpr size_t length() const { return m_length; } + + ReadonlyBytes bytes() const + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return {}; + } + constexpr char const& operator[](size_t index) const; + + constexpr StringView substring_view(size_t start, size_t length) const + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return StringView(); + } + constexpr StringView substring_view(size_t start) const + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return StringView(); + } + + StringView replace(StringView, StringView, ReplaceMode) const; + constexpr int compare() + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return 0; + } + + constexpr int* begin() const + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return 0; + } + constexpr int* end() const + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return 0; + } + + constexpr unsigned hash() const + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return 0; + } + + bool starts_with(StringView, CaseSensitivity = CaseSensitivity::CaseSensitive) const + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return false; + } + bool ends_with(StringView, CaseSensitivity = CaseSensitivity::CaseSensitive) const + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return false; + } + bool starts_with(char) const + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return false; + } + bool ends_with(char) const + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return false; + } + bool matches(StringView mask, CaseSensitivity = CaseSensitivity::CaseInsensitive) const + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return false; + } + bool matches(StringView mask, Vector&, CaseSensitivity = CaseSensitivity::CaseInsensitive) const + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return false; + } + bool contains(char) const + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return false; + } + bool contains(StringView, CaseSensitivity = CaseSensitivity::CaseSensitive) const + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return false; + } + bool equals_ignoring_case(StringView other) const + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return false; + } + + StringView trim(StringView characters, TrimMode mode = TrimMode::Both) const; + StringView trim_whitespace(TrimMode mode = TrimMode::Both) const; + + String to_lowercase_string() const; + String to_uppercase_string() const; + String to_titlecase_string() const; + + Optional find(char needle, size_t start = 0) const + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return {}; + } + Optional find(StringView needle, size_t start = 0) const + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return {}; + } + Optional find_last(char needle) const + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return {}; + } + + Vector find_all(StringView needle); + + using SearchDirection = StringUtils::SearchDirection; + Optional find_any_of(StringView needles, SearchDirection direction = SearchDirection::Forward) const; + + Vector lines(bool consider_cr = true) const; + + template + Optional to_int() const + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return {}; + } + template + Optional to_uint() const + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return {}; + } + + StringView substring_view_starting_from_substring(StringView substring) const + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return StringView(); + } + StringView substring_view_starting_after_substring(StringView substring) const + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return StringView(); + } + + bool copy_characters_to_buffer(char* buffer, size_t buffer_size) const + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return false; + } + + bool operator==(StringView other) const + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return false; + } + constexpr bool operator==(char const* cstring) const + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return false; + } + constexpr bool operator!=(StringView other) const + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return false; + } + bool operator<(StringView other) const + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return false; + } + bool operator<=(StringView other) const + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return false; + } + bool operator>(StringView other) const + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return false; + } + bool operator>=(StringView other) const + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return false; + } + + String to_string() const; + + template + ALWAYS_INLINE constexpr bool is_one_of(Ts&&... strings) const + { + return (... || this->operator==(forward(strings))); + } + + template + ALWAYS_INLINE constexpr bool is_one_of_ignoring_case(Ts&&... strings) const + { + return (... || + [this, &strings]() -> bool { + if constexpr (requires(Ts a) { a.view()->StringView; }) + return this->equals_ignoring_case(forward(strings.view())); + else + return this->equals_ignoring_case(forward(strings)); + }()); + } + +private: + friend class String; + char const* m_characters{ nullptr }; + size_t m_length{ 0 }; +}; + +} + +ALWAYS_INLINE constexpr AK::StringView operator"" sv(char const* cstring, size_t length) +{ + VERIFY_NOT_REACHED(); + return AK::StringView(cstring, length); +} + +using AK::StringView; diff --git a/AK/AK/TemporaryChange.h b/LibC-Shim/AK/TemporaryChange.h similarity index 94% rename from AK/AK/TemporaryChange.h rename to LibC-Shim/AK/TemporaryChange.h index ea8fd5c..f585dbc 100644 --- a/AK/AK/TemporaryChange.h +++ b/LibC-Shim/AK/TemporaryChange.h @@ -1,29 +1,29 @@ -/* - * Copyright (c) 2018-2020, Andreas Kling - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -namespace AK { - -template -class TemporaryChange { -public: - TemporaryChange(T& variable, T value) - : m_variable(variable) - , m_old_value(variable) - { - m_variable = value; - } - ~TemporaryChange() { m_variable = m_old_value; } - -private: - T& m_variable; - T m_old_value; -}; - -} - -using AK::TemporaryChange; +/* + * Copyright (c) 2018-2020, Andreas Kling + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +namespace AK { + +template +class TemporaryChange { +public: + TemporaryChange(T& variable, T value) + : m_variable(variable) + , m_old_value(variable) + { + m_variable = value; + } + ~TemporaryChange() { m_variable = m_old_value; } + +private: + T& m_variable; + T m_old_value; +}; + +} + +using AK::TemporaryChange; diff --git a/LibC-Shim/AK/Time.cpp b/LibC-Shim/AK/Time.cpp new file mode 100644 index 0000000..5c9c8a4 --- /dev/null +++ b/LibC-Shim/AK/Time.cpp @@ -0,0 +1,2 @@ +#include "pch.h" +#include "Time.h" diff --git a/AK/AK/Time.h b/LibC-Shim/AK/Time.h similarity index 95% rename from AK/AK/Time.h rename to LibC-Shim/AK/Time.h index 8e421a8..1394f79 100644 --- a/AK/AK/Time.h +++ b/LibC-Shim/AK/Time.h @@ -1,378 +1,386 @@ -/* - * Copyright (c) 2018-2020, Andreas Kling - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once -#undef min -#undef max - -#include -#include -#include "./AK/Array.h" -#include "./AK/Assertions.h" -#include "./AK/Platform.h" -#include "./AK/Types.h" - - // Kernel and Userspace pull in the definitions from different places. - // Avoid trying to figure out which one. -struct timeval; -struct timespec; - -namespace AK { - -// Concept to detect types which look like timespec without requiring the type. -template -concept TimeSpecType = requires(T t) -{ - t.tv_sec; - t.tv_nsec; -}; - -constexpr bool is_leap_year(int year) -{ - return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0); -} - -// Month and day start at 1. Month must be >= 1 and <= 12. -// The return value is 0-indexed, that is 0 is Sunday, 1 is Monday, etc. -// Day may be negative or larger than the number of days -// in the given month. -unsigned day_of_week(int year, unsigned month, int day); - -// Month and day start at 1. Month must be >= 1 and <= 12. -// The return value is 0-indexed, that is Jan 1 is day 0. -// Day may be negative or larger than the number of days -// in the given month. If day is negative enough, the result -// can be negative. -constexpr int day_of_year(int year, unsigned month, int day) -{ - VERIFY(month >= 1 && month <= 12); - - constexpr Array seek_table = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }; - int day_of_year = seek_table[month - 1] + day - 1; - - if (is_leap_year(year) && month >= 3) - day_of_year++; - - return day_of_year; -} - -// Month starts at 1. Month must be >= 1 and <= 12. -int days_in_month(int year, unsigned month); - -constexpr int days_in_year(int year) -{ - return 365 + (is_leap_year(year) ? 1 : 0); -} - -constexpr int years_to_days_since_epoch(int year) -{ - int days = 0; - for (int current_year = 1970; current_year < year; ++current_year) - days += days_in_year(current_year); - for (int current_year = year; current_year < 1970; ++current_year) - days -= days_in_year(current_year); - return days; -} - -constexpr int days_since_epoch(int year, int month, int day) -{ - return years_to_days_since_epoch(year) + day_of_year(year, month, day); -} - -constexpr i64 seconds_since_epoch_to_year(i64 seconds) -{ - constexpr double seconds_per_year = 60.0 * 60.0 * 24.0 * 365.2425; - - // NOTE: We are not using floor() from to avoid LibC / DynamicLoader dependency issues. - auto round_down = [](double value) -> i64 { - auto as_i64 = static_cast(value); - - if ((value == as_i64) || (as_i64 >= 0)) - return as_i64; - return as_i64 - 1; - }; - - auto years_since_epoch = static_cast(seconds) / seconds_per_year; - return 1970 + round_down(years_since_epoch); -} - -/* - * Represents a time amount in a "safe" way. - * Minimum: 0 seconds, 0 nanoseconds - * Maximum: 2**63-1 seconds, 999'999'999 nanoseconds - * If any operation (e.g. 'from_timeval' or operator-) would over- or underflow, the closest legal value is returned instead. - * Inputs (e.g. to 'from_timespec') are allowed to be in non-normal form (e.g. "1 second, 2'012'345'678 nanoseconds" or "1 second, -2 microseconds"). - * Outputs (e.g. from 'to_timeval') are always in normal form. - */ -class Time { -public: - Time() = default; - Time(Time const&) = default; - Time& operator=(Time const&) = default; - - Time(Time&& other) - : m_seconds(exchange(other.m_seconds, 0)) - , m_nanoseconds(exchange(other.m_nanoseconds, 0)) - { - } - Time& operator=(Time&& other) - { - if (this != &other) { - m_seconds = exchange(other.m_seconds, 0); - m_nanoseconds = exchange(other.m_nanoseconds, 0); - } - return *this; - } - -private: - // This must be part of the header in order to make the various 'from_*' functions constexpr. - // However, sane_mod can only deal with a limited range of values for 'denominator', so this can't be made public. - ALWAYS_INLINE static constexpr i64 sane_mod(i64& numerator, i64 denominator) - { - VERIFY(2 <= denominator && denominator <= 1'000'000'000); - // '%' in C/C++ does not work in the obvious way: - // For example, -9 % 7 is -2, not +5. - // However, we want a representation like "(-2)*7 + (+5)". - i64 dividend = numerator / denominator; - numerator %= denominator; - if (numerator < 0) { - // Does not overflow: different signs. - numerator += denominator; - // Does not underflow: denominator >= 2. - dividend -= 1; - } - return dividend; - } - ALWAYS_INLINE static constexpr i32 sane_mod(i32& numerator, i32 denominator) - { - i64 numerator_64 = numerator; - i64 dividend = sane_mod(numerator_64, denominator); - // Does not underflow: numerator can only become smaller. - numerator = static_cast(numerator_64); - // Does not overflow: Will be smaller than original value of 'numerator'. - return static_cast(dividend); - } - -public: - constexpr static Time from_timestamp(i32 year, u8 month, u8 day, u8 hour, u8 minute, u8 second, u16 millisecond) - { - constexpr auto milliseconds_per_day = 86'400'000; - constexpr auto milliseconds_per_hour = 3'600'000; - constexpr auto milliseconds_per_minute = 60'000; - constexpr auto milliseconds_per_second = 1'000; - - i64 milliseconds_since_epoch = days_since_epoch(year, month, day); - milliseconds_since_epoch *= milliseconds_per_day; - - milliseconds_since_epoch += hour * milliseconds_per_hour; - milliseconds_since_epoch += minute * milliseconds_per_minute; - milliseconds_since_epoch += second * milliseconds_per_second; - milliseconds_since_epoch += millisecond; - - return from_milliseconds(milliseconds_since_epoch); - } - - constexpr static Time from_seconds(i64 seconds) { return Time(seconds, 0); } - constexpr static Time from_nanoseconds(i64 nanoseconds) - { - i64 seconds = sane_mod(nanoseconds, 1'000'000'000); - return Time(seconds, nanoseconds); - } - constexpr static Time from_microseconds(i64 microseconds) - { - i64 seconds = sane_mod(microseconds, 1'000'000); - return Time(seconds, microseconds * 1'000); - } - constexpr static Time from_milliseconds(i64 milliseconds) - { - i64 seconds = sane_mod(milliseconds, 1'000); - return Time(seconds, milliseconds * 1'000'000); - } - static Time from_ticks(clock_t, time_t); - static Time from_timespec(const struct timespec&); - static Time from_timeval(const struct timeval&); - // We don't pull in for the pretty min/max definitions because this file is also included in the Kernel - constexpr static Time min() { return Time(-_I64_MAX - 1LL, 0); }; - constexpr static Time zero() { return Time(0, 0); }; - constexpr static Time max() { return Time(_I64_MAX, 999'999'999); }; - -#ifndef KERNEL - static Time now_realtime(); - static Time now_realtime_coarse(); - static Time now_monotonic(); - static Time now_monotonic_coarse(); -#endif - - // Truncates towards zero (2.8s to 2s, -2.8s to -2s). - i64 to_truncated_seconds() const; - i64 to_truncated_milliseconds() const; - i64 to_truncated_microseconds() const; - // Rounds away from zero (2.3s to 3s, -2.3s to -3s). - i64 to_seconds() const; - i64 to_milliseconds() const; - i64 to_microseconds() const; - i64 to_nanoseconds() const; - timespec to_timespec() const; - // Rounds towards -inf (it was the easiest to implement). - timeval to_timeval() const; - - bool is_zero() const { return (m_seconds == 0) && (m_nanoseconds == 0); } - bool is_negative() const { return m_seconds < 0; } - - bool operator==(Time const& other) const { return this->m_seconds == other.m_seconds && this->m_nanoseconds == other.m_nanoseconds; } - bool operator!=(Time const& other) const { return !(*this == other); } - Time operator+(Time const& other) const; - Time& operator+=(Time const& other); - Time operator-(Time const& other) const; - Time& operator-=(Time const& other); - bool operator<(Time const& other) const; - bool operator<=(Time const& other) const; - bool operator>(Time const& other) const; - bool operator>=(Time const& other) const; - -private: - constexpr explicit Time(i64 seconds, u32 nanoseconds) - : m_seconds(seconds) - , m_nanoseconds(nanoseconds) - { - } - - static Time from_half_sanitized(i64 seconds, i32 extra_seconds, u32 nanoseconds); - - i64 m_seconds{ 0 }; - u32 m_nanoseconds{ 0 }; // Always less than 1'000'000'000 -}; - -template -ALWAYS_INLINE void timeval_sub(TimevalType const& a, TimevalType const& b, TimevalType& result) -{ - result.tv_sec = a.tv_sec - b.tv_sec; - result.tv_usec = a.tv_usec - b.tv_usec; - if (result.tv_usec < 0) { - --result.tv_sec; - result.tv_usec += 1'000'000; - } -} - -template -ALWAYS_INLINE void timeval_add(TimevalType const& a, TimevalType const& b, TimevalType& result) -{ - result.tv_sec = a.tv_sec + b.tv_sec; - result.tv_usec = a.tv_usec + b.tv_usec; - if (result.tv_usec >= 1'000'000) { - ++result.tv_sec; - result.tv_usec -= 1'000'000; - } -} - -template -ALWAYS_INLINE void timespec_sub(TimespecType const& a, TimespecType const& b, TimespecType& result) -{ - result.tv_sec = a.tv_sec - b.tv_sec; - result.tv_nsec = a.tv_nsec - b.tv_nsec; - if (result.tv_nsec < 0) { - --result.tv_sec; - result.tv_nsec += 1'000'000'000; - } -} - -template -ALWAYS_INLINE void timespec_add(TimespecType const& a, TimespecType const& b, TimespecType& result) -{ - result.tv_sec = a.tv_sec + b.tv_sec; - result.tv_nsec = a.tv_nsec + b.tv_nsec; - if (result.tv_nsec >= 1000'000'000) { - ++result.tv_sec; - result.tv_nsec -= 1000'000'000; - } -} - -template -ALWAYS_INLINE void timespec_add_timeval(TimespecType const& a, TimevalType const& b, TimespecType& result) -{ - result.tv_sec = a.tv_sec + b.tv_sec; - result.tv_nsec = a.tv_nsec + b.tv_usec * 1000; - if (result.tv_nsec >= 1000'000'000) { - ++result.tv_sec; - result.tv_nsec -= 1000'000'000; - } -} - -template -ALWAYS_INLINE void timeval_to_timespec(TimevalType const& tv, TimespecType& ts) -{ - ts.tv_sec = tv.tv_sec; - ts.tv_nsec = tv.tv_usec * 1000; -} - -template -ALWAYS_INLINE void timespec_to_timeval(TimespecType const& ts, TimevalType& tv) -{ - tv.tv_sec = ts.tv_sec; - tv.tv_usec = ts.tv_nsec / 1000; -} - -template -ALWAYS_INLINE bool operator>=(const T& a, const T& b) -{ - return a.tv_sec > b.tv_sec || (a.tv_sec == b.tv_sec && a.tv_nsec >= b.tv_nsec); -} - -template -ALWAYS_INLINE bool operator>(const T& a, const T& b) -{ - return a.tv_sec > b.tv_sec || (a.tv_sec == b.tv_sec && a.tv_nsec > b.tv_nsec); -} - -template -ALWAYS_INLINE bool operator<(const T& a, const T& b) -{ - return a.tv_sec < b.tv_sec || (a.tv_sec == b.tv_sec && a.tv_nsec < b.tv_nsec); -} - -template -ALWAYS_INLINE bool operator<=(const T& a, const T& b) - -{ - return a.tv_sec < b.tv_sec || (a.tv_sec == b.tv_sec && a.tv_nsec <= b.tv_nsec); -} - -template -ALWAYS_INLINE bool operator==(const T& a, const T& b) -{ - return a.tv_sec == b.tv_sec && a.tv_nsec == b.tv_nsec; -} - -template -ALWAYS_INLINE bool operator!=(const T& a, const T& b) -{ - return a.tv_sec != b.tv_sec || a.tv_nsec != b.tv_nsec; -} - -} - -using AK::day_of_week; -using AK::day_of_year; -using AK::days_in_month; -using AK::days_in_year; -using AK::days_since_epoch; -using AK::is_leap_year; -using AK::seconds_since_epoch_to_year; -using AK::Time; -using AK::timespec_add; -using AK::timespec_add_timeval; -using AK::timespec_sub; -using AK::timespec_to_timeval; -using AK::timeval_add; -using AK::timeval_sub; -using AK::timeval_to_timespec; -using AK::years_to_days_since_epoch; -using AK::operator<=; -using AK::operator<; -using AK::operator>; -using AK::operator>=; -using AK::operator==; -using AK::operator!=; +/* + * Copyright (c) 2018-2020, Andreas Kling + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once +#undef min +#undef max + +#include +#include +#include "Array.h" +#include "Assertions.h" +#include "Platform.h" +#include "Types.h" + + // Kernel and Userspace pull in the definitions from different places. + // Avoid trying to figure out which one. +struct timeval; +struct timespec; + +namespace AK { + +// Concept to detect types which look like timespec without requiring the type. +template +concept TimeSpecType = requires(T t) +{ + t.tv_sec; + t.tv_nsec; +}; + +constexpr bool is_leap_year(int year) +{ + return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0); +} + +// Month and day start at 1. Month must be >= 1 and <= 12. +// The return value is 0-indexed, that is 0 is Sunday, 1 is Monday, etc. +// Day may be negative or larger than the number of days +// in the given month. +unsigned day_of_week(int year, unsigned month, int day) +{ + VERIFY(month >= 1 && month <= 12); + constexpr Array seek_table = { 0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4 }; + if (month < 3) + --year; + + return (year + year / 4 - year / 100 + year / 400 + seek_table[month - 1] + day) % 7; +} + +// Month and day start at 1. Month must be >= 1 and <= 12. +// The return value is 0-indexed, that is Jan 1 is day 0. +// Day may be negative or larger than the number of days +// in the given month. If day is negative enough, the result +// can be negative. +constexpr int day_of_year(int year, unsigned month, int day) +{ + VERIFY(month >= 1 && month <= 12); + + constexpr Array seek_table = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }; + int day_of_year = seek_table[month - 1] + day - 1; + + if (is_leap_year(year) && month >= 3) + day_of_year++; + + return day_of_year; +} + +// Month starts at 1. Month must be >= 1 and <= 12. +int days_in_month(int year, unsigned month); + +constexpr int days_in_year(int year) +{ + return 365 + (is_leap_year(year) ? 1 : 0); +} + +constexpr int years_to_days_since_epoch(int year) +{ + int days = 0; + for (int current_year = 1970; current_year < year; ++current_year) + days += days_in_year(current_year); + for (int current_year = year; current_year < 1970; ++current_year) + days -= days_in_year(current_year); + return days; +} + +constexpr int days_since_epoch(int year, int month, int day) +{ + return years_to_days_since_epoch(year) + day_of_year(year, month, day); +} + +constexpr i64 seconds_since_epoch_to_year(i64 seconds) +{ + constexpr double seconds_per_year = 60.0 * 60.0 * 24.0 * 365.2425; + + // NOTE: We are not using floor() from to avoid LibC / DynamicLoader dependency issues. + auto round_down = [](double value) -> i64 { + auto as_i64 = static_cast(value); + + if ((value == as_i64) || (as_i64 >= 0)) + return as_i64; + return as_i64 - 1; + }; + + auto years_since_epoch = static_cast(seconds) / seconds_per_year; + return 1970 + round_down(years_since_epoch); +} + +/* + * Represents a time amount in a "safe" way. + * Minimum: 0 seconds, 0 nanoseconds + * Maximum: 2**63-1 seconds, 999'999'999 nanoseconds + * If any operation (e.g. 'from_timeval' or operator-) would over- or underflow, the closest legal value is returned instead. + * Inputs (e.g. to 'from_timespec') are allowed to be in non-normal form (e.g. "1 second, 2'012'345'678 nanoseconds" or "1 second, -2 microseconds"). + * Outputs (e.g. from 'to_timeval') are always in normal form. + */ +class Time { +public: + Time() = default; + Time(Time const&) = default; + Time& operator=(Time const&) = default; + + Time(Time&& other) + : m_seconds(exchange(other.m_seconds, 0)) + , m_nanoseconds(exchange(other.m_nanoseconds, 0)) + { + } + Time& operator=(Time&& other) + { + if (this != &other) { + m_seconds = exchange(other.m_seconds, 0); + m_nanoseconds = exchange(other.m_nanoseconds, 0); + } + return *this; + } + +private: + // This must be part of the header in order to make the various 'from_*' functions constexpr. + // However, sane_mod can only deal with a limited range of values for 'denominator', so this can't be made public. + ALWAYS_INLINE static constexpr i64 sane_mod(i64& numerator, i64 denominator) + { + VERIFY(2 <= denominator && denominator <= 1'000'000'000); + // '%' in C/C++ does not work in the obvious way: + // For example, -9 % 7 is -2, not +5. + // However, we want a representation like "(-2)*7 + (+5)". + i64 dividend = numerator / denominator; + numerator %= denominator; + if (numerator < 0) { + // Does not overflow: different signs. + numerator += denominator; + // Does not underflow: denominator >= 2. + dividend -= 1; + } + return dividend; + } + ALWAYS_INLINE static constexpr i32 sane_mod(i32& numerator, i32 denominator) + { + i64 numerator_64 = numerator; + i64 dividend = sane_mod(numerator_64, denominator); + // Does not underflow: numerator can only become smaller. + numerator = static_cast(numerator_64); + // Does not overflow: Will be smaller than original value of 'numerator'. + return static_cast(dividend); + } + +public: + constexpr static Time from_timestamp(i32 year, u8 month, u8 day, u8 hour, u8 minute, u8 second, u16 millisecond) + { + constexpr auto milliseconds_per_day = 86'400'000; + constexpr auto milliseconds_per_hour = 3'600'000; + constexpr auto milliseconds_per_minute = 60'000; + constexpr auto milliseconds_per_second = 1'000; + + i64 milliseconds_since_epoch = days_since_epoch(year, month, day); + milliseconds_since_epoch *= milliseconds_per_day; + + milliseconds_since_epoch += hour * milliseconds_per_hour; + milliseconds_since_epoch += minute * milliseconds_per_minute; + milliseconds_since_epoch += second * milliseconds_per_second; + milliseconds_since_epoch += millisecond; + + return from_milliseconds(milliseconds_since_epoch); + } + + constexpr static Time from_seconds(i64 seconds) { return Time(seconds, 0); } + constexpr static Time from_nanoseconds(i64 nanoseconds) + { + i64 seconds = sane_mod(nanoseconds, 1'000'000'000); + return Time(seconds, nanoseconds); + } + constexpr static Time from_microseconds(i64 microseconds) + { + i64 seconds = sane_mod(microseconds, 1'000'000); + return Time(seconds, microseconds * 1'000); + } + constexpr static Time from_milliseconds(i64 milliseconds) + { + i64 seconds = sane_mod(milliseconds, 1'000); + return Time(seconds, milliseconds * 1'000'000); + } + static Time from_ticks(clock_t, time_t); + static Time from_timespec(const struct timespec&); + static Time from_timeval(const struct timeval&); + // We don't pull in for the pretty min/max definitions because this file is also included in the Kernel + constexpr static Time min() { return Time(-_I64_MAX - 1LL, 0); }; + constexpr static Time zero() { return Time(0, 0); }; + constexpr static Time max() { return Time(_I64_MAX, 999'999'999); }; + +#ifndef KERNEL + static Time now_realtime(); + static Time now_realtime_coarse(); + static Time now_monotonic(); + static Time now_monotonic_coarse(); +#endif + + // Truncates towards zero (2.8s to 2s, -2.8s to -2s). + i64 to_truncated_seconds() const; + i64 to_truncated_milliseconds() const; + i64 to_truncated_microseconds() const; + // Rounds away from zero (2.3s to 3s, -2.3s to -3s). + i64 to_seconds() const; + i64 to_milliseconds() const; + i64 to_microseconds() const; + i64 to_nanoseconds() const; + timespec to_timespec() const; + // Rounds towards -inf (it was the easiest to implement). + timeval to_timeval() const; + + bool is_zero() const { return (m_seconds == 0) && (m_nanoseconds == 0); } + bool is_negative() const { return m_seconds < 0; } + + bool operator==(Time const& other) const { return this->m_seconds == other.m_seconds && this->m_nanoseconds == other.m_nanoseconds; } + bool operator!=(Time const& other) const { return !(*this == other); } + Time operator+(Time const& other) const; + Time& operator+=(Time const& other); + Time operator-(Time const& other) const; + Time& operator-=(Time const& other); + bool operator<(Time const& other) const; + bool operator<=(Time const& other) const; + bool operator>(Time const& other) const; + bool operator>=(Time const& other) const; + +private: + constexpr explicit Time(i64 seconds, u32 nanoseconds) + : m_seconds(seconds) + , m_nanoseconds(nanoseconds) + { + } + + static Time from_half_sanitized(i64 seconds, i32 extra_seconds, u32 nanoseconds); + + i64 m_seconds{ 0 }; + u32 m_nanoseconds{ 0 }; // Always less than 1'000'000'000 +}; + +template +ALWAYS_INLINE void timeval_sub(TimevalType const& a, TimevalType const& b, TimevalType& result) +{ + result.tv_sec = a.tv_sec - b.tv_sec; + result.tv_usec = a.tv_usec - b.tv_usec; + if (result.tv_usec < 0) { + --result.tv_sec; + result.tv_usec += 1'000'000; + } +} + +template +ALWAYS_INLINE void timeval_add(TimevalType const& a, TimevalType const& b, TimevalType& result) +{ + result.tv_sec = a.tv_sec + b.tv_sec; + result.tv_usec = a.tv_usec + b.tv_usec; + if (result.tv_usec >= 1'000'000) { + ++result.tv_sec; + result.tv_usec -= 1'000'000; + } +} + +template +ALWAYS_INLINE void timespec_sub(TimespecType const& a, TimespecType const& b, TimespecType& result) +{ + result.tv_sec = a.tv_sec - b.tv_sec; + result.tv_nsec = a.tv_nsec - b.tv_nsec; + if (result.tv_nsec < 0) { + --result.tv_sec; + result.tv_nsec += 1'000'000'000; + } +} + +template +ALWAYS_INLINE void timespec_add(TimespecType const& a, TimespecType const& b, TimespecType& result) +{ + result.tv_sec = a.tv_sec + b.tv_sec; + result.tv_nsec = a.tv_nsec + b.tv_nsec; + if (result.tv_nsec >= 1000'000'000) { + ++result.tv_sec; + result.tv_nsec -= 1000'000'000; + } +} + +template +ALWAYS_INLINE void timespec_add_timeval(TimespecType const& a, TimevalType const& b, TimespecType& result) +{ + result.tv_sec = a.tv_sec + b.tv_sec; + result.tv_nsec = a.tv_nsec + b.tv_usec * 1000; + if (result.tv_nsec >= 1000'000'000) { + ++result.tv_sec; + result.tv_nsec -= 1000'000'000; + } +} + +template +ALWAYS_INLINE void timeval_to_timespec(TimevalType const& tv, TimespecType& ts) +{ + ts.tv_sec = tv.tv_sec; + ts.tv_nsec = tv.tv_usec * 1000; +} + +template +ALWAYS_INLINE void timespec_to_timeval(TimespecType const& ts, TimevalType& tv) +{ + tv.tv_sec = ts.tv_sec; + tv.tv_usec = ts.tv_nsec / 1000; +} + +template +ALWAYS_INLINE bool operator>=(const T& a, const T& b) +{ + return a.tv_sec > b.tv_sec || (a.tv_sec == b.tv_sec && a.tv_nsec >= b.tv_nsec); +} + +template +ALWAYS_INLINE bool operator>(const T& a, const T& b) +{ + return a.tv_sec > b.tv_sec || (a.tv_sec == b.tv_sec && a.tv_nsec > b.tv_nsec); +} + +template +ALWAYS_INLINE bool operator<(const T& a, const T& b) +{ + return a.tv_sec < b.tv_sec || (a.tv_sec == b.tv_sec && a.tv_nsec < b.tv_nsec); +} + +template +ALWAYS_INLINE bool operator<=(const T& a, const T& b) + +{ + return a.tv_sec < b.tv_sec || (a.tv_sec == b.tv_sec && a.tv_nsec <= b.tv_nsec); +} + +template +ALWAYS_INLINE bool operator==(const T& a, const T& b) +{ + return a.tv_sec == b.tv_sec && a.tv_nsec == b.tv_nsec; +} + +template +ALWAYS_INLINE bool operator!=(const T& a, const T& b) +{ + return a.tv_sec != b.tv_sec || a.tv_nsec != b.tv_nsec; +} + +} + +using AK::day_of_week; +using AK::day_of_year; +using AK::days_in_month; +using AK::days_in_year; +using AK::days_since_epoch; +using AK::is_leap_year; +using AK::seconds_since_epoch_to_year; +using AK::Time; +using AK::timespec_add; +using AK::timespec_add_timeval; +using AK::timespec_sub; +using AK::timespec_to_timeval; +using AK::timeval_add; +using AK::timeval_sub; +using AK::timeval_to_timespec; +using AK::years_to_days_since_epoch; +using AK::operator<=; +using AK::operator<; +using AK::operator>; +using AK::operator>=; +using AK::operator==; +using AK::operator!=; diff --git a/AK/AK/Traits.h b/LibC-Shim/AK/Traits.h similarity index 90% rename from AK/AK/Traits.h rename to LibC-Shim/AK/Traits.h index 0821b43..c8d4c60 100644 --- a/AK/AK/Traits.h +++ b/LibC-Shim/AK/Traits.h @@ -1,79 +1,79 @@ -/* - * Copyright (c) 2018-2022, Andreas Kling - * - * SPDX-License-Identifier: BSD-2-Clause - */ - - -#pragma once - -#include -#include "./AK/BitCast.h" -#include "./AK/Concepts.h" -#include "./AK/Forward.h" -#include "./AK/HashFunctions.h" -#include "./AK/StringHash.h" - -namespace AK { - -template -struct GenericTraits { - using PeekType = T&; - using ConstPeekType = T const&; - static constexpr bool is_trivial() { return false; } - static constexpr bool equals(const T& a, const T& b) { return a == b; } - template U> - static bool equals(U const& a, T const& b) { return a == b; } -}; - -template -struct Traits : public GenericTraits { -}; - -template - requires(IsIntegral) struct Traits : public GenericTraits { - static constexpr bool is_trivial() { return true; } - static constexpr unsigned hash(T value) - { - if constexpr (sizeof(T) < 8) - return int_hash(value); - else - return u64_hash(value); - } -}; - -template - requires(IsFloatingPoint) struct Traits : public GenericTraits { - static constexpr bool is_trivial() { return true; } - static constexpr unsigned hash(T value) - { - if constexpr (sizeof(T) < 8) - return int_hash(bit_cast(value)); - else - return u64_hash(bit_cast(value)); - } -}; - -template - requires(IsPointer && !Detail::IsPointerOfType) struct Traits : public GenericTraits { - static unsigned hash(T p) { return ptr_hash((FlatPtr)p); } - static constexpr bool is_trivial() { return true; } -}; - -template -struct Traits : public GenericTraits { - static unsigned hash(T value) { return Traits>::hash(to_underlying(value)); } - static constexpr bool is_trivial() { return Traits>::is_trivial(); } -}; - -template - requires(Detail::IsPointerOfType) struct Traits : public GenericTraits { - static unsigned hash(T const value) { return string_hash(value, strlen(value)); } - static constexpr bool equals(T const a, T const b) { return strcmp(a, b); } - static constexpr bool is_trivial() { return true; } -}; - -} - -using AK::GenericTraits; -using AK::Traits; \ No newline at end of file +/* + * Copyright (c) 2018-2022, Andreas Kling + * + * SPDX-License-Identifier: BSD-2-Clause + */ + + +#pragma once + +#include +#include "BitCast.h" +#include "Concepts.h" +#include "Forward.h" +#include "HashFunctions.h" +#include "StringHash.h" + +namespace AK { + +template +struct GenericTraits { + using PeekType = T&; + using ConstPeekType = T const&; + static constexpr bool is_trivial() { return false; } + static constexpr bool equals(const T& a, const T& b) { return a == b; } + template U> + static bool equals(U const& a, T const& b) { return a == b; } +}; + +template +struct Traits : public GenericTraits { +}; + +template + requires(IsIntegral) struct Traits : public GenericTraits { + static constexpr bool is_trivial() { return true; } + static constexpr unsigned hash(T value) + { + if constexpr (sizeof(T) < 8) + return int_hash(value); + else + return u64_hash(value); + } +}; + +template + requires(IsFloatingPoint) struct Traits : public GenericTraits { + static constexpr bool is_trivial() { return true; } + static constexpr unsigned hash(T value) + { + if constexpr (sizeof(T) < 8) + return int_hash(bit_cast(value)); + else + return u64_hash(bit_cast(value)); + } +}; + +template + requires(IsPointer && !Detail::IsPointerOfType) struct Traits : public GenericTraits { + static unsigned hash(T p) { return ptr_hash((FlatPtr)p); } + static constexpr bool is_trivial() { return true; } +}; + +template +struct Traits : public GenericTraits { + static unsigned hash(T value) { return Traits>::hash(to_underlying(value)); } + static constexpr bool is_trivial() { return Traits>::is_trivial(); } +}; + +template + requires(Detail::IsPointerOfType) struct Traits : public GenericTraits { + static unsigned hash(T const value) { return string_hash(value, strlen(value)); } + static constexpr bool equals(T const a, T const b) { return strcmp(a, b); } + static constexpr bool is_trivial() { return true; } +}; + +} + +using AK::GenericTraits; +using AK::Traits; diff --git a/AK/AK/Try.h b/LibC-Shim/AK/Try.h similarity index 97% rename from AK/AK/Try.h rename to LibC-Shim/AK/Try.h index 35ac8c4..654f232 100644 --- a/AK/AK/Try.h +++ b/LibC-Shim/AK/Try.h @@ -1,27 +1,27 @@ -/* - * Copyright (c) 2021, Andreas Kling - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - - // NOTE: This macro works with any result type that has the expected APIs. - // It's designed with AK::Result and AK::Error in mind. -/*#define TRY(expression) \ - ({ \ - auto _temporary_result = (expression); \ - if (_temporary_result.is_error()) \ - return _temporary_result.release_error(); \ - _temporary_result.release_value(); \ - }) - -#define MUST(expression) \ - ({ \ - auto _temporary_result = (expression); \ - VERIFY(!_temporary_result.is_error()); \ - _temporary_result.release_value(); \ - })*/ - -#define TRY(expression) (expression.release_value()) -#define MUST(expression) (expression.release_value()) +/* + * Copyright (c) 2021, Andreas Kling + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + + // NOTE: This macro works with any result type that has the expected APIs. + // It's designed with AK::Result and AK::Error in mind. +/*#define TRY(expression) \ + ({ \ + auto _temporary_result = (expression); \ + if (_temporary_result.is_error()) \ + return _temporary_result.release_error(); \ + _temporary_result.release_value(); \ + }) + +#define MUST(expression) \ + ({ \ + auto _temporary_result = (expression); \ + VERIFY(!_temporary_result.is_error()); \ + _temporary_result.release_value(); \ + })*/ + +#define TRY(expression) (expression.release_value()) +#define MUST(expression) (expression.release_value()) diff --git a/AK/AK/TypeCasts.h b/LibC-Shim/AK/TypeCasts.h similarity index 84% rename from AK/AK/TypeCasts.h rename to LibC-Shim/AK/TypeCasts.h index fbc32b1..b1caaf7 100644 --- a/AK/AK/TypeCasts.h +++ b/LibC-Shim/AK/TypeCasts.h @@ -1,30 +1,30 @@ -/* - * Copyright (c) 2020-2021, Andreas Kling - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include "./AK/Assertions.h" -#include "./AK/Platform.h" -#include "./AK/StdLibExtras.h" - -namespace AK { - -template -ALWAYS_INLINE bool is(InputType& input); - -template -ALWAYS_INLINE bool is(InputType* input); - -template -ALWAYS_INLINE CopyConst* verify_cast(InputType* input); - -template -ALWAYS_INLINE CopyConst& verify_cast(InputType& input); - -} - -using AK::is; -using AK::verify_cast; +/* + * Copyright (c) 2020-2021, Andreas Kling + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include "Assertions.h" +#include "Platform.h" +#include "StdLibExtras.h" + +namespace AK { + +template +ALWAYS_INLINE bool is(InputType& input); + +template +ALWAYS_INLINE bool is(InputType* input); + +template +ALWAYS_INLINE CopyConst* verify_cast(InputType* input); + +template +ALWAYS_INLINE CopyConst& verify_cast(InputType& input); + +} + +using AK::is; +using AK::verify_cast; diff --git a/AK/AK/TypedTransfer.h b/LibC-Shim/AK/TypedTransfer.h similarity index 92% rename from AK/AK/TypedTransfer.h rename to LibC-Shim/AK/TypedTransfer.h index 50e9667..6f70f09 100644 --- a/AK/AK/TypedTransfer.h +++ b/LibC-Shim/AK/TypedTransfer.h @@ -1 +1 @@ -#pragma once +#pragma once diff --git a/AK/AK/Types.h b/LibC-Shim/AK/Types.h similarity index 79% rename from AK/AK/Types.h rename to LibC-Shim/AK/Types.h index 3b464a0..f702f07 100644 --- a/AK/AK/Types.h +++ b/LibC-Shim/AK/Types.h @@ -1,78 +1,73 @@ -/* - * Copyright (c) 2018-2020, Andreas Kling - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include -#include "./AK/IterationDecision.h" -#include "./AK/Platform.h" -#include "./AK/StdLibExtras.h" - -using u64 = uint64_t; -using u32 = uint32_t; -using u16 = uint16_t; -using u8 = uint8_t; -using i64 = int64_t; -using i32 = int32_t; -using i16 = int16_t; -using i8 = int8_t; - -using FlatPtr = Conditional; - -constexpr u64 KiB = 1024; -constexpr u64 MiB = KiB * KiB; -constexpr u64 GiB = KiB * KiB * KiB; -constexpr u64 TiB = KiB * KiB * KiB * KiB; -constexpr u64 PiB = KiB * KiB * KiB * KiB * KiB; -constexpr u64 EiB = KiB * KiB * KiB * KiB * KiB * KiB; - -namespace std { // NOLINT(cert-dcl58-cpp) nullptr_t must be in ::std:: for some analysis tools - using nullptr_t = decltype(nullptr); -} - -static constexpr FlatPtr explode_byte(u8 b) -{ - FlatPtr value = b; - if constexpr (sizeof(FlatPtr) == 4) - return value << 24 | value << 16 | value << 8 | value; - else if (sizeof(FlatPtr) == 8) - return value << 56 | value << 48 | value << 40 | value << 32 | value << 24 | value << 16 | value << 8 | value; -} - -static_assert(explode_byte(0xff) == (FlatPtr)0xffffffffffffffffull); -static_assert(explode_byte(0x80) == (FlatPtr)0x8080808080808080ull); -static_assert(explode_byte(0x7f) == (FlatPtr)0x7f7f7f7f7f7f7f7full); -static_assert(explode_byte(0) == 0); - -constexpr size_t align_up_to(const size_t value, const size_t alignment) -{ - return (value + (alignment - 1)) & ~(alignment - 1); -} - -constexpr size_t align_down_to(const size_t value, const size_t alignment) -{ - return value & ~(alignment - 1); -} - -enum class TriState : u8 { - False, - True, - Unknown -}; - -namespace AK { - -enum MemoryOrder { - memory_order_relaxed = 0, - memory_order_consume = 1, - memory_order_acquire = 2, - memory_order_release = 3, - memory_order_acq_rel = 4, - memory_order_seq_cst = 5 -}; - -} - +/* + * Copyright (c) 2018-2020, Andreas Kling + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include "IterationDecision.h" +#include "Platform.h" +#include "StdLibExtras.h" + +using u64 = uint64_t; +using u32 = uint32_t; +using u16 = uint16_t; +using u8 = uint8_t; +using i64 = int64_t; +using i32 = int32_t; +using i16 = int16_t; +using i8 = int8_t; + +using FlatPtr = Conditional; + +constexpr u64 KiB = 1024; +constexpr u64 MiB = KiB * KiB; +constexpr u64 GiB = KiB * KiB * KiB; +constexpr u64 TiB = KiB * KiB * KiB * KiB; +constexpr u64 PiB = KiB * KiB * KiB * KiB * KiB; +constexpr u64 EiB = KiB * KiB * KiB * KiB * KiB * KiB; + +namespace std { // NOLINT(cert-dcl58-cpp) nullptr_t must be in ::std:: for some analysis tools + using nullptr_t = decltype(nullptr); +} + +static constexpr FlatPtr explode_byte(u8 b) +{ + FlatPtr value = b; + if constexpr (sizeof(FlatPtr) == 4) + return value << 24 | value << 16 | value << 8 | value; + else if (sizeof(FlatPtr) == 8) + return value << 56 | value << 48 | value << 40 | value << 32 | value << 24 | value << 16 | value << 8 | value; +} + +constexpr size_t align_up_to(const size_t value, const size_t alignment) +{ + return (value + (alignment - 1)) & ~(alignment - 1); +} + +constexpr size_t align_down_to(const size_t value, const size_t alignment) +{ + return value & ~(alignment - 1); +} + +enum class TriState : u8 { + False, + True, + Unknown +}; + +namespace AK { + +enum MemoryOrder { + memory_order_relaxed = 0, + memory_order_consume = 1, + memory_order_acquire = 2, + memory_order_release = 3, + memory_order_acq_rel = 4, + memory_order_seq_cst = 5 +}; + +} + diff --git a/AK/AK/UnicodeUtils.h b/LibC-Shim/AK/UnicodeUtils.h similarity index 94% rename from AK/AK/UnicodeUtils.h rename to LibC-Shim/AK/UnicodeUtils.h index 69f1542..a055cdf 100644 --- a/AK/AK/UnicodeUtils.h +++ b/LibC-Shim/AK/UnicodeUtils.h @@ -1,38 +1,38 @@ -/* - * Copyright (c) 2021, Max Wipfli - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include "./AK/Forward.h" - -namespace AK::UnicodeUtils { - -template -constexpr int code_point_to_utf8(u32 code_point, Callback callback) -{ - if (code_point <= 0x7f) { - callback((char)code_point); - return 1; - } else if (code_point <= 0x07ff) { - callback((char)(((code_point >> 6) & 0x1f) | 0xc0)); - callback((char)(((code_point >> 0) & 0x3f) | 0x80)); - return 2; - } else if (code_point <= 0xffff) { - callback((char)(((code_point >> 12) & 0x0f) | 0xe0)); - callback((char)(((code_point >> 6) & 0x3f) | 0x80)); - callback((char)(((code_point >> 0) & 0x3f) | 0x80)); - return 3; - } else if (code_point <= 0x10ffff) { - callback((char)(((code_point >> 18) & 0x07) | 0xf0)); - callback((char)(((code_point >> 12) & 0x3f) | 0x80)); - callback((char)(((code_point >> 6) & 0x3f) | 0x80)); - callback((char)(((code_point >> 0) & 0x3f) | 0x80)); - return 4; - } - return -1; -} - -} +/* + * Copyright (c) 2021, Max Wipfli + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include "Forward.h" + +namespace AK::UnicodeUtils { + +template +constexpr int code_point_to_utf8(u32 code_point, Callback callback) +{ + if (code_point <= 0x7f) { + callback((char)code_point); + return 1; + } else if (code_point <= 0x07ff) { + callback((char)(((code_point >> 6) & 0x1f) | 0xc0)); + callback((char)(((code_point >> 0) & 0x3f) | 0x80)); + return 2; + } else if (code_point <= 0xffff) { + callback((char)(((code_point >> 12) & 0x0f) | 0xe0)); + callback((char)(((code_point >> 6) & 0x3f) | 0x80)); + callback((char)(((code_point >> 0) & 0x3f) | 0x80)); + return 3; + } else if (code_point <= 0x10ffff) { + callback((char)(((code_point >> 18) & 0x07) | 0xf0)); + callback((char)(((code_point >> 12) & 0x3f) | 0x80)); + callback((char)(((code_point >> 6) & 0x3f) | 0x80)); + callback((char)(((code_point >> 0) & 0x3f) | 0x80)); + return 4; + } + return -1; +} + +} diff --git a/AK/AK/Utf16View.cpp b/LibC-Shim/AK/Utf16View.cpp similarity index 95% rename from AK/AK/Utf16View.cpp rename to LibC-Shim/AK/Utf16View.cpp index b645a6e..b37b806 100644 --- a/AK/AK/Utf16View.cpp +++ b/LibC-Shim/AK/Utf16View.cpp @@ -1,2 +1,2 @@ -#include "pch.h" -#include "Utf16View.h" +#include "pch.h" +#include "Utf16View.h" diff --git a/AK/AK/Utf16View.h b/LibC-Shim/AK/Utf16View.h similarity index 90% rename from AK/AK/Utf16View.h rename to LibC-Shim/AK/Utf16View.h index 299e316..bde3efa 100644 --- a/AK/AK/Utf16View.h +++ b/LibC-Shim/AK/Utf16View.h @@ -1,120 +1,120 @@ -/* - * Copyright (c) 2021, Tim Flynn - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include "./AK/Format.h" -#include "./AK/Forward.h" -#include "./AK/Optional.h" -#include "./AK/Span.h" -#include "./AK/String.h" -#include "./AK/Types.h" -#include "./AK/Vector.h" - -namespace AK { - -Vector utf8_to_utf16(StringView); -Vector utf8_to_utf16(Utf8View const&); -Vector utf32_to_utf16(Utf32View const&); -void code_point_to_utf16(Vector&, u32); - -class Utf16View; - -class Utf16CodePointIterator { - friend class Utf16View; - -public: - Utf16CodePointIterator() = default; - ~Utf16CodePointIterator() = default; - - bool operator==(Utf16CodePointIterator const& other) const; - - bool operator!=(Utf16CodePointIterator const& other) const; - - Utf16CodePointIterator& operator++(); - u32 operator*() const; - - size_t length_in_code_units() const; - -private: - Utf16CodePointIterator(u16 const* ptr, size_t length) - : m_ptr(ptr) - , m_remaining_code_units(length) - { - } - - u16 const* m_ptr{ nullptr }; - size_t m_remaining_code_units{ 0 }; -}; - -class Utf16View { -public: - static bool is_high_surrogate(u16); - static bool is_low_surrogate(u16); - static u32 decode_surrogate_pair(u16 high_surrogate, u16 low_surrogate); - - Utf16View() = default; - ~Utf16View() = default; - - explicit Utf16View(Span code_units) - : m_code_units(code_units) - { - } - - bool operator==(Utf16View const& other) const { return m_code_units == other.m_code_units; } - - enum class AllowInvalidCodeUnits { - Yes, - No, - }; - - String to_utf8(AllowInvalidCodeUnits = AllowInvalidCodeUnits::No) const; - - bool is_null() const; - bool is_empty() const; - size_t length_in_code_units() const; - size_t length_in_code_points() const; - - Utf16CodePointIterator begin() const; - Utf16CodePointIterator end() const; - - u16 const* data() const; - u16 code_unit_at(size_t index) const; - u32 code_point_at(size_t index) const; - - size_t code_point_offset_of(size_t code_unit_offset) const; - size_t code_unit_offset_of(size_t code_point_offset) const; - size_t code_unit_offset_of(Utf16CodePointIterator const&) const; - - Utf16View substring_view(size_t code_unit_offset, size_t code_unit_length) const; - Utf16View substring_view(size_t code_unit_offset) const; - - Utf16View unicode_substring_view(size_t code_point_offset, size_t code_point_length) const; - Utf16View unicode_substring_view(size_t code_point_offset) const; - - bool validate(size_t& valid_code_units) const; - bool validate() const; - - bool equals_ignoring_case(Utf16View const&) const; - -private: - u16 const* begin_ptr() const; - u16 const* end_ptr() const; - - size_t calculate_length_in_code_points() const; - - Span m_code_units; - mutable Optional m_length_in_code_points; -}; - -} - -template<> -struct AK::Formatter : Formatter { - ErrorOr format(FormatBuilder& builder, AK::Utf16View const& value); -}; - -using AK::Utf16View; +/* + * Copyright (c) 2021, Tim Flynn + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include "Format.h" +#include "Forward.h" +#include "Optional.h" +#include "Span.h" +#include "String.h" +#include "Types.h" +#include "Vector.h" + +namespace AK { + +Vector utf8_to_utf16(StringView); +Vector utf8_to_utf16(Utf8View const&); +Vector utf32_to_utf16(Utf32View const&); +void code_point_to_utf16(Vector&, u32); + +class Utf16View; + +class Utf16CodePointIterator { + friend class Utf16View; + +public: + Utf16CodePointIterator() = default; + ~Utf16CodePointIterator() = default; + + bool operator==(Utf16CodePointIterator const& other) const; + + bool operator!=(Utf16CodePointIterator const& other) const; + + Utf16CodePointIterator& operator++(); + u32 operator*() const; + + size_t length_in_code_units() const; + +private: + Utf16CodePointIterator(u16 const* ptr, size_t length) + : m_ptr(ptr) + , m_remaining_code_units(length) + { + } + + u16 const* m_ptr{ nullptr }; + size_t m_remaining_code_units{ 0 }; +}; + +class Utf16View { +public: + static bool is_high_surrogate(u16); + static bool is_low_surrogate(u16); + static u32 decode_surrogate_pair(u16 high_surrogate, u16 low_surrogate); + + Utf16View() = default; + ~Utf16View() = default; + + explicit Utf16View(Span code_units) + : m_code_units(code_units) + { + } + + bool operator==(Utf16View const& other) const { return m_code_units == other.m_code_units; } + + enum class AllowInvalidCodeUnits { + Yes, + No, + }; + + String to_utf8(AllowInvalidCodeUnits = AllowInvalidCodeUnits::No) const; + + bool is_null() const; + bool is_empty() const; + size_t length_in_code_units() const; + size_t length_in_code_points() const; + + Utf16CodePointIterator begin() const; + Utf16CodePointIterator end() const; + + u16 const* data() const; + u16 code_unit_at(size_t index) const; + u32 code_point_at(size_t index) const; + + size_t code_point_offset_of(size_t code_unit_offset) const; + size_t code_unit_offset_of(size_t code_point_offset) const; + size_t code_unit_offset_of(Utf16CodePointIterator const&) const; + + Utf16View substring_view(size_t code_unit_offset, size_t code_unit_length) const; + Utf16View substring_view(size_t code_unit_offset) const; + + Utf16View unicode_substring_view(size_t code_point_offset, size_t code_point_length) const; + Utf16View unicode_substring_view(size_t code_point_offset) const; + + bool validate(size_t& valid_code_units) const; + bool validate() const; + + bool equals_ignoring_case(Utf16View const&) const; + +private: + u16 const* begin_ptr() const; + u16 const* end_ptr() const; + + size_t calculate_length_in_code_points() const; + + Span m_code_units; + mutable Optional m_length_in_code_points; +}; + +} + +template<> +struct AK::Formatter : Formatter { + ErrorOr format(FormatBuilder& builder, AK::Utf16View const& value); +}; + +using AK::Utf16View; diff --git a/AK/AK/Utf32View.cpp b/LibC-Shim/AK/Utf32View.cpp similarity index 95% rename from AK/AK/Utf32View.cpp rename to LibC-Shim/AK/Utf32View.cpp index f9fd183..bb522bb 100644 --- a/AK/AK/Utf32View.cpp +++ b/LibC-Shim/AK/Utf32View.cpp @@ -1,2 +1,2 @@ -#include "pch.h" -#include "Utf32View.h" +#include "pch.h" +#include "Utf32View.h" diff --git a/AK/AK/Utf32View.h b/LibC-Shim/AK/Utf32View.h similarity index 91% rename from AK/AK/Utf32View.h rename to LibC-Shim/AK/Utf32View.h index b0d4d98..a4102c8 100644 --- a/AK/AK/Utf32View.h +++ b/LibC-Shim/AK/Utf32View.h @@ -1,81 +1,81 @@ -/* - * Copyright (c) 2020, Andreas Kling - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include "./AK/Assertions.h" -#include "./AK/Checked.h" -#include "./AK/Types.h" - -namespace AK { - -class Utf32View; - -class Utf32CodePointIterator { - friend class Utf32View; - -public: - Utf32CodePointIterator() = default; - ~Utf32CodePointIterator() = default; - - bool operator==(Utf32CodePointIterator const& other) const; - bool operator!=(Utf32CodePointIterator const& other) const; - Utf32CodePointIterator& operator++(); - ssize_t operator-(Utf32CodePointIterator const& other) const; - u32 operator*() const; - - constexpr int code_point_length_in_bytes() const { return sizeof(u32); } - bool done() const { return !m_length; } - -private: - Utf32CodePointIterator(u32 const* ptr, size_t length) - : m_ptr(ptr) - , m_length((ssize_t)length) - { - } - u32 const* m_ptr{ nullptr }; - ssize_t m_length{ -1 }; -}; - -class Utf32View { -public: - using Iterator = Utf32CodePointIterator; - - Utf32View() = default; - Utf32View(u32 const* code_points, size_t length) - : m_code_points(code_points) - , m_length(length) - { - } - - Utf32CodePointIterator begin() const; - - Utf32CodePointIterator end() const; - - u32 at(size_t index) const; - - u32 operator[](size_t index) const { return at(index); } - - u32 const* code_points() const { return m_code_points; } - bool is_empty() const { return m_length == 0; } - bool is_null() const { return !m_code_points; } - size_t length() const { return m_length; } - - size_t iterator_offset(Utf32CodePointIterator const& it) const; - - Utf32View substring_view(size_t offset, size_t length) const; - -private: - u32 const* begin_ptr() const; - u32 const* end_ptr() const; - - u32 const* m_code_points{ nullptr }; - size_t m_length{ 0 }; -}; - -} - -using AK::Utf32View; +/* + * Copyright (c) 2020, Andreas Kling + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include "Assertions.h" +#include "Checked.h" +#include "Types.h" + +namespace AK { + +class Utf32View; + +class Utf32CodePointIterator { + friend class Utf32View; + +public: + Utf32CodePointIterator() = default; + ~Utf32CodePointIterator() = default; + + bool operator==(Utf32CodePointIterator const& other) const; + bool operator!=(Utf32CodePointIterator const& other) const; + Utf32CodePointIterator& operator++(); + ssize_t operator-(Utf32CodePointIterator const& other) const; + u32 operator*() const; + + constexpr int code_point_length_in_bytes() const { return sizeof(u32); } + bool done() const { return !m_length; } + +private: + Utf32CodePointIterator(u32 const* ptr, size_t length) + : m_ptr(ptr) + , m_length((ssize_t)length) + { + } + u32 const* m_ptr{ nullptr }; + ssize_t m_length{ -1 }; +}; + +class Utf32View { +public: + using Iterator = Utf32CodePointIterator; + + Utf32View() = default; + Utf32View(u32 const* code_points, size_t length) + : m_code_points(code_points) + , m_length(length) + { + } + + Utf32CodePointIterator begin() const; + + Utf32CodePointIterator end() const; + + u32 at(size_t index) const; + + u32 operator[](size_t index) const { return at(index); } + + u32 const* code_points() const { return m_code_points; } + bool is_empty() const { return m_length == 0; } + bool is_null() const { return !m_code_points; } + size_t length() const { return m_length; } + + size_t iterator_offset(Utf32CodePointIterator const& it) const; + + Utf32View substring_view(size_t offset, size_t length) const; + +private: + u32 const* begin_ptr() const; + u32 const* end_ptr() const; + + u32 const* m_code_points{ nullptr }; + size_t m_length{ 0 }; +}; + +} + +using AK::Utf32View; diff --git a/AK/AK/Utf8View.cpp b/LibC-Shim/AK/Utf8View.cpp similarity index 95% rename from AK/AK/Utf8View.cpp rename to LibC-Shim/AK/Utf8View.cpp index dff2057..c77c780 100644 --- a/AK/AK/Utf8View.cpp +++ b/LibC-Shim/AK/Utf8View.cpp @@ -1,2 +1,2 @@ -#include "pch.h" -#include "Utf8View.h" +#include "pch.h" +#include "Utf8View.h" diff --git a/AK/AK/Utf8View.h b/LibC-Shim/AK/Utf8View.h similarity index 95% rename from AK/AK/Utf8View.h rename to LibC-Shim/AK/Utf8View.h index 07c5c51..3f82430 100644 --- a/AK/AK/Utf8View.h +++ b/LibC-Shim/AK/Utf8View.h @@ -1,134 +1,134 @@ -/* - * Copyright (c) 2019-2020, Sergey Bugaev - * Copyright (c) 2021, Max Wipfli - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include "./AK/String.h" -#include "./AK/StringView.h" -#include "./AK/Types.h" - -namespace AK { - -class Utf8View; - -class Utf8CodePointIterator { - friend class Utf8View; - -public: - Utf8CodePointIterator() = default; - ~Utf8CodePointIterator() = default; - - bool operator==(Utf8CodePointIterator const&) const = default; - bool operator!=(Utf8CodePointIterator const&) const = default; - Utf8CodePointIterator& operator++(); - u32 operator*() const; - // NOTE: This returns {} if the peek is at or past EOF. - Optional peek(size_t offset = 0) const; - - ssize_t operator-(Utf8CodePointIterator const& other) const - { - return m_ptr - other.m_ptr; - } - - // Note : These methods return the information about the underlying UTF-8 bytes. - // If the UTF-8 string encoding is not valid at the iterator's position, then the underlying bytes might be different from the - // decoded character's re-encoded bytes (which will be an `0xFFFD REPLACEMENT CHARACTER` with an UTF-8 length of three bytes). - // If your code relies on the decoded character being equivalent to the re-encoded character, use the `UTF8View::validate()` - // method on the view prior to using its iterator. - size_t underlying_code_point_length_in_bytes() const; - ReadonlyBytes underlying_code_point_bytes() const; - bool done() const { return m_length == 0; } - -private: - Utf8CodePointIterator(u8 const* ptr, size_t length) - : m_ptr(ptr) - , m_length(length) - { - } - - u8 const* m_ptr{ nullptr }; - size_t m_length{ 0 }; -}; - -class Utf8View { -public: - using Iterator = Utf8CodePointIterator; - - Utf8View() = default; - - explicit Utf8View(String& string) - : m_string(string.view()) - { - } - - explicit constexpr Utf8View(StringView string) - : m_string(string) - { - } - - ~Utf8View() = default; - - explicit Utf8View(String&&) = delete; - - StringView as_string() const { return m_string; } - - Utf8CodePointIterator begin() const { return { begin_ptr(), m_string.length() }; } - Utf8CodePointIterator end() const { return { end_ptr(), 0 }; } - Utf8CodePointIterator iterator_at_byte_offset(size_t) const; - - unsigned char const* bytes() const { return begin_ptr(); } - size_t byte_length() const { return m_string.length(); } - size_t byte_offset_of(Utf8CodePointIterator const&) const; - size_t byte_offset_of(size_t code_point_offset) const; - - Utf8View substring_view(size_t byte_offset, size_t byte_length) const { return Utf8View{ m_string.substring_view(byte_offset, byte_length) }; } - Utf8View substring_view(size_t byte_offset) const { return substring_view(byte_offset, byte_length() - byte_offset); } - Utf8View unicode_substring_view(size_t code_point_offset, size_t code_point_length) const; - Utf8View unicode_substring_view(size_t code_point_offset) const { return unicode_substring_view(code_point_offset, length() - code_point_offset); } - - bool is_empty() const { return m_string.is_empty(); } - bool is_null() const { return m_string.is_null(); } - bool starts_with(Utf8View const&) const; - bool contains(u32) const; - - Utf8View trim(Utf8View const& characters, TrimMode mode = TrimMode::Both) const; - - size_t iterator_offset(Utf8CodePointIterator const& it) const - { - return byte_offset_of(it); - } - - bool validate(size_t& valid_bytes) const; - bool validate() const - { - size_t valid_bytes; - return validate(valid_bytes); - } - - size_t length() const - { - if (!m_have_length) { - m_length = calculate_length(); - m_have_length = true; - } - return m_length; - } - -private: - u8 const* begin_ptr() const { return (u8 const*)m_string.characters_without_null_termination(); } - u8 const* end_ptr() const { return begin_ptr() + m_string.length(); } - size_t calculate_length() const; - - StringView m_string; - mutable size_t m_length{ 0 }; - mutable bool m_have_length{ false }; -}; - -} - -using AK::Utf8CodePointIterator; -using AK::Utf8View; +/* + * Copyright (c) 2019-2020, Sergey Bugaev + * Copyright (c) 2021, Max Wipfli + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include "String.h" +#include "StringView.h" +#include "Types.h" + +namespace AK { + +class Utf8View; + +class Utf8CodePointIterator { + friend class Utf8View; + +public: + Utf8CodePointIterator() = default; + ~Utf8CodePointIterator() = default; + + bool operator==(Utf8CodePointIterator const&) const = default; + bool operator!=(Utf8CodePointIterator const&) const = default; + Utf8CodePointIterator& operator++(); + u32 operator*() const; + // NOTE: This returns {} if the peek is at or past EOF. + Optional peek(size_t offset = 0) const; + + ssize_t operator-(Utf8CodePointIterator const& other) const + { + return m_ptr - other.m_ptr; + } + + // Note : These methods return the information about the underlying UTF-8 bytes. + // If the UTF-8 string encoding is not valid at the iterator's position, then the underlying bytes might be different from the + // decoded character's re-encoded bytes (which will be an `0xFFFD REPLACEMENT CHARACTER` with an UTF-8 length of three bytes). + // If your code relies on the decoded character being equivalent to the re-encoded character, use the `UTF8View::validate()` + // method on the view prior to using its iterator. + size_t underlying_code_point_length_in_bytes() const; + ReadonlyBytes underlying_code_point_bytes() const; + bool done() const { return m_length == 0; } + +private: + Utf8CodePointIterator(u8 const* ptr, size_t length) + : m_ptr(ptr) + , m_length(length) + { + } + + u8 const* m_ptr{ nullptr }; + size_t m_length{ 0 }; +}; + +class Utf8View { +public: + using Iterator = Utf8CodePointIterator; + + Utf8View() = default; + + explicit Utf8View(String& string) + : m_string(string.view()) + { + } + + explicit constexpr Utf8View(StringView string) + : m_string(string) + { + } + + ~Utf8View() = default; + + explicit Utf8View(String&&) = delete; + + StringView as_string() const { return m_string; } + + Utf8CodePointIterator begin() const { return { begin_ptr(), m_string.length() }; } + Utf8CodePointIterator end() const { return { end_ptr(), 0 }; } + Utf8CodePointIterator iterator_at_byte_offset(size_t) const; + + unsigned char const* bytes() const { return begin_ptr(); } + size_t byte_length() const { return m_string.length(); } + size_t byte_offset_of(Utf8CodePointIterator const&) const; + size_t byte_offset_of(size_t code_point_offset) const; + + Utf8View substring_view(size_t byte_offset, size_t byte_length) const { return Utf8View{ m_string.substring_view(byte_offset, byte_length) }; } + Utf8View substring_view(size_t byte_offset) const { return substring_view(byte_offset, byte_length() - byte_offset); } + Utf8View unicode_substring_view(size_t code_point_offset, size_t code_point_length) const; + Utf8View unicode_substring_view(size_t code_point_offset) const { return unicode_substring_view(code_point_offset, length() - code_point_offset); } + + bool is_empty() const { return m_string.is_empty(); } + bool is_null() const { return m_string.is_null(); } + bool starts_with(Utf8View const&) const; + bool contains(u32) const; + + Utf8View trim(Utf8View const& characters, TrimMode mode = TrimMode::Both) const; + + size_t iterator_offset(Utf8CodePointIterator const& it) const + { + return byte_offset_of(it); + } + + bool validate(size_t& valid_bytes) const; + bool validate() const + { + size_t valid_bytes; + return validate(valid_bytes); + } + + size_t length() const + { + if (!m_have_length) { + m_length = calculate_length(); + m_have_length = true; + } + return m_length; + } + +private: + u8 const* begin_ptr() const { return (u8 const*)m_string.characters_without_null_termination(); } + u8 const* end_ptr() const { return begin_ptr() + m_string.length(); } + size_t calculate_length() const; + + StringView m_string; + mutable size_t m_length{ 0 }; + mutable bool m_have_length{ false }; +}; + +} + +using AK::Utf8CodePointIterator; +using AK::Utf8View; diff --git a/AK/AK/Variant.h b/LibC-Shim/AK/Variant.h similarity index 93% rename from AK/AK/Variant.h rename to LibC-Shim/AK/Variant.h index 3b53727..67d1e10 100644 --- a/AK/AK/Variant.h +++ b/LibC-Shim/AK/Variant.h @@ -1,86 +1,86 @@ -#pragma once - -#include -#include "./AK/Forward.h" - -namespace AK { -using Empty = std::monostate; - -template -struct Variant : public std::variant { - Variant(); - - using std::variant::variant; - using std::variant::operator=; - - template - void set(T&& t) - { - *this = std::forward(t); - } - - template - T* get_pointer() - { - return std::get_if(this); - } - - template - T& get() - { - return std::get(*this); - } - - template - T* get_pointer() const - { - return const_cast(std::get_if(this)); - } - - template - T& get() const - { - return const_cast(std::get(*this)); - } - - template - bool has() const - { - return std::holds_alternative(*this); - } - - template - struct overloaded : Us... { using Us::operator()...; }; - - template - decltype(auto) visit(Fs&&... functions) const - { - return std::visit(overloaded{ std::forward(functions)... }, *this); - } - - template - decltype(auto) visit(Fs&&... functions) - { - return std::visit(overloaded{ std::forward(functions)... }, *this); - } - - template - Variant downcast()&&; - /* { - return std::visit([](auto& entry) -> Variant { - return Variant(std::move(entry)); - }, *this); - }*/ - - template - Variant downcast() const&; - /* { - return std::visit([](auto const& entry) -> Variant { - return entry; - }, *this); - }*/ -}; -} - -using AK::Empty; -using AK::Variant; \ No newline at end of file +#pragma once + +#include +#include "Forward.h" + +namespace AK { +using Empty = std::monostate; + +template +struct Variant : public std::variant { + Variant(); + + using std::variant::variant; + using std::variant::operator=; + + template + void set(T&& t) + { + *this = std::forward(t); + } + + template + T* get_pointer() + { + return std::get_if(this); + } + + template + T& get() + { + return std::get(*this); + } + + template + T* get_pointer() const + { + return const_cast(std::get_if(this)); + } + + template + T& get() const + { + return const_cast(std::get(*this)); + } + + template + bool has() const + { + return std::holds_alternative(*this); + } + + template + struct overloaded : Us... { using Us::operator()...; }; + + template + decltype(auto) visit(Fs&&... functions) const + { + return std::visit(overloaded{ std::forward(functions)... }, *this); + } + + template + decltype(auto) visit(Fs&&... functions) + { + return std::visit(overloaded{ std::forward(functions)... }, *this); + } + + template + Variant downcast()&&; + /* { + return std::visit([](auto& entry) -> Variant { + return Variant(std::move(entry)); + }, *this); + }*/ + + template + Variant downcast() const&; + /* { + return std::visit([](auto const& entry) -> Variant { + return entry; + }, *this); + }*/ +}; +} + +using AK::Empty; +using AK::Variant; diff --git a/LibC-Shim/AK/Vector.h b/LibC-Shim/AK/Vector.h new file mode 100644 index 0000000..d425994 --- /dev/null +++ b/LibC-Shim/AK/Vector.h @@ -0,0 +1,565 @@ +/* + * Copyright (c) 2018-2021, Andreas Kling + * Copyright (c) 2021, the SerenityOS developers. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include "Assertions.h" +#include "Error.h" +#include "Find.h" +#include "Forward.h" +#include "Iterator.h" +#include "Optional.h" +#include "ReverseIterator.h" +#include "Span.h" +#include "StdLibExtras.h" +#include "Traits.h" +#include "TypedTransfer.h" +#include "kmalloc.h" +#include + +namespace AK { + +namespace Detail { + +template +struct CanBePlacedInsideVectorHelper; + +template +struct CanBePlacedInsideVectorHelper { + template + static constexpr bool value = requires(U && u) { StorageType{ &u }; }; +}; + +template +struct CanBePlacedInsideVectorHelper { + template + static constexpr bool value = requires(U && u) { StorageType(forward(u)); }; +}; + +} + +template +requires(!IsRvalueReference) class Vector { + private: + static constexpr bool contains_reference = IsLvalueReference; + using StorageType = Conditional>, T>; + + using VisibleType = RemoveReference; + + template + static constexpr bool CanBePlacedInsideVector = Detail::CanBePlacedInsideVectorHelper::template value; + + public: + using ValueType = T; + Vector() + : m_capacity(inline_capacity) + { + } + + Vector(std::initializer_list list) requires(!IsLvalueReference); + + Vector(Vector&& other) + : m_size(other.m_size) + , m_capacity(other.m_capacity) + , m_outline_buffer(other.m_outline_buffer) + { + } + + Vector(Vector const& other); + + explicit Vector(Span other) requires(!IsLvalueReference); + + template + Vector(Vector const& other); + + ~Vector() + { + clear(); + } + + Span span() { return { data(), size() }; } + Span span() const { return { data(), size() }; } + + operator Span() { return span(); } + operator Span() const { return span(); } + + bool is_empty() const { return size() == 0; } + ALWAYS_INLINE size_t size() const { return m_size; } + size_t capacity() const { return m_capacity; } + + ALWAYS_INLINE StorageType* data() + { + if constexpr (inline_capacity > 0) + return m_outline_buffer ? m_outline_buffer : inline_buffer(); + return m_outline_buffer; + } + + ALWAYS_INLINE StorageType const* data() const + { + if constexpr (inline_capacity > 0) + return m_outline_buffer ? m_outline_buffer : inline_buffer(); + return m_outline_buffer; + } + + ALWAYS_INLINE VisibleType const& at(size_t i) const + { + VERIFY(i < m_size); + if constexpr (contains_reference) + return *data()[i]; + else + return data()[i]; + } + + ALWAYS_INLINE VisibleType& at(size_t i) + { + VERIFY(i < m_size); + if constexpr (contains_reference) + return *data()[i]; + else + return data()[i]; + } + + ALWAYS_INLINE VisibleType const& operator[](size_t i) const { return at(i); } + ALWAYS_INLINE VisibleType& operator[](size_t i) { return at(i); } + + VisibleType const& first() const { return at(0); } + VisibleType& first() { return at(0); } + + VisibleType const& last() const { return at(size() - 1); } + VisibleType& last() { return at(size() - 1); } + + template + Optional first_matching(TUnaryPredicate const& predicate) requires(!contains_reference); + + template + Optional first_matching(TUnaryPredicate const& predicate) const requires(!contains_reference); + + template + Optional last_matching(TUnaryPredicate const& predicate) requires(!contains_reference); + + template + bool operator==(V const& other) const + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return false; + } + + template + bool contains_slow(V const& value) const + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return false; + } + + bool contains_in_range(VisibleType const& value, size_t const start, size_t const end) const + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return false; + } + + template + void insert(size_t index, U&& value) requires(CanBePlacedInsideVector); + + template + void insert_before_matching(U&& value, TUnaryPredicate const& predicate, size_t first_index = 0, size_t* inserted_index = nullptr) requires(CanBePlacedInsideVector); + + void extend(Vector&& other) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + } + + void extend(Vector const& other) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + } + + ALWAYS_INLINE void append(T&& value) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + } + + ALWAYS_INLINE void append(T const& value) requires(!contains_reference) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + } + + void append(StorageType const* values, size_t count) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + } + + template + ALWAYS_INLINE void unchecked_append(U&& value) requires(CanBePlacedInsideVector) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + } + + ALWAYS_INLINE void unchecked_append(StorageType const* values, size_t count) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + } + + template + void empend(Args&&... args)/* requires(!contains_reference)*/ + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + } + + template + void prepend(U&& value)/* requires(CanBePlacedInsideVector)*/ + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + } + + void prepend(Vector&& other) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + } + + void prepend(StorageType const* values, size_t count) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + } + + Vector& operator=(Vector&& other) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return *this; + } + + Vector& operator=(Vector const& other) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return *this; + } + + template + Vector& operator=(Vector const& other) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return *this; + } + + void clear() + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + } + + void clear_with_capacity() + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + } + + void remove(size_t index) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + } + + void remove(size_t index, size_t count) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + } + + template + bool remove_first_matching(TUnaryPredicate const& predicate) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return false; + } + + template + bool remove_all_matching(TUnaryPredicate const& predicate) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return false; + } + + ALWAYS_INLINE T take_last(); + + T take_first() + { + VERIFY(!is_empty()); + auto value = move(raw_first()); + remove(0); + if constexpr (contains_reference) + return *value; + else + return value; + } + + T take(size_t index) + { + auto value = move(raw_at(index)); + remove(index); + if constexpr (contains_reference) + return *value; + else + return value; + } + + T unstable_take(size_t index) + { + VERIFY(index < m_size); + swap(raw_at(index), raw_at(m_size - 1)); + return take_last(); + } + + template + ErrorOr try_insert(size_t index, U&& value) requires(CanBePlacedInsideVector) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return {}; + } + + template + ErrorOr try_insert_before_matching(U&& value, TUnaryPredicate const& predicate, size_t first_index = 0, size_t* inserted_index = nullptr) requires(CanBePlacedInsideVector) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return {}; + } + + ErrorOr try_extend(Vector&& other) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return {}; + } + + ErrorOr try_extend(Vector const& other) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return {}; + } + + ErrorOr try_append(T&& value) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return {}; + } + + ErrorOr try_append(T const& value) requires(!contains_reference) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return {}; + } + + ErrorOr try_append(StorageType const* values, size_t count) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return {}; + } + + template + ErrorOr try_empend(Args&&... args) requires(!contains_reference) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return {}; + } + + template + ErrorOr try_prepend(U&& value) requires(CanBePlacedInsideVector) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return {}; + } + + ErrorOr try_prepend(Vector&& other) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return {}; + } + + ErrorOr try_prepend(StorageType const* values, size_t count) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return {}; + } + + ErrorOr try_grow_capacity(size_t needed_capacity) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return {}; + } + + ErrorOr try_ensure_capacity(size_t needed_capacity) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return {}; + } + + ErrorOr try_resize(size_t new_size, bool keep_capacity = false) requires(!contains_reference) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return {}; + } + + ErrorOr try_resize_and_keep_capacity(size_t new_size) requires(!contains_reference) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return {}; + } + + void grow_capacity(size_t needed_capacity) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + } + + void ensure_capacity(size_t needed_capacity) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + } + + void shrink(size_t new_size, bool keep_capacity = false) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + } + + void resize(size_t new_size, bool keep_capacity = false) requires(!contains_reference) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + } + + void resize_and_keep_capacity(size_t new_size) requires(!contains_reference) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + } + + using ConstIterator = SimpleIterator; + using Iterator = SimpleIterator; + using ReverseIterator = SimpleReverseIterator; + using ReverseConstIterator = SimpleReverseIterator; + + ConstIterator begin() const { return ConstIterator::begin(*this); } + Iterator begin() { return Iterator::begin(*this); } + ReverseIterator rbegin() { return ReverseIterator::rbegin(*this); } + ReverseConstIterator rbegin() const { return ReverseConstIterator::rbegin(*this); } + + ConstIterator end() const { return ConstIterator::end(*this); } + Iterator end() { return Iterator::end(*this); } + ReverseIterator rend() { return ReverseIterator::rend(*this); } + ReverseConstIterator rend() const { return ReverseConstIterator::rend(*this); } + + ALWAYS_INLINE constexpr auto in_reverse() + { + return ReverseWrapper::in_reverse(*this); + } + + template + ConstIterator find_if(TUnaryPredicate&& finder) const; + + template + Iterator find_if(TUnaryPredicate&& finder); + + ConstIterator find(VisibleType const& value) const; + + Iterator find(VisibleType const& value); + + Optional find_first_index(VisibleType const& value) const; + + void reverse(); + + private: + void reset_capacity() + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + } + + static size_t padded_capacity(size_t capacity) + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return capacity; + } + + StorageType* slot(size_t i) { return &data()[i]; } + StorageType const* slot(size_t i) const { return &data()[i]; } + + StorageType* inline_buffer() + { + static_assert(inline_capacity > 0); + return reinterpret_cast(m_inline_buffer_storage); + } + StorageType const* inline_buffer() const + { + static_assert(inline_capacity > 0); + return reinterpret_cast(m_inline_buffer_storage); + } + + StorageType& raw_last() { return raw_at(size() - 1); } + StorageType& raw_first() { return raw_at(0); } + StorageType& raw_at(size_t index) { return *slot(index); } + + size_t m_size{ 0 }; + size_t m_capacity{ 0 }; + + static constexpr size_t storage_size() + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return 1; + } + + static constexpr size_t storage_alignment() + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return 1; + } + + unsigned char m_inline_buffer_storage[storage_size()]; + StorageType* m_outline_buffer{ nullptr }; +}; + +template +Vector(Args... args)->Vector>; + +} + +using AK::Vector; diff --git a/AK/AK/WeakPtr.h b/LibC-Shim/AK/WeakPtr.h similarity index 93% rename from AK/AK/WeakPtr.h rename to LibC-Shim/AK/WeakPtr.h index a83b876..0275cfd 100644 --- a/AK/AK/WeakPtr.h +++ b/LibC-Shim/AK/WeakPtr.h @@ -1,134 +1,139 @@ -/* - * Copyright (c) 2018-2020, Andreas Kling - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include "./AK/Weakable.h" - -namespace AK { - -template -class WeakPtr { - template - friend class Weakable; - -public: - WeakPtr() = default; - - template - WeakPtr(WeakPtr const& other)/* requires(IsBaseOf)*/ - : m_link(other.m_link) - { - } - - template - WeakPtr(WeakPtr&& other)/* requires(IsBaseOf)*/ - : m_link(other.take_link()) - { - } - - template - WeakPtr& operator=(WeakPtr&& other)/* requires(IsBaseOf)*/ - { - m_link = other.take_link(); - return *this; - } - - template - WeakPtr& operator=(WeakPtr const& other)/* requires(IsBaseOf)*/; - - WeakPtr& operator=(std::nullptr_t); - - template - WeakPtr(const U& object)/* requires(IsBaseOf)*/ - { - } - - template - WeakPtr(const U* object)/* requires(IsBaseOf)*/; - - template - WeakPtr(RefPtr const& object)/* requires(IsBaseOf)*/; - - template - WeakPtr(NonnullRefPtr const& object)/* requires(IsBaseOf)*/; - template - WeakPtr& operator=(const U& object)/* requires(IsBaseOf)*/; - - template - WeakPtr& operator=(const U* object)/* requires(IsBaseOf)*/; - - template - WeakPtr& operator=(RefPtr const& object)/* requires(IsBaseOf)*/; - - template - WeakPtr& operator=(NonnullRefPtr const& object)/* requires(IsBaseOf)*/; - - RefPtr strong_ref() const - { - return RefPtr { ptr() }; - } - - T* ptr() const { return unsafe_ptr(); } - T* operator->() { return unsafe_ptr(); } - const T* operator->() const { return unsafe_ptr(); } - operator const T* () const { return unsafe_ptr(); } - operator T* () { return unsafe_ptr(); } - - T* unsafe_ptr() const; - - operator bool() const { return m_link ? !m_link->is_null() : false; } - - bool is_null() const { return !m_link || m_link->is_null(); } - void clear() { m_link = nullptr; } - - RefPtr take_link() { return move(m_link); } - -private: - WeakPtr(RefPtr const& link) - : m_link(link) - { - } - - RefPtr m_link; -}; - -template -template -ALWAYS_INLINE ErrorOr> Weakable::try_make_weak_ptr() const -{ - if (!m_link) - m_link = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) WeakLink(const_cast(static_cast(*this))))); - - return WeakPtr(m_link); -} - -template -struct Formatter> : Formatter { - ErrorOr format(FormatBuilder& builder, WeakPtr const& value) - { - return Formatter::format(builder, value.ptr()); - } -}; - -template -ErrorOr> try_make_weak_ptr_if_nonnull(T const* ptr) -{ - if (ptr) { - return ptr->template try_make_weak_ptr(); - } - return WeakPtr {}; -} - -template -WeakPtr make_weak_ptr_if_nonnull(T const* ptr) -{ - return MUST(try_make_weak_ptr_if_nonnull(ptr)); -} - -} - -using AK::WeakPtr; +/* + * Copyright (c) 2018-2020, Andreas Kling + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include "Weakable.h" + +namespace AK { + +template +class WeakPtr { + template + friend class Weakable; + +public: + WeakPtr() = default; + + template + WeakPtr(WeakPtr const& other)/* requires(IsBaseOf)*/ + : m_link(other.m_link) + { + } + + template + WeakPtr(WeakPtr&& other)/* requires(IsBaseOf)*/ + : m_link(other.take_link()) + { + } + + template + WeakPtr& operator=(WeakPtr&& other)/* requires(IsBaseOf)*/ + { + m_link = other.take_link(); + return *this; + } + + template + WeakPtr& operator=(WeakPtr const& other)/* requires(IsBaseOf)*/; + + WeakPtr& operator=(std::nullptr_t); + + template + WeakPtr(const U& object)/* requires(IsBaseOf)*/ + { + } + + template + WeakPtr(const U* object)/* requires(IsBaseOf)*/; + + template + WeakPtr(RefPtr const& object)/* requires(IsBaseOf)*/; + + template + WeakPtr(NonnullRefPtr const& object)/* requires(IsBaseOf)*/; + template + WeakPtr& operator=(const U& object)/* requires(IsBaseOf)*/; + + template + WeakPtr& operator=(const U* object)/* requires(IsBaseOf)*/; + + template + WeakPtr& operator=(RefPtr const& object)/* requires(IsBaseOf)*/; + + template + WeakPtr& operator=(NonnullRefPtr const& object)/* requires(IsBaseOf)*/; + + [[nodiscard]] RefPtr strong_ref() const + { + return RefPtr { ptr() }; + } + + T* ptr() const { return unsafe_ptr(); } + T* operator->() { return unsafe_ptr(); } + const T* operator->() const { return unsafe_ptr(); } + operator const T* () const { return unsafe_ptr(); } + operator T* () { return unsafe_ptr(); } + + [[nodiscard]] T* unsafe_ptr() const + { + // FIXME: Impl this. + VERIFY_NOT_REACHED(); + return nullptr; + } + + operator bool() const { return m_link ? !m_link->is_null() : false; } + + bool is_null() const { return !m_link || m_link->is_null(); } + void clear() { m_link = nullptr; } + + RefPtr take_link() { return move(m_link); } + +private: + WeakPtr(RefPtr const& link) + : m_link(link) + { + } + + RefPtr m_link; +}; + +template +template +ALWAYS_INLINE ErrorOr> Weakable::try_make_weak_ptr() const +{ + if (!m_link) + m_link = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) WeakLink(const_cast(static_cast(*this))))); + + return WeakPtr(m_link); +} + +template +struct Formatter> : Formatter { + ErrorOr format(FormatBuilder& builder, WeakPtr const& value) + { + return Formatter::format(builder, value.ptr()); + } +}; + +template +ErrorOr> try_make_weak_ptr_if_nonnull(T const* ptr) +{ + if (ptr) { + return ptr->template try_make_weak_ptr(); + } + return WeakPtr {}; +} + +template +WeakPtr make_weak_ptr_if_nonnull(T const* ptr) +{ + return MUST(try_make_weak_ptr_if_nonnull(ptr)); +} + +} + +using AK::WeakPtr; diff --git a/AK/AK/Weakable.h b/LibC-Shim/AK/Weakable.h similarity index 80% rename from AK/AK/Weakable.h rename to LibC-Shim/AK/Weakable.h index 5bfb70a..60a9b19 100644 --- a/AK/AK/Weakable.h +++ b/LibC-Shim/AK/Weakable.h @@ -1,56 +1,56 @@ -/* - * Copyright (c) 2018-2022, Andreas Kling - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include "./AK/Assertions.h" -#include "./AK/Atomic.h" -#include "./AK/RefCounted.h" -#include "./AK/RefPtr.h" -#include "./AK/StdLibExtras.h" - -namespace AK { - -template -class Weakable; -template -class WeakPtr; - -class WeakLink : public RefCounted { - template - friend class Weakable; - template - friend class WeakPtr; - -private: - template - explicit WeakLink(T&) - { - } -}; - -template -class Weakable { -private: - class Link; - -public: - template - WeakPtr make_weak_ptr() const; - - template - ErrorOr> try_make_weak_ptr() const; - -protected: - Weakable() = default; - -private: - mutable RefPtr m_link; -}; - -} - -using AK::Weakable; +/* + * Copyright (c) 2018-2022, Andreas Kling + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include "Assertions.h" +#include "Atomic.h" +#include "RefCounted.h" +#include "RefPtr.h" +#include "StdLibExtras.h" + +namespace AK { + +template +class Weakable; +template +class WeakPtr; + +class WeakLink : public RefCounted { + template + friend class Weakable; + template + friend class WeakPtr; + +private: + template + explicit WeakLink(T&) + { + } +}; + +template +class Weakable { +private: + class Link; + +public: + template + WeakPtr make_weak_ptr() const; + + template + ErrorOr> try_make_weak_ptr() const; + +protected: + Weakable() = default; + +private: + mutable RefPtr m_link; +}; + +} + +using AK::Weakable; diff --git a/LibC-Shim/AK/kmalloc.cpp b/LibC-Shim/AK/kmalloc.cpp new file mode 100644 index 0000000..de0d201 --- /dev/null +++ b/LibC-Shim/AK/kmalloc.cpp @@ -0,0 +1,2 @@ +#include "pch.h" +#include "kmalloc.h" diff --git a/LibC-Shim/AK/kmalloc.h b/LibC-Shim/AK/kmalloc.h new file mode 100644 index 0000000..d358c40 --- /dev/null +++ b/LibC-Shim/AK/kmalloc.h @@ -0,0 +1,9 @@ +#pragma once + +#include +#include +#include +#include "Checked.h" +#include "Types.h" + +using std::nothrow; diff --git a/AK/Kernel/API/KeyCode.h b/LibC-Shim/Kernel/API/KeyCode.h similarity index 100% rename from AK/Kernel/API/KeyCode.h rename to LibC-Shim/Kernel/API/KeyCode.h diff --git a/AK/AK.vcxproj b/LibC-Shim/LibC-Shim.vcxproj similarity index 83% rename from AK/AK.vcxproj rename to LibC-Shim/LibC-Shim.vcxproj index 7f650a0..ea85090 100644 --- a/AK/AK.vcxproj +++ b/LibC-Shim/LibC-Shim.vcxproj @@ -1,352 +1,336 @@ - - - - - Debug - ARM - - - Debug - x86 - - - Debug - x64 - - - Release - ARM - - - Release - x86 - - - Release - x64 - - - - {4482715a-767d-4a17-a64d-4d990654de2e} - StaticLibrary - AK - en-US - 14.0 - true - Windows Store - 10.0.16299.0 - 10.0.10586.0 - 10.0 - LibC-Shim - - - - StaticLibrary - true - v143 - - - StaticLibrary - true - v143 - - - StaticLibrary - true - v143 - - - StaticLibrary - false - true - v143 - - - StaticLibrary - false - true - v143 - - - StaticLibrary - false - true - v143 - - - - - - - - - - - - - - - - - - - - - - - - - - - - false - - - false - - - false - - - false - - - false - $(WindowsSDK_IncludePath); - $(VC_IncludePath);$(WindowsSDK_IncludePath); - - - false - - - - Use - false - true - stdcpplatest - - - Console - false - false - - - - - Use - false - true - - - Console - false - false - - - - - Use - false - true - stdcpplatest - - - Console - false - false - - - - - Use - false - true - - - Console - false - false - - - - - Use - false - true - $(ProjectDir)/../x64/Debug/AK.pch - true - stdcpplatest - Default - false - false - $(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) - _UNICODE;UNICODE;%(PreprocessorDefinitions);NOMINMAX;_CRT_SECURE_NO_WARNINGS - - - Console - false - false - - - - - Use - false - true - _UNICODE;UNICODE;%(PreprocessorDefinitions);NOMINMAX - - - Console - false - false - - - - - stdcpplatest - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create - Create - Create - Create - Create - Create - Create - Create - - - - - - - - + + + + + Debug + ARM + + + Debug + Win32 + + + Debug + x64 + + + Release + ARM + + + Release + Win32 + + + Release + x64 + + + + {274e4ccd-578f-4645-a3a5-9773423d2ca1} + StaticLibrary + LibC_Shim + en-US + 14.0 + true + Windows Store + 10.0.16299.0 + 10.0.10586.0 + 10.0 + + + + DynamicLibrary + true + v143 + + + DynamicLibrary + true + v143 + + + DynamicLibrary + true + v143 + + + StaticLibrary + false + true + v143 + + + StaticLibrary + false + true + v143 + + + StaticLibrary + false + true + v143 + + + + + + + + + + + + + + + + + + + + + + + + + + + + false + + + false + + + false + + + false + + + false + + + false + + + + Use + false + true + stdcpplatest + + + Console + false + false + /FORCE %(AdditionalOptions) + + + %(AdditionalDependencies) + + + + + Use + false + true + + + Console + false + false + + + + + Use + false + true + stdcpplatest + + + Console + false + false + /FORCE %(AdditionalOptions) + + + %(AdditionalDependencies) + + + + + Use + false + true + + + Console + false + false + + + + + Use + false + true + stdcpplatest + + + Console + false + false + /FORCE %(AdditionalOptions) + + + %(AdditionalDependencies) + + + + + Use + false + true + + + Console + false + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Create + Create + Create + Create + Create + Create + Create + Create + + + + + \ No newline at end of file diff --git a/AK/AK.vcxproj.filters b/LibC-Shim/LibC-Shim.vcxproj.filters similarity index 76% rename from AK/AK.vcxproj.filters rename to LibC-Shim/LibC-Shim.vcxproj.filters index 981c4c7..6aa148b 100644 --- a/AK/AK.vcxproj.filters +++ b/LibC-Shim/LibC-Shim.vcxproj.filters @@ -1,413 +1,351 @@ - - - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tga;tiff;tif;png;wav;mfcribbon-ms - - - {4e54793f-9733-4382-993c-968282743c26} - - - {3f7b064d-8eb8-43b1-abd4-c2537ff2000c} - - - {1eb34466-6832-4d41-a2ca-f8b1bd31250d} - - - {f50d2597-c69c-488a-9fd1-1f63bb8fee6b} - - - {68022297-8568-4b21-9b2c-8df0b49cbc63} - - - {3132eeae-b399-4a8a-87cb-ded2bc670f8b} - - - {8ff33975-9894-4f2a-8540-9cdf8e725c6c} - - - {f91a0b3f-ca1f-49c4-b691-570d3ae06bfd} - - - {cd4eeceb-b757-404e-a1ae-9f1d427dd1b5} - - - {911cc48e-1112-4899-9901-8967e09e918e} - - - {df074b9e-1e73-460b-8f5d-8038160860ec} - - - - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - - - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - sys - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - LibCrypto\BigInt - - - LibCrypto\BigInt - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - AK - - - sys - - - AK - - - AK - - - AK - - - AK - - - AK - - - - AK - - - LibThreading - - - LibCore - - - AK - - - LibCore - - - LibUnicode - - - LibCore - - - AK - - - Kernel\API - - - Services\WindowServer - - - - - + + + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tga;tiff;tif;png;wav;mfcribbon-ms + + + {658754e4-a270-47a1-87d0-5d1d749efc57} + + + + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + + + + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + AK + + + \ No newline at end of file diff --git a/LibC-Shim/LibC.cpp b/LibC-Shim/LibC.cpp new file mode 100644 index 0000000..c8b454b --- /dev/null +++ b/LibC-Shim/LibC.cpp @@ -0,0 +1,2 @@ +#include "pch.h" +#include "LibC.h" diff --git a/LibC-Shim/LibC.h b/LibC-Shim/LibC.h new file mode 100644 index 0000000..9a0e83e --- /dev/null +++ b/LibC-Shim/LibC.h @@ -0,0 +1,2 @@ +#pragma once +#include "AK/Forward.h" diff --git a/AK/LibCore/ConfigFile.h b/LibC-Shim/LibCore/ConfigFile.h similarity index 100% rename from AK/LibCore/ConfigFile.h rename to LibC-Shim/LibCore/ConfigFile.h diff --git a/AK/LibCore/File.h b/LibC-Shim/LibCore/File.h similarity index 100% rename from AK/LibCore/File.h rename to LibC-Shim/LibCore/File.h diff --git a/AK/LibCore/SocketAddress.h b/LibC-Shim/LibCore/SocketAddress.h similarity index 100% rename from AK/LibCore/SocketAddress.h rename to LibC-Shim/LibCore/SocketAddress.h diff --git a/AK/LibCrypto/BigInt/SignedBigInteger.h b/LibC-Shim/LibCrypto/BigInt/SignedBigInteger.h similarity index 96% rename from AK/LibCrypto/BigInt/SignedBigInteger.h rename to LibC-Shim/LibCrypto/BigInt/SignedBigInteger.h index 5143931..a766965 100644 --- a/AK/LibCrypto/BigInt/SignedBigInteger.h +++ b/LibC-Shim/LibCrypto/BigInt/SignedBigInteger.h @@ -1,127 +1,127 @@ -/* - * Copyright (c) 2020, the SerenityOS developers. - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include "./AK/Span.h" -#include "./LibCrypto/BigInt/UnsignedBigInteger.h" - -namespace Crypto { - -struct SignedDivisionResult; - -class SignedBigInteger { -public: - SignedBigInteger(i32 x) - : m_sign(x < 0) - , m_unsigned_data(abs(x)) - { - } - - SignedBigInteger(UnsignedBigInteger&& unsigned_data, bool sign) - : m_sign(sign) - , m_unsigned_data(move(unsigned_data)) - { - ensure_sign_is_valid(); - } - - explicit SignedBigInteger(UnsignedBigInteger unsigned_data) - : m_sign(false) - , m_unsigned_data(move(unsigned_data)) - { - } - - SignedBigInteger() - : m_sign(false) - , m_unsigned_data() - { - } - - static SignedBigInteger create_invalid(); - - static SignedBigInteger import_data(StringView data); - static SignedBigInteger import_data(u8 const* ptr, size_t length); - - static SignedBigInteger create_from(i64 value); - - size_t export_data(Bytes, bool remove_leading_zeros = false) const;; - - static SignedBigInteger from_base(u16 N, StringView str); - String to_base(u16 N) const; - - u64 to_u64() const; - double to_double() const; - - UnsignedBigInteger const& unsigned_value() const; - Vector const words() const; - bool is_negative() const; - bool is_zero() const; - - void negate(); - - void set_to_0(); - - void set_to(i32 other); - void set_to(SignedBigInteger const& other); - - void invalidate(); - - bool is_invalid() const; - - size_t length() const; - size_t trimmed_length(); - - SignedBigInteger plus(SignedBigInteger const& other) const; - SignedBigInteger minus(SignedBigInteger const& other) const; - SignedBigInteger bitwise_or(SignedBigInteger const& other) const; - SignedBigInteger bitwise_and(SignedBigInteger const& other) const; - SignedBigInteger bitwise_xor(SignedBigInteger const& other) const; - SignedBigInteger bitwise_not() const; - SignedBigInteger shift_left(size_t num_bits) const; - SignedBigInteger multiplied_by(SignedBigInteger const& other) const; - SignedDivisionResult divided_by(SignedBigInteger const& divisor) const; - - SignedBigInteger plus(UnsignedBigInteger const& other) const; - SignedBigInteger minus(UnsignedBigInteger const& other) const; - SignedBigInteger multiplied_by(UnsignedBigInteger const& other) const; - SignedDivisionResult divided_by(UnsignedBigInteger const& divisor) const; - - u32 hash() const; - - void set_bit_inplace(size_t bit_index); - - bool operator==(SignedBigInteger const& other) const; - bool operator!=(SignedBigInteger const& other) const; - bool operator<(SignedBigInteger const& other) const; - bool operator<=(SignedBigInteger const& other) const; - bool operator>(SignedBigInteger const& other) const; - bool operator>=(SignedBigInteger const& other) const; - - bool operator==(UnsignedBigInteger const& other) const; - bool operator!=(UnsignedBigInteger const& other) const; - bool operator<(UnsignedBigInteger const& other) const; - bool operator>(UnsignedBigInteger const& other) const; - -private: - void ensure_sign_is_valid(); - - bool m_sign{ false }; - UnsignedBigInteger m_unsigned_data; -}; - -struct SignedDivisionResult { - Crypto::SignedBigInteger quotient; - Crypto::SignedBigInteger remainder; -}; - -} - -template<> -struct AK::Formatter : AK::Formatter { - ErrorOr format(FormatBuilder&, Crypto::SignedBigInteger const&); -}; - -inline Crypto::SignedBigInteger operator""_sbigint(char const* string, size_t length); +/* + * Copyright (c) 2020, the SerenityOS developers. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include "./AK/Span.h" +#include "./LibCrypto/BigInt/UnsignedBigInteger.h" + +namespace Crypto { + +struct SignedDivisionResult; + +class SignedBigInteger { +public: + SignedBigInteger(i32 x) + : m_sign(x < 0) + , m_unsigned_data(abs(x)) + { + } + + SignedBigInteger(UnsignedBigInteger&& unsigned_data, bool sign) + : m_sign(sign) + , m_unsigned_data(move(unsigned_data)) + { + ensure_sign_is_valid(); + } + + explicit SignedBigInteger(UnsignedBigInteger unsigned_data) + : m_sign(false) + , m_unsigned_data(move(unsigned_data)) + { + } + + SignedBigInteger() + : m_sign(false) + , m_unsigned_data() + { + } + + static SignedBigInteger create_invalid(); + + static SignedBigInteger import_data(StringView data); + static SignedBigInteger import_data(u8 const* ptr, size_t length); + + static SignedBigInteger create_from(i64 value); + + size_t export_data(Bytes, bool remove_leading_zeros = false) const;; + + static SignedBigInteger from_base(u16 N, StringView str); + String to_base(u16 N) const; + + u64 to_u64() const; + double to_double() const; + + UnsignedBigInteger const& unsigned_value() const; + Vector const words() const; + bool is_negative() const; + bool is_zero() const; + + void negate(); + + void set_to_0(); + + void set_to(i32 other); + void set_to(SignedBigInteger const& other); + + void invalidate(); + + bool is_invalid() const; + + size_t length() const; + size_t trimmed_length(); + + SignedBigInteger plus(SignedBigInteger const& other) const; + SignedBigInteger minus(SignedBigInteger const& other) const; + SignedBigInteger bitwise_or(SignedBigInteger const& other) const; + SignedBigInteger bitwise_and(SignedBigInteger const& other) const; + SignedBigInteger bitwise_xor(SignedBigInteger const& other) const; + SignedBigInteger bitwise_not() const; + SignedBigInteger shift_left(size_t num_bits) const; + SignedBigInteger multiplied_by(SignedBigInteger const& other) const; + SignedDivisionResult divided_by(SignedBigInteger const& divisor) const; + + SignedBigInteger plus(UnsignedBigInteger const& other) const; + SignedBigInteger minus(UnsignedBigInteger const& other) const; + SignedBigInteger multiplied_by(UnsignedBigInteger const& other) const; + SignedDivisionResult divided_by(UnsignedBigInteger const& divisor) const; + + u32 hash() const; + + void set_bit_inplace(size_t bit_index); + + bool operator==(SignedBigInteger const& other) const; + bool operator!=(SignedBigInteger const& other) const; + bool operator<(SignedBigInteger const& other) const; + bool operator<=(SignedBigInteger const& other) const; + bool operator>(SignedBigInteger const& other) const; + bool operator>=(SignedBigInteger const& other) const; + + bool operator==(UnsignedBigInteger const& other) const; + bool operator!=(UnsignedBigInteger const& other) const; + bool operator<(UnsignedBigInteger const& other) const; + bool operator>(UnsignedBigInteger const& other) const; + +private: + void ensure_sign_is_valid(); + + bool m_sign{ false }; + UnsignedBigInteger m_unsigned_data; +}; + +struct SignedDivisionResult { + Crypto::SignedBigInteger quotient; + Crypto::SignedBigInteger remainder; +}; + +} + +template<> +struct AK::Formatter : AK::Formatter { + ErrorOr format(FormatBuilder&, Crypto::SignedBigInteger const&); +}; + +inline Crypto::SignedBigInteger operator""_sbigint(char const* string, size_t length); diff --git a/AK/LibCrypto/BigInt/UnsignedBigInteger.h b/LibC-Shim/LibCrypto/BigInt/UnsignedBigInteger.h similarity index 96% rename from AK/LibCrypto/BigInt/UnsignedBigInteger.h rename to LibC-Shim/LibCrypto/BigInt/UnsignedBigInteger.h index 32f9747..b7efccb 100644 --- a/AK/LibCrypto/BigInt/UnsignedBigInteger.h +++ b/LibC-Shim/LibCrypto/BigInt/UnsignedBigInteger.h @@ -1,108 +1,108 @@ -/* - * Copyright (c) 2020, Itamar S. - * Copyright (c) 2022, the SerenityOS developers. - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include "./AK/ByteBuffer.h" -#include "./AK/Span.h" -#include "./AK/String.h" -#include "./AK/Types.h" -#include "./AK/Vector.h" - -namespace Crypto { - -struct UnsignedDivisionResult; -constexpr size_t STARTING_WORD_SIZE = 32; - -class UnsignedBigInteger { -public: - using Word = u32; - static constexpr size_t BITS_IN_WORD = 32; - - UnsignedBigInteger(Word x) { m_words.append(x); } - - explicit UnsignedBigInteger(Vector&& words) - : m_words(move(words)) - { - } - - explicit UnsignedBigInteger(u8 const* ptr, size_t length); - - UnsignedBigInteger() = default; - - static UnsignedBigInteger create_invalid(); - - static UnsignedBigInteger import_data(StringView data); - static UnsignedBigInteger import_data(u8 const* ptr, size_t length); - - static UnsignedBigInteger create_from(u64 value); - - size_t export_data(Bytes, bool remove_leading_zeros = false) const; - - static UnsignedBigInteger from_base(u16 N, StringView str); - String to_base(u16 N) const; - - u64 to_u64() const; - double to_double() const; - - Vector const& words(); - - void set_to_0(); - void set_to(Word other); - void set_to(UnsignedBigInteger const& other); - - UnsignedBigInteger plus(UnsignedBigInteger const& other) const; - UnsignedBigInteger minus(UnsignedBigInteger const& other) const; - UnsignedBigInteger bitwise_or(UnsignedBigInteger const& other) const; - UnsignedBigInteger bitwise_and(UnsignedBigInteger const& other) const; - UnsignedBigInteger bitwise_xor(UnsignedBigInteger const& other) const; - UnsignedBigInteger bitwise_not_fill_to_one_based_index(size_t) const; - UnsignedBigInteger shift_left(size_t num_bits) const; - UnsignedBigInteger multiplied_by(UnsignedBigInteger const& other) const; - UnsignedDivisionResult divided_by(UnsignedBigInteger const& divisor) const; - - u32 hash() const; - - void set_bit_inplace(size_t bit_index); - - bool operator==(UnsignedBigInteger const& other) const; - bool operator!=(UnsignedBigInteger const& other) const; - bool operator<(UnsignedBigInteger const& other) const; - bool operator>(UnsignedBigInteger const& other) const; - bool operator>=(UnsignedBigInteger const& other) const; - -private: - friend class UnsignedBigIntegerAlgorithms; - // Little endian - // m_word[0] + m_word[1] * Word::MAX + m_word[2] * Word::MAX * Word::MAX + ... - Vector m_words; - - mutable u32 m_cached_hash{ 0 }; - - // Used to indicate a negative result, or a result of an invalid operation - bool m_is_invalid{ false }; - - mutable Optional m_cached_trimmed_length; -}; - -struct UnsignedDivisionResult { - Crypto::UnsignedBigInteger quotient; - Crypto::UnsignedBigInteger remainder; -}; - -} - -template<> -struct AK::Formatter : Formatter { - ErrorOr format(FormatBuilder&, Crypto::UnsignedBigInteger const&); -}; - -inline Crypto::UnsignedBigInteger -operator""_bigint(char const* string, size_t length) -{ - return Crypto::UnsignedBigInteger::from_base(10, { string, length }); -} +/* + * Copyright (c) 2020, Itamar S. + * Copyright (c) 2022, the SerenityOS developers. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include "./AK/ByteBuffer.h" +#include "./AK/Span.h" +#include "./AK/String.h" +#include "./AK/Types.h" +#include "./AK/Vector.h" + +namespace Crypto { + +struct UnsignedDivisionResult; +constexpr size_t STARTING_WORD_SIZE = 32; + +class UnsignedBigInteger { +public: + using Word = u32; + static constexpr size_t BITS_IN_WORD = 32; + + UnsignedBigInteger(Word x) { m_words.append(x); } + + explicit UnsignedBigInteger(Vector&& words) + : m_words(move(words)) + { + } + + explicit UnsignedBigInteger(u8 const* ptr, size_t length); + + UnsignedBigInteger() = default; + + static UnsignedBigInteger create_invalid(); + + static UnsignedBigInteger import_data(StringView data); + static UnsignedBigInteger import_data(u8 const* ptr, size_t length); + + static UnsignedBigInteger create_from(u64 value); + + size_t export_data(Bytes, bool remove_leading_zeros = false) const; + + static UnsignedBigInteger from_base(u16 N, StringView str); + String to_base(u16 N) const; + + u64 to_u64() const; + double to_double() const; + + Vector const& words(); + + void set_to_0(); + void set_to(Word other); + void set_to(UnsignedBigInteger const& other); + + UnsignedBigInteger plus(UnsignedBigInteger const& other) const; + UnsignedBigInteger minus(UnsignedBigInteger const& other) const; + UnsignedBigInteger bitwise_or(UnsignedBigInteger const& other) const; + UnsignedBigInteger bitwise_and(UnsignedBigInteger const& other) const; + UnsignedBigInteger bitwise_xor(UnsignedBigInteger const& other) const; + UnsignedBigInteger bitwise_not_fill_to_one_based_index(size_t) const; + UnsignedBigInteger shift_left(size_t num_bits) const; + UnsignedBigInteger multiplied_by(UnsignedBigInteger const& other) const; + UnsignedDivisionResult divided_by(UnsignedBigInteger const& divisor) const; + + u32 hash() const; + + void set_bit_inplace(size_t bit_index); + + bool operator==(UnsignedBigInteger const& other) const; + bool operator!=(UnsignedBigInteger const& other) const; + bool operator<(UnsignedBigInteger const& other) const; + bool operator>(UnsignedBigInteger const& other) const; + bool operator>=(UnsignedBigInteger const& other) const; + +private: + friend class UnsignedBigIntegerAlgorithms; + // Little endian + // m_word[0] + m_word[1] * Word::MAX + m_word[2] * Word::MAX * Word::MAX + ... + Vector m_words; + + mutable u32 m_cached_hash{ 0 }; + + // Used to indicate a negative result, or a result of an invalid operation + bool m_is_invalid{ false }; + + mutable Optional m_cached_trimmed_length; +}; + +struct UnsignedDivisionResult { + Crypto::UnsignedBigInteger quotient; + Crypto::UnsignedBigInteger remainder; +}; + +} + +template<> +struct AK::Formatter : Formatter { + ErrorOr format(FormatBuilder&, Crypto::UnsignedBigInteger const&); +}; + +inline Crypto::UnsignedBigInteger +operator""_bigint(char const* string, size_t length) +{ + return Crypto::UnsignedBigInteger::from_base(10, { string, length }); +} diff --git a/AK/LibThreading/Mutex.h b/LibC-Shim/LibThreading/Mutex.h similarity index 100% rename from AK/LibThreading/Mutex.h rename to LibC-Shim/LibThreading/Mutex.h diff --git a/AK/LibUnicode/PluralRules.h b/LibC-Shim/LibUnicode/PluralRules.h similarity index 100% rename from AK/LibUnicode/PluralRules.h rename to LibC-Shim/LibUnicode/PluralRules.h diff --git a/AK/Services/WindowServer/WindowType.h b/LibC-Shim/Services/WindowServer/WindowType.h similarity index 100% rename from AK/Services/WindowServer/WindowType.h rename to LibC-Shim/Services/WindowServer/WindowType.h diff --git a/LibC-Shim/pch.cpp b/LibC-Shim/pch.cpp new file mode 100644 index 0000000..bcb5590 --- /dev/null +++ b/LibC-Shim/pch.cpp @@ -0,0 +1 @@ +#include "pch.h" diff --git a/AK/pch.h b/LibC-Shim/pch.h similarity index 93% rename from AK/pch.h rename to LibC-Shim/pch.h index dcdc970..529bbb1 100644 --- a/AK/pch.h +++ b/LibC-Shim/pch.h @@ -1,9 +1,9 @@ -#pragma once - -#include "targetver.h" - -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN -#endif - -#include +#pragma once + +#include "targetver.h" + +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif + +#include diff --git a/AK/AK/FixedPoint.h b/LibC-Shim/pthread.h similarity index 92% rename from AK/AK/FixedPoint.h rename to LibC-Shim/pthread.h index 50e9667..6f70f09 100644 --- a/AK/AK/FixedPoint.h +++ b/LibC-Shim/pthread.h @@ -1 +1 @@ -#pragma once +#pragma once diff --git a/AK/sys/mman.h b/LibC-Shim/sys/mman.h similarity index 94% rename from AK/sys/mman.h rename to LibC-Shim/sys/mman.h index 150fef7..d7294cb 100644 --- a/AK/sys/mman.h +++ b/LibC-Shim/sys/mman.h @@ -1,8 +1,8 @@ -#pragma once - -#include -#include -#include -#include - +#pragma once + +#include +#include +#include +#include + #define aligned_alloc _aligned_malloc; \ No newline at end of file diff --git a/AK/sys/time.h b/LibC-Shim/sys/time.h similarity index 94% rename from AK/sys/time.h rename to LibC-Shim/sys/time.h index 87829db..09621ee 100644 --- a/AK/sys/time.h +++ b/LibC-Shim/sys/time.h @@ -1,13 +1,13 @@ -#pragma once - -#include - -struct timeval -{ - __time64_t tv_sec; /* Seconds. */ - long tv_usec; /* Microseconds. */ -}; - -int gettimeofday(struct timeval* tv, struct timezone* tz) { - return 0; +#pragma once + +#include + +struct timeval +{ + __time64_t tv_sec; /* Seconds. */ + long tv_usec; /* Microseconds. */ +}; + +int gettimeofday(struct timeval* tv, struct timezone* tz) { + return 0; } \ No newline at end of file diff --git a/AK/targetver.h b/LibC-Shim/targetver.h similarity index 97% rename from AK/targetver.h rename to LibC-Shim/targetver.h index eddeeea..a66ecb0 100644 --- a/AK/targetver.h +++ b/LibC-Shim/targetver.h @@ -1,8 +1,8 @@ -#pragma once - -// Including SDKDDKVer.h defines the highest available Windows platform. - -// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and -// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. - -#include +#pragma once + +// Including SDKDDKVer.h defines the highest available Windows platform. + +// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and +// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. + +#include diff --git a/LibJS/LibJS.h b/LibJS/LibJS.h new file mode 100644 index 0000000..6f70f09 --- /dev/null +++ b/LibJS/LibJS.h @@ -0,0 +1 @@ +#pragma once diff --git a/LibJS/LibJS.vcxproj b/LibJS/LibJS.vcxproj index 629e9be..853c734 100644 --- a/LibJS/LibJS.vcxproj +++ b/LibJS/LibJS.vcxproj @@ -5,9 +5,13 @@ Debug ARM - + Debug - x86 + ARM64 + + + Debug + Win32 Debug @@ -17,9 +21,13 @@ Release ARM - + + Release + ARM64 + + Release - x86 + Win32 Release @@ -27,8 +35,8 @@ - {124fa43a-a3ce-4a53-b440-01b704bbe0f3} - StaticLibrary + {429e1151-2338-4d6d-b154-c3c8195158a9} + DynamicLibrary LibJS en-US 14.0 @@ -38,39 +46,47 @@ 10.0.10586.0 10.0 - - true - - - StaticLibrary + + DynamicLibrary true v143 - StaticLibrary + DynamicLibrary + true + v143 + + + DynamicLibrary true v143 - StaticLibrary + DynamicLibrary true v143 - - StaticLibrary + + DynamicLibrary false true v143 - StaticLibrary + DynamicLibrary + false + true + v143 + + + DynamicLibrary false true v143 - StaticLibrary + DynamicLibrary false true v143 @@ -80,10 +96,10 @@ - + - + @@ -92,6 +108,12 @@ + + + + + + @@ -100,42 +122,59 @@ - + false + false - + false + false false + false false + false + + + false + false + + + false + false false + false false + false - + Use false - true - pch.h;%(ForcedIncludeFiles) + $(ProjectDir)/../LibC-Shim/;$(ProjectDir)/../serenity/Userland/Libraries/;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + stdcpplatest + pch.h; Console false false + /FORCE %(AdditionalOptions) + ..\LibC-Shim\$(IntDir) + LibC-Shim.lib;$(CoreLibraryDependencies);%(AdditionalDependencies) - + Use false - true Console @@ -147,26 +186,23 @@ Use false - true - pch.h;%(ForcedIncludeFiles) + $(ProjectDir)/../LibC-Shim/;$(ProjectDir)/../serenity/Userland/Libraries/;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + stdcpplatest + pch.h; Console false false + /FORCE %(AdditionalOptions) + ..\LibC-Shim\$(IntDir) + LibC-Shim.lib;$(CoreLibraryDependencies);%(AdditionalDependencies) - - powershell.exe -ExecutionPolicy Bypass -NoProfile -NonInteractive -File PreBuild.ps1 - - - powershell.exe -ExecutionPolicy Bypass -NoProfile -NonInteractive -File PostBuild.ps1 - Use false - true Console @@ -174,33 +210,27 @@ false - + Use false - true - pch.h;%(ForcedIncludeFiles) - true - $(ProjectDir)/../AK/;$(ProjectDir)/../serenity/Userland/Libraries/;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + $(ProjectDir)/../LibC-Shim/;$(ProjectDir)/../serenity/Userland/Libraries/;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) stdcpplatest + pch.h; Console false false + /FORCE %(AdditionalOptions) + ..\LibC-Shim\$(IntDir) + LibC-Shim.lib;$(CoreLibraryDependencies);%(AdditionalDependencies) - - powershell.exe -ExecutionPolicy Bypass -NoProfile -NonInteractive -File PreBuild.ps1 - - - powershell.exe -ExecutionPolicy Bypass -NoProfile -NonInteractive -File PostBuild.ps1 - - + Use false - true Console @@ -208,37 +238,36 @@ false - - - powershell.exe -ExecutionPolicy Bypass -NoProfile -NonInteractive -File PreBuild.ps1 - - - - - powershell.exe -ExecutionPolicy Bypass -NoProfile -NonInteractive -File PreBuild.ps1 - - - - - powershell.exe -ExecutionPolicy Bypass -NoProfile -NonInteractive -File PreBuild.ps1 - - - - - powershell.exe -ExecutionPolicy Bypass -NoProfile -NonInteractive -File PreBuild.ps1 - - - - - powershell.exe -ExecutionPolicy Bypass -NoProfile -NonInteractive -File PreBuild.ps1 - + + + Use + false + $(ProjectDir)/../LibC-Shim/;$(ProjectDir)/../serenity/Userland/Libraries/;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + stdcpplatest + pch.h; + + + Console + false + false + /FORCE %(AdditionalOptions) + ..\LibC-Shim\$(IntDir) + LibC-Shim.lib;$(CoreLibraryDependencies);%(AdditionalDependencies) + - - - powershell.exe -ExecutionPolicy Bypass -NoProfile -NonInteractive -File PostBuild.ps1 - + + + Use + false + + + Console + false + false + + @@ -252,9 +281,10 @@ true + - Create - Create + Create + Create Create Create Create @@ -264,11 +294,15 @@ - - {4482715a-767d-4a17-a64d-4d990654de2e} + + {274e4ccd-578f-4645-a3a5-9773423d2ca1} - + + + + + \ No newline at end of file diff --git a/LibJS/LibJS.vcxproj.filters b/LibJS/LibJS.vcxproj.filters new file mode 100644 index 0000000..7be79fa --- /dev/null +++ b/LibJS/LibJS.vcxproj.filters @@ -0,0 +1,18759 @@ + + + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tga;tiff;tif;png;wav;mfcribbon-ms + + + {57d5508a-9804-4dc1-931d-9b43bd960d37} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + LibJS + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/LibJS/PostBuild.ps1 b/LibJS/PostBuild.ps1 deleted file mode 100644 index 4a371cc..0000000 --- a/LibJS/PostBuild.ps1 +++ /dev/null @@ -1,5 +0,0 @@ -$curDir = Get-Location - -Set-Location .\..\serenity -git reset --hard -Set-Location $curDir diff --git a/LibJS/dllmain.cpp b/LibJS/dllmain.cpp new file mode 100644 index 0000000..fa2d748 --- /dev/null +++ b/LibJS/dllmain.cpp @@ -0,0 +1,14 @@ +#include "pch.h" + +BOOL APIENTRY DllMain(HMODULE /* hModule */, DWORD ul_reason_for_call, LPVOID /* lpReserved */) +{ + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + } + return TRUE; +} diff --git a/LibWeb-WinRT.sln b/LibWeb-WinRT.sln index a8c5055..b65d6fd 100644 --- a/LibWeb-WinRT.sln +++ b/LibWeb-WinRT.sln @@ -3,50 +3,88 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.2.32630.192 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LibC-Shim", "AK\AK.vcxproj", "{4482715A-767D-4A17-A64D-4D990654DE2E}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LibJS", "LibJS\LibJS.vcxproj", "{124FA43A-A3CE-4A53-B440-01B704BBE0F3}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{9905EAAA-C7F9-4653-8F28-9E8B8CA3FDC4}" ProjectSection(SolutionItems) = preProject .github\workflows\build.yml = .github\workflows\build.yml README.md = README.md EndProjectSection EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{550DFE6B-0FAC-4C3E-A12C-47DFCFC78172}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LibC-Shim", "LibC-Shim\LibC-Shim.vcxproj", "{274E4CCD-578F-4645-A3A5-9773423D2CA1}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LibJS", "LibJS\LibJS.vcxproj", "{429E1151-2338-4D6D-B154-C3C8195158A9}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestApp", "TestApp\TestApp.vcxproj", "{D79FA7F2-A558-4B09-9023-4EFEA919A6F5}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|ARM = Debug|ARM + Debug|ARM64 = Debug|ARM64 Debug|x64 = Debug|x64 Debug|x86 = Debug|x86 Release|ARM = Release|ARM + Release|ARM64 = Release|ARM64 Release|x64 = Release|x64 Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {4482715A-767D-4A17-A64D-4D990654DE2E}.Debug|ARM.ActiveCfg = Debug|ARM - {4482715A-767D-4A17-A64D-4D990654DE2E}.Debug|ARM.Build.0 = Debug|ARM - {4482715A-767D-4A17-A64D-4D990654DE2E}.Debug|x64.ActiveCfg = Debug|x64 - {4482715A-767D-4A17-A64D-4D990654DE2E}.Debug|x64.Build.0 = Debug|x64 - {4482715A-767D-4A17-A64D-4D990654DE2E}.Debug|x86.ActiveCfg = Debug|x86 - {4482715A-767D-4A17-A64D-4D990654DE2E}.Debug|x86.Build.0 = Debug|x86 - {4482715A-767D-4A17-A64D-4D990654DE2E}.Release|ARM.ActiveCfg = Release|ARM - {4482715A-767D-4A17-A64D-4D990654DE2E}.Release|ARM.Build.0 = Release|ARM - {4482715A-767D-4A17-A64D-4D990654DE2E}.Release|x64.ActiveCfg = Release|x64 - {4482715A-767D-4A17-A64D-4D990654DE2E}.Release|x64.Build.0 = Release|x64 - {4482715A-767D-4A17-A64D-4D990654DE2E}.Release|x86.ActiveCfg = Release|x86 - {4482715A-767D-4A17-A64D-4D990654DE2E}.Release|x86.Build.0 = Release|x86 - {124FA43A-A3CE-4A53-B440-01B704BBE0F3}.Debug|ARM.ActiveCfg = Debug|ARM - {124FA43A-A3CE-4A53-B440-01B704BBE0F3}.Debug|ARM.Build.0 = Debug|ARM - {124FA43A-A3CE-4A53-B440-01B704BBE0F3}.Debug|x64.ActiveCfg = Debug|x64 - {124FA43A-A3CE-4A53-B440-01B704BBE0F3}.Debug|x64.Build.0 = Debug|x64 - {124FA43A-A3CE-4A53-B440-01B704BBE0F3}.Debug|x86.ActiveCfg = Debug|x86 - {124FA43A-A3CE-4A53-B440-01B704BBE0F3}.Debug|x86.Build.0 = Debug|x86 - {124FA43A-A3CE-4A53-B440-01B704BBE0F3}.Release|ARM.ActiveCfg = Release|ARM - {124FA43A-A3CE-4A53-B440-01B704BBE0F3}.Release|ARM.Build.0 = Release|ARM - {124FA43A-A3CE-4A53-B440-01B704BBE0F3}.Release|x64.ActiveCfg = Release|x64 - {124FA43A-A3CE-4A53-B440-01B704BBE0F3}.Release|x64.Build.0 = Release|x64 - {124FA43A-A3CE-4A53-B440-01B704BBE0F3}.Release|x86.ActiveCfg = Release|x86 - {124FA43A-A3CE-4A53-B440-01B704BBE0F3}.Release|x86.Build.0 = Release|x86 + {274E4CCD-578F-4645-A3A5-9773423D2CA1}.Debug|ARM.ActiveCfg = Debug|ARM + {274E4CCD-578F-4645-A3A5-9773423D2CA1}.Debug|ARM.Build.0 = Debug|ARM + {274E4CCD-578F-4645-A3A5-9773423D2CA1}.Debug|ARM64.ActiveCfg = Debug|x64 + {274E4CCD-578F-4645-A3A5-9773423D2CA1}.Debug|ARM64.Build.0 = Debug|x64 + {274E4CCD-578F-4645-A3A5-9773423D2CA1}.Debug|x64.ActiveCfg = Debug|x64 + {274E4CCD-578F-4645-A3A5-9773423D2CA1}.Debug|x64.Build.0 = Debug|x64 + {274E4CCD-578F-4645-A3A5-9773423D2CA1}.Debug|x86.ActiveCfg = Debug|Win32 + {274E4CCD-578F-4645-A3A5-9773423D2CA1}.Debug|x86.Build.0 = Debug|Win32 + {274E4CCD-578F-4645-A3A5-9773423D2CA1}.Release|ARM.ActiveCfg = Release|ARM + {274E4CCD-578F-4645-A3A5-9773423D2CA1}.Release|ARM.Build.0 = Release|ARM + {274E4CCD-578F-4645-A3A5-9773423D2CA1}.Release|ARM64.ActiveCfg = Release|x64 + {274E4CCD-578F-4645-A3A5-9773423D2CA1}.Release|ARM64.Build.0 = Release|x64 + {274E4CCD-578F-4645-A3A5-9773423D2CA1}.Release|x64.ActiveCfg = Release|x64 + {274E4CCD-578F-4645-A3A5-9773423D2CA1}.Release|x64.Build.0 = Release|x64 + {274E4CCD-578F-4645-A3A5-9773423D2CA1}.Release|x86.ActiveCfg = Release|Win32 + {274E4CCD-578F-4645-A3A5-9773423D2CA1}.Release|x86.Build.0 = Release|Win32 + {429E1151-2338-4D6D-B154-C3C8195158A9}.Debug|ARM.ActiveCfg = Debug|ARM + {429E1151-2338-4D6D-B154-C3C8195158A9}.Debug|ARM.Build.0 = Debug|ARM + {429E1151-2338-4D6D-B154-C3C8195158A9}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {429E1151-2338-4D6D-B154-C3C8195158A9}.Debug|ARM64.Build.0 = Debug|ARM64 + {429E1151-2338-4D6D-B154-C3C8195158A9}.Debug|x64.ActiveCfg = Debug|x64 + {429E1151-2338-4D6D-B154-C3C8195158A9}.Debug|x64.Build.0 = Debug|x64 + {429E1151-2338-4D6D-B154-C3C8195158A9}.Debug|x86.ActiveCfg = Debug|Win32 + {429E1151-2338-4D6D-B154-C3C8195158A9}.Debug|x86.Build.0 = Debug|Win32 + {429E1151-2338-4D6D-B154-C3C8195158A9}.Release|ARM.ActiveCfg = Release|ARM + {429E1151-2338-4D6D-B154-C3C8195158A9}.Release|ARM.Build.0 = Release|ARM + {429E1151-2338-4D6D-B154-C3C8195158A9}.Release|ARM64.ActiveCfg = Release|ARM64 + {429E1151-2338-4D6D-B154-C3C8195158A9}.Release|ARM64.Build.0 = Release|ARM64 + {429E1151-2338-4D6D-B154-C3C8195158A9}.Release|x64.ActiveCfg = Release|x64 + {429E1151-2338-4D6D-B154-C3C8195158A9}.Release|x64.Build.0 = Release|x64 + {429E1151-2338-4D6D-B154-C3C8195158A9}.Release|x86.ActiveCfg = Release|Win32 + {429E1151-2338-4D6D-B154-C3C8195158A9}.Release|x86.Build.0 = Release|Win32 + {D79FA7F2-A558-4B09-9023-4EFEA919A6F5}.Debug|ARM.ActiveCfg = Debug|ARM + {D79FA7F2-A558-4B09-9023-4EFEA919A6F5}.Debug|ARM.Build.0 = Debug|ARM + {D79FA7F2-A558-4B09-9023-4EFEA919A6F5}.Debug|ARM.Deploy.0 = Debug|ARM + {D79FA7F2-A558-4B09-9023-4EFEA919A6F5}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {D79FA7F2-A558-4B09-9023-4EFEA919A6F5}.Debug|ARM64.Build.0 = Debug|ARM64 + {D79FA7F2-A558-4B09-9023-4EFEA919A6F5}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {D79FA7F2-A558-4B09-9023-4EFEA919A6F5}.Debug|x64.ActiveCfg = Debug|x64 + {D79FA7F2-A558-4B09-9023-4EFEA919A6F5}.Debug|x64.Build.0 = Debug|x64 + {D79FA7F2-A558-4B09-9023-4EFEA919A6F5}.Debug|x64.Deploy.0 = Debug|x64 + {D79FA7F2-A558-4B09-9023-4EFEA919A6F5}.Debug|x86.ActiveCfg = Debug|Win32 + {D79FA7F2-A558-4B09-9023-4EFEA919A6F5}.Debug|x86.Build.0 = Debug|Win32 + {D79FA7F2-A558-4B09-9023-4EFEA919A6F5}.Debug|x86.Deploy.0 = Debug|Win32 + {D79FA7F2-A558-4B09-9023-4EFEA919A6F5}.Release|ARM.ActiveCfg = Release|ARM + {D79FA7F2-A558-4B09-9023-4EFEA919A6F5}.Release|ARM.Build.0 = Release|ARM + {D79FA7F2-A558-4B09-9023-4EFEA919A6F5}.Release|ARM.Deploy.0 = Release|ARM + {D79FA7F2-A558-4B09-9023-4EFEA919A6F5}.Release|ARM64.ActiveCfg = Release|ARM64 + {D79FA7F2-A558-4B09-9023-4EFEA919A6F5}.Release|ARM64.Build.0 = Release|ARM64 + {D79FA7F2-A558-4B09-9023-4EFEA919A6F5}.Release|ARM64.Deploy.0 = Release|ARM64 + {D79FA7F2-A558-4B09-9023-4EFEA919A6F5}.Release|x64.ActiveCfg = Release|x64 + {D79FA7F2-A558-4B09-9023-4EFEA919A6F5}.Release|x64.Build.0 = Release|x64 + {D79FA7F2-A558-4B09-9023-4EFEA919A6F5}.Release|x64.Deploy.0 = Release|x64 + {D79FA7F2-A558-4B09-9023-4EFEA919A6F5}.Release|x86.ActiveCfg = Release|Win32 + {D79FA7F2-A558-4B09-9023-4EFEA919A6F5}.Release|x86.Build.0 = Release|Win32 + {D79FA7F2-A558-4B09-9023-4EFEA919A6F5}.Release|x86.Deploy.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/TestApp/App.xaml b/TestApp/App.xaml new file mode 100644 index 0000000..eac7b26 --- /dev/null +++ b/TestApp/App.xaml @@ -0,0 +1,7 @@ + + + diff --git a/TestApp/App.xaml.cpp b/TestApp/App.xaml.cpp new file mode 100644 index 0000000..1035e88 --- /dev/null +++ b/TestApp/App.xaml.cpp @@ -0,0 +1,116 @@ +// +// App.xaml.cpp +// Implementation of the App class. +// + +#include "pch.h" +#include "MainPage.xaml.h" + +using namespace TestApp; + +using namespace Platform; +using namespace Windows::ApplicationModel; +using namespace Windows::ApplicationModel::Activation; +using namespace Windows::Foundation; +using namespace Windows::Foundation::Collections; +using namespace Windows::UI::Xaml; +using namespace Windows::UI::Xaml::Controls; +using namespace Windows::UI::Xaml::Controls::Primitives; +using namespace Windows::UI::Xaml::Data; +using namespace Windows::UI::Xaml::Input; +using namespace Windows::UI::Xaml::Interop; +using namespace Windows::UI::Xaml::Media; +using namespace Windows::UI::Xaml::Navigation; + +///

+/// Initializes the singleton application object. This is the first line of authored code +/// executed, and as such is the logical equivalent of main() or WinMain(). +/// +App::App() +{ + InitializeComponent(); + Suspending += ref new SuspendingEventHandler(this, &App::OnSuspending); +} + +/// +/// Invoked when the application is launched normally by the end user. Other entry points +/// will be used such as when the application is launched to open a specific file. +/// +/// Details about the launch request and process. +void App::OnLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEventArgs^ e) +{ + auto rootFrame = dynamic_cast(Window::Current->Content); + + // Do not repeat app initialization when the Window already has content, + // just ensure that the window is active + if (rootFrame == nullptr) + { + // Create a Frame to act as the navigation context and associate it with + // a SuspensionManager key + rootFrame = ref new Frame(); + + rootFrame->NavigationFailed += ref new Windows::UI::Xaml::Navigation::NavigationFailedEventHandler(this, &App::OnNavigationFailed); + + if (e->PreviousExecutionState == ApplicationExecutionState::Terminated) + { + // TODO: Restore the saved session state only when appropriate, scheduling the + // final launch steps after the restore is complete + + } + + if (e->PrelaunchActivated == false) + { + if (rootFrame->Content == nullptr) + { + // When the navigation stack isn't restored navigate to the first page, + // configuring the new page by passing required information as a navigation + // parameter + rootFrame->Navigate(TypeName(MainPage::typeid), e->Arguments); + } + // Place the frame in the current Window + Window::Current->Content = rootFrame; + // Ensure the current window is active + Window::Current->Activate(); + } + } + else + { + if (e->PrelaunchActivated == false) + { + if (rootFrame->Content == nullptr) + { + // When the navigation stack isn't restored navigate to the first page, + // configuring the new page by passing required information as a navigation + // parameter + rootFrame->Navigate(TypeName(MainPage::typeid), e->Arguments); + } + // Ensure the current window is active + Window::Current->Activate(); + } + } +} + +/// +/// Invoked when application execution is being suspended. Application state is saved +/// without knowing whether the application will be terminated or resumed with the contents +/// of memory still intact. +/// +/// The source of the suspend request. +/// Details about the suspend request. +void App::OnSuspending(Object^ sender, SuspendingEventArgs^ e) +{ + (void) sender; // Unused parameter + (void) e; // Unused parameter + + //TODO: Save application state and stop any background activity +} + +/// +/// Invoked when Navigation to a certain page fails +/// +/// The Frame which failed navigation +/// Details about the navigation failure +void App::OnNavigationFailed(Platform::Object ^sender, Windows::UI::Xaml::Navigation::NavigationFailedEventArgs ^e) +{ + throw ref new FailureException("Failed to load Page " + e->SourcePageType.Name); +} \ No newline at end of file diff --git a/TestApp/App.xaml.h b/TestApp/App.xaml.h new file mode 100644 index 0000000..75f74fd --- /dev/null +++ b/TestApp/App.xaml.h @@ -0,0 +1,27 @@ +// +// App.xaml.h +// Declaration of the App class. +// + +#pragma once + +#include "App.g.h" + +namespace TestApp +{ + /// + /// Provides application-specific behavior to supplement the default Application class. + /// + ref class App sealed + { + protected: + virtual void OnLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEventArgs^ e) override; + + internal: + App(); + + private: + void OnSuspending(Platform::Object^ sender, Windows::ApplicationModel::SuspendingEventArgs^ e); + void OnNavigationFailed(Platform::Object ^sender, Windows::UI::Xaml::Navigation::NavigationFailedEventArgs ^e); + }; +} diff --git a/TestApp/Assets/LockScreenLogo.scale-200.png b/TestApp/Assets/LockScreenLogo.scale-200.png new file mode 100644 index 0000000..735f57a Binary files /dev/null and b/TestApp/Assets/LockScreenLogo.scale-200.png differ diff --git a/TestApp/Assets/SplashScreen.scale-200.png b/TestApp/Assets/SplashScreen.scale-200.png new file mode 100644 index 0000000..023e7f1 Binary files /dev/null and b/TestApp/Assets/SplashScreen.scale-200.png differ diff --git a/TestApp/Assets/Square150x150Logo.scale-200.png b/TestApp/Assets/Square150x150Logo.scale-200.png new file mode 100644 index 0000000..af49fec Binary files /dev/null and b/TestApp/Assets/Square150x150Logo.scale-200.png differ diff --git a/TestApp/Assets/Square44x44Logo.scale-200.png b/TestApp/Assets/Square44x44Logo.scale-200.png new file mode 100644 index 0000000..ce342a2 Binary files /dev/null and b/TestApp/Assets/Square44x44Logo.scale-200.png differ diff --git a/TestApp/Assets/Square44x44Logo.targetsize-24_altform-unplated.png b/TestApp/Assets/Square44x44Logo.targetsize-24_altform-unplated.png new file mode 100644 index 0000000..f6c02ce Binary files /dev/null and b/TestApp/Assets/Square44x44Logo.targetsize-24_altform-unplated.png differ diff --git a/TestApp/Assets/StoreLogo.png b/TestApp/Assets/StoreLogo.png new file mode 100644 index 0000000..7385b56 Binary files /dev/null and b/TestApp/Assets/StoreLogo.png differ diff --git a/TestApp/Assets/Wide310x150Logo.scale-200.png b/TestApp/Assets/Wide310x150Logo.scale-200.png new file mode 100644 index 0000000..288995b Binary files /dev/null and b/TestApp/Assets/Wide310x150Logo.scale-200.png differ diff --git a/TestApp/MainPage.xaml b/TestApp/MainPage.xaml new file mode 100644 index 0000000..20ec237 --- /dev/null +++ b/TestApp/MainPage.xaml @@ -0,0 +1,14 @@ + + + + + + diff --git a/TestApp/MainPage.xaml.cpp b/TestApp/MainPage.xaml.cpp new file mode 100644 index 0000000..6dc89b9 --- /dev/null +++ b/TestApp/MainPage.xaml.cpp @@ -0,0 +1,30 @@ +// +// MainPage.xaml.cpp +// Implementation of the MainPage class. +// + +#include "pch.h" +#include "MainPage.xaml.h" +//#include + +using namespace TestApp; + +using namespace Platform; +using namespace Windows::Foundation; +using namespace Windows::Foundation::Collections; +using namespace Windows::UI::Xaml; +using namespace Windows::UI::Xaml::Controls; +using namespace Windows::UI::Xaml::Controls::Primitives; +using namespace Windows::UI::Xaml::Data; +using namespace Windows::UI::Xaml::Input; +using namespace Windows::UI::Xaml::Media; +using namespace Windows::UI::Xaml::Navigation; + +// The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409 + +MainPage::MainPage() +{ + InitializeComponent(); + + //auto str = AK::String(); +} diff --git a/TestApp/MainPage.xaml.h b/TestApp/MainPage.xaml.h new file mode 100644 index 0000000..096a59d --- /dev/null +++ b/TestApp/MainPage.xaml.h @@ -0,0 +1,21 @@ +// +// MainPage.xaml.h +// Declaration of the MainPage class. +// + +#pragma once + +#include "MainPage.g.h" + +namespace TestApp +{ + /// + /// An empty page that can be used on its own or navigated to within a Frame. + /// + public ref class MainPage sealed + { + public: + MainPage(); + + }; +} diff --git a/TestApp/Package.appxmanifest b/TestApp/Package.appxmanifest new file mode 100644 index 0000000..c7996b6 --- /dev/null +++ b/TestApp/Package.appxmanifest @@ -0,0 +1,49 @@ + + + + + + + + + + TestApp + filfa + Assets\StoreLogo.png + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/TestApp/TestApp.vcxproj b/TestApp/TestApp.vcxproj new file mode 100644 index 0000000..e47430b --- /dev/null +++ b/TestApp/TestApp.vcxproj @@ -0,0 +1,239 @@ + + + + {d79fa7f2-a558-4b09-9023-4efea919a6f5} + TestApp + en-US + 14.0 + true + Windows Store + 10.0.16299.0 + 10.0.10586.0 + 10.0 + false + + + + + Debug + ARM + + + Debug + ARM64 + + + Debug + Win32 + + + Debug + x64 + + + Release + ARM + + + Release + ARM64 + + + Release + Win32 + + + Release + x64 + + + + Application + true + v143 + + + Application + true + v143 + + + Application + true + v143 + + + Application + true + v143 + true + + + Application + false + true + v143 + true + + + Application + false + true + v143 + true + + + Application + false + true + v143 + true + + + Application + false + true + v143 + true + + + + + + + + + + + + + + + + + + + + + + + + + + /bigobj %(AdditionalOptions) + 4453;28204 + C:\Users\filfa\libweb-winrt\LibC-Shim\;%(AdditionalIncludeDirectories) + stdcpp20 + + + + + /bigobj %(AdditionalOptions) + 4453;28204 + + + + + /bigobj %(AdditionalOptions) + 4453;28204 + C:\Users\filfa\libweb-winrt\LibC-Shim\;%(AdditionalIncludeDirectories) + stdcpp20 + + + + + /bigobj %(AdditionalOptions) + 4453;28204 + + + + + /bigobj %(AdditionalOptions) + 4453;28204 + C:\Users\filfa\libweb-winrt\LibC-Shim\;%(AdditionalIncludeDirectories) + stdcpp20 + + + + + /bigobj %(AdditionalOptions) + 4453;28204 + + + + + /bigobj %(AdditionalOptions) + 4453;28204 + C:\Users\filfa\libweb-winrt\LibC-Shim\;%(AdditionalIncludeDirectories) + stdcpp20 + + + + + /bigobj %(AdditionalOptions) + 4453;28204 + + + + + + App.xaml + + + MainPage.xaml + + + + + Designer + + + Designer + + + + + Designer + + + + + + + + + + + + + + App.xaml + + + MainPage.xaml + + + Create + Create + Create + Create + Create + Create + Create + Create + + + + + {274e4ccd-578f-4645-a3a5-9773423d2ca1} + + + + + true + + + + + + \ No newline at end of file diff --git a/TestApp/TestApp.vcxproj.filters b/TestApp/TestApp.vcxproj.filters new file mode 100644 index 0000000..0407cfc --- /dev/null +++ b/TestApp/TestApp.vcxproj.filters @@ -0,0 +1,53 @@ + + + + + d79fa7f2-a558-4b09-9023-4efea919a6f5 + + + e78937ba-8016-44c4-8234-02ae23be5426 + bmp;fbx;gif;jpg;jpeg;tga;tiff;tif;png + + + + + + + + + + + + + + Assets + + + Assets + + + Assets + + + Assets + + + Assets + + + Assets + + + Assets + + + + + + + + + + + + \ No newline at end of file diff --git a/TestApp/pch.cpp b/TestApp/pch.cpp new file mode 100644 index 0000000..ea14621 --- /dev/null +++ b/TestApp/pch.cpp @@ -0,0 +1,5 @@ +// +// pch.cpp +// + +#include "pch.h" diff --git a/TestApp/pch.h b/TestApp/pch.h new file mode 100644 index 0000000..ce9b681 --- /dev/null +++ b/TestApp/pch.h @@ -0,0 +1,10 @@ +// +// pch.h +// + +#pragma once + +#include +#include + +#include "App.xaml.h"