diff options
Diffstat (limited to 'AK')
-rw-r--r-- | AK/Buffer.h | 3 | ||||
-rw-r--r-- | AK/DoublyLinkedList.h | 4 | ||||
-rw-r--r-- | AK/Function.h | 111 | ||||
-rw-r--r-- | AK/HashMap.h | 13 | ||||
-rw-r--r-- | AK/HashTable.h | 44 | ||||
-rw-r--r-- | AK/StdLib.h | 86 | ||||
-rw-r--r-- | AK/String.cpp | 2 | ||||
-rw-r--r-- | AK/String.h | 10 | ||||
-rw-r--r-- | AK/StringImpl.cpp | 9 | ||||
-rw-r--r-- | AK/Traits.h | 8 | ||||
-rw-r--r-- | AK/Vector.h | 1 | ||||
-rw-r--r-- | AK/kmalloc.cpp | 2 | ||||
-rw-r--r-- | AK/kmalloc.h | 9 | ||||
-rw-r--r-- | AK/ktime.h | 15 |
14 files changed, 264 insertions, 53 deletions
diff --git a/AK/Buffer.h b/AK/Buffer.h index 91ef48cda2..efed0313b4 100644 --- a/AK/Buffer.h +++ b/AK/Buffer.h @@ -3,8 +3,7 @@ #include "Assertions.h" #include "Retainable.h" #include "RetainPtr.h" -#include <cstdlib> -#include <cstring> +#include "StdLib.h" #include "kmalloc.h" namespace AK { diff --git a/AK/DoublyLinkedList.h b/AK/DoublyLinkedList.h index fe65bb6264..a5a72562d6 100644 --- a/AK/DoublyLinkedList.h +++ b/AK/DoublyLinkedList.h @@ -1,6 +1,6 @@ #pragma once -#include <utility> +#include "StdLib.h" namespace AK { @@ -38,7 +38,7 @@ public: void append(T&& value) { - auto* node = new Node(std::move(value)); + auto* node = new Node(move(value)); if (!m_head) { ASSERT(!m_tail); m_head = node; diff --git a/AK/Function.h b/AK/Function.h new file mode 100644 index 0000000000..0fef35abe8 --- /dev/null +++ b/AK/Function.h @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2016 Apple Inc. 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 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 "OwnPtr.h" +#include "StdLib.h" + +namespace AK { + +template<typename> class Function; + +template <typename Out, typename... In> +class Function<Out(In...)> { +public: + Function() = default; + Function(std::nullptr_t) { } + + template<typename CallableType, class = typename EnableIf<!(IsPointer<CallableType>::value && IsFunction<typename RemovePointer<CallableType>::Type>::value) && IsRvalueReference<CallableType&&>::value>::Type> + Function(CallableType&& callable) + : m_callableWrapper(make<CallableWrapper<CallableType>>(move(callable))) + { + } + + template<typename FunctionType, class = typename EnableIf<IsPointer<FunctionType>::value && IsFunction<typename RemovePointer<FunctionType>::Type>::value>::Type> + Function(FunctionType f) + : m_callableWrapper(make<CallableWrapper<FunctionType>>(move(f))) + { + } + + Out operator()(In... in) + { + ASSERT(m_callableWrapper); + return m_callableWrapper->call(forward<In>(in)...); + } + + explicit operator bool() const { return !!m_callableWrapper; } + + template<typename CallableType, class = typename EnableIf<!(IsPointer<CallableType>::value && IsFunction<typename RemovePointer<CallableType>::Type>::value) && IsRvalueReference<CallableType&&>::value>::Type> + Function& operator=(CallableType&& callable) + { + m_callableWrapper = make<CallableWrapper<CallableType>>(move(callable)); + return *this; + } + + template<typename FunctionType, class = typename EnableIf<IsPointer<FunctionType>::value && IsFunction<typename RemovePointer<FunctionType>::Type>::value>::Type> + Function& operator=(FunctionType f) + { + m_callableWrapper = make<CallableWrapper<FunctionType>>(move(f)); + return *this; + } + + Function& operator=(std::nullptr_t) + { + m_callableWrapper = nullptr; + return *this; + } + +private: + class CallableWrapperBase { + public: + virtual ~CallableWrapperBase() { } + virtual Out call(In...) = 0; + }; + + template<typename CallableType> + class CallableWrapper : public CallableWrapperBase { + public: + explicit CallableWrapper(CallableType&& callable) + : m_callable(move(callable)) + { + } + + CallableWrapper(const CallableWrapper&) = delete; + CallableWrapper& operator=(const CallableWrapper&) = delete; + + Out call(In... in) final { return m_callable(forward<In>(in)...); } + + private: + CallableType m_callable; + }; + + OwnPtr<CallableWrapperBase> m_callableWrapper; +}; + +} + +using AK::Function; + diff --git a/AK/HashMap.h b/AK/HashMap.h index 751f2dbb1a..70f4259e05 100644 --- a/AK/HashMap.h +++ b/AK/HashMap.h @@ -1,7 +1,8 @@ #pragma once #include "HashTable.h" -#include <utility> +#include "StdLib.h" +#include "kstdio.h" namespace AK { @@ -22,9 +23,9 @@ private: static unsigned hash(const Entry& entry) { return Traits<K>::hash(entry.key); } static void dump(const Entry& entry) { - printf("key="); + kprintf("key="); Traits<K>::dump(entry.key); - printf(" value="); + kprintf(" value="); Traits<V>::dump(entry.value); } }; @@ -33,14 +34,14 @@ public: HashMap() { } HashMap(HashMap&& other) - : m_table(std::move(other.m_table)) + : m_table(move(other.m_table)) { } HashMap& operator=(HashMap&& other) { if (this != &other) { - m_table = std::move(other.m_table); + m_table = move(other.m_table); } return *this; } @@ -73,7 +74,7 @@ private: template<typename K, typename V> void HashMap<K, V>::set(const K& key, V&& value) { - m_table.set(Entry{key, std::move(value)}); + m_table.set(Entry{key, move(value)}); } template<typename K, typename V> diff --git a/AK/HashTable.h b/AK/HashTable.h index e42c3c4dbe..807b1e845b 100644 --- a/AK/HashTable.h +++ b/AK/HashTable.h @@ -3,8 +3,8 @@ #include "Assertions.h" #include "DoublyLinkedList.h" #include "Traits.h" -#include <cstdlib> -#include <utility> +#include "StdLib.h" +#include "kstdio.h" //#define HASHTABLE_DEBUG @@ -68,7 +68,7 @@ public: T& operator*() { #ifdef HASHTABLE_DEBUG - printf("retrieve { bucketIndex: %u, isEnd: %u }\n", m_bucketIndex, m_isEnd); + kprintf("retrieve { bucketIndex: %u, isEnd: %u }\n", m_bucketIndex, m_isEnd); #endif return *m_bucketIterator; } @@ -86,7 +86,7 @@ public: while (!m_isEnd) { #ifdef HASHTABLE_DEBUG ++pass; - printf("skipToNext pass %u, m_bucketIndex=%u\n", pass, m_bucketIndex); + kprintf("skipToNext pass %u, m_bucketIndex=%u\n", pass, m_bucketIndex); #endif if (m_bucketIterator.isEnd()) { ++m_bucketIndex; @@ -112,7 +112,7 @@ public: { if (!isEnd && !m_table.isEmpty() && !(m_bucketIterator != DoublyLinkedList<T>::Iterator::universalEnd())) { #ifdef HASHTABLE_DEBUG - printf("bucket iterator init!\n"); + kprintf("bucket iterator init!\n"); #endif m_bucketIterator = m_table.m_buckets[0].chain.begin(); if (m_bucketIterator.isEnd()) @@ -143,7 +143,7 @@ public: const T& operator*() const { #ifdef HASHTABLE_DEBUG - printf("retrieve { bucketIndex: %u, isEnd: %u }\n", m_bucketIndex, m_isEnd); + kprintf("retrieve { bucketIndex: %u, isEnd: %u }\n", m_bucketIndex, m_isEnd); #endif return *m_bucketIterator; } @@ -161,7 +161,7 @@ public: while (!m_isEnd) { #ifdef HASHTABLE_DEBUG ++pass; - printf("skipToNext pass %u, m_bucketIndex=%u\n", pass, m_bucketIndex); + kprintf("skipToNext pass %u, m_bucketIndex=%u\n", pass, m_bucketIndex); #endif if (m_bucketIterator.isEnd()) { ++m_bucketIndex; @@ -188,7 +188,7 @@ public: { if (!isEnd && !m_table.isEmpty() && !(m_bucketIterator != DoublyLinkedList<T>::ConstIterator::universalEnd())) { #ifdef HASHTABLE_DEBUG - printf("const bucket iterator init!\n"); + kprintf("const bucket iterator init!\n"); #endif const DoublyLinkedList<T>& chain = m_table.m_buckets[0].chain; m_bucketIterator = chain.begin(); @@ -242,9 +242,9 @@ void HashTable<T, TraitsForT>::set(T&& value) } if (size() >= capacity()) { rehash(size() + 1); - insert(std::move(value)); + insert(move(value)); } else { - bucket.chain.append(std::move(value)); + bucket.chain.append(move(value)); } m_size++; } @@ -254,7 +254,7 @@ void HashTable<T, TraitsForT>::rehash(unsigned newCapacity) { newCapacity *= 2; #ifdef HASHTABLE_DEBUG - printf("rehash to %u buckets\n", newCapacity); + kprintf("rehash to %u buckets\n", newCapacity); #endif auto* newBuckets = new Bucket[newCapacity]; auto* oldBuckets = m_buckets; @@ -263,11 +263,11 @@ void HashTable<T, TraitsForT>::rehash(unsigned newCapacity) m_capacity = newCapacity; #ifdef HASHTABLE_DEBUG - printf("reinsert %u buckets\n", oldCapacity); + kprintf("reinsert %u buckets\n", oldCapacity); #endif for (unsigned i = 0; i < oldCapacity; ++i) { for (auto& value : oldBuckets[i].chain) { - insert(std::move(value)); + insert(move(value)); } } @@ -286,7 +286,7 @@ template<typename T, typename TraitsForT> void HashTable<T, TraitsForT>::insert(T&& value) { auto& bucket = lookup(value); - bucket.chain.append(std::move(value)); + bucket.chain.append(move(value)); } template<typename T, typename TraitsForT> @@ -341,9 +341,9 @@ typename HashTable<T, TraitsForT>::Bucket& HashTable<T, TraitsForT>::lookup(cons { unsigned hash = TraitsForT::hash(value); #ifdef HASHTABLE_DEBUG - printf("hash for "); + kprintf("hash for "); TraitsForT::dump(value); - printf(" is %u\n", hash); + kprintf(" is %u\n", hash); #endif if (bucketIndex) *bucketIndex = hash % m_capacity; @@ -355,9 +355,9 @@ const typename HashTable<T, TraitsForT>::Bucket& HashTable<T, TraitsForT>::looku { unsigned hash = TraitsForT::hash(value); #ifdef HASHTABLE_DEBUG - printf("hash for "); + kprintf("hash for "); TraitsForT::dump(value); - printf(" is %u\n", hash); + kprintf(" is %u\n", hash); #endif if (bucketIndex) *bucketIndex = hash % m_capacity; @@ -367,14 +367,14 @@ const typename HashTable<T, TraitsForT>::Bucket& HashTable<T, TraitsForT>::looku template<typename T, typename TraitsForT> void HashTable<T, TraitsForT>::dump() const { - printf("HashTable{%p} m_size=%u, m_capacity=%u, m_buckets=%p\n", this, m_size, m_capacity, m_buckets); + kprintf("HashTable{%p} m_size=%u, m_capacity=%u, m_buckets=%p\n", this, m_size, m_capacity, m_buckets); for (unsigned i = 0; i < m_capacity; ++i) { auto& bucket = m_buckets[i]; - printf("Bucket %u\n", i); + kprintf("Bucket %u\n", i); for (auto& e : bucket.chain) { - printf(" > "); + kprintf(" > "); TraitsForT::dump(e); - printf("\n"); + kprintf("\n"); } } } diff --git a/AK/StdLib.h b/AK/StdLib.h index 20d32e8139..ca7196432c 100644 --- a/AK/StdLib.h +++ b/AK/StdLib.h @@ -4,6 +4,7 @@ #include <Kernel/StdLib.h> #else #include <cstring> +#include <cstdlib> #include <utility> #endif @@ -38,11 +39,12 @@ T&& move(T& arg) } template<typename T> -struct identity { - typedef T type; +struct Identity { + typedef T Type; }; + template<class T> -constexpr T&& forward(typename identity<T>::type& param) +constexpr T&& forward(typename Identity<T>::Type& param) { return static_cast<T&&>(param); } @@ -63,6 +65,84 @@ void swap(T& a, U& b) b = move(tmp); } +template<bool B, class T = void> +struct EnableIf +{ +}; + +template<class T> +struct EnableIf<true, T> +{ + typedef T Type; +}; + +template<class T> struct RemoveConst { typedef T Type; }; +template<class T> struct RemoveConst<const T> { typedef T Type; }; +template<class T> struct RemoveVolatile { typedef T Type; }; +template<class T> struct RemoveVolatile<const T> { typedef T Type; }; +template<class T> struct RemoveCV { + typedef typename RemoveVolatile<typename RemoveConst<T>::Type>::Type Type; +}; + +template<class T, T v> +struct IntegralConstant { + static constexpr T value = v; + typedef T ValueType; + typedef IntegralConstant Type; + constexpr operator ValueType() const { return value; } + constexpr ValueType operator()() const { return value; } +}; + +typedef IntegralConstant<bool, false> FalseType; +typedef IntegralConstant<bool, true> TrueType; + +template<class T> +struct __IsPointerHelper : FalseType { }; + +template<class T> +struct __IsPointerHelper<T*> : TrueType { }; + +template<class T> +struct IsPointer : __IsPointerHelper<typename RemoveCV<T>::Type> { }; + +template<class> struct IsFunction : FalseType { }; + +template<class Ret, class... Args> struct IsFunction<Ret(Args...)> : TrueType { }; +template<class Ret, class... Args> struct IsFunction<Ret(Args......)> : TrueType { }; +template<class Ret, class... Args> struct IsFunction<Ret(Args...) const> : TrueType { }; +template<class Ret, class... Args> struct IsFunction<Ret(Args......) const> : TrueType { }; +template<class Ret, class... Args> struct IsFunction<Ret(Args...) volatile> : TrueType { }; +template<class Ret, class... Args> struct IsFunction<Ret(Args......) volatile> : TrueType { }; +template<class Ret, class... Args> struct IsFunction<Ret(Args...) const volatile> : TrueType { }; +template<class Ret, class... Args> struct IsFunction<Ret(Args......) const volatile> : TrueType { }; + +template<class Ret, class... Args> struct IsFunction<Ret(Args...) &> : TrueType { }; +template<class Ret, class... Args> struct IsFunction<Ret(Args......) &> : TrueType { }; +template<class Ret, class... Args> struct IsFunction<Ret(Args...) const &> : TrueType { }; +template<class Ret, class... Args> struct IsFunction<Ret(Args......) const &> : TrueType { }; +template<class Ret, class... Args> struct IsFunction<Ret(Args...) volatile &> : TrueType { }; +template<class Ret, class... Args> struct IsFunction<Ret(Args......) volatile &> : TrueType { }; +template<class Ret, class... Args> struct IsFunction<Ret(Args...) const volatile &> : TrueType { }; +template<class Ret, class... Args> struct IsFunction<Ret(Args......) const volatile &> : TrueType { }; + +template<class Ret, class... Args> struct IsFunction<Ret(Args...) &&> : TrueType { }; +template<class Ret, class... Args> struct IsFunction<Ret(Args......) &&> : TrueType { }; +template<class Ret, class... Args> struct IsFunction<Ret(Args...) const &&> : TrueType { }; +template<class Ret, class... Args> struct IsFunction<Ret(Args......) const &&> : TrueType { }; +template<class Ret, class... Args> struct IsFunction<Ret(Args...) volatile &&> : TrueType { }; +template<class Ret, class... Args> struct IsFunction<Ret(Args......) volatile &&> : TrueType { }; +template<class Ret, class... Args> struct IsFunction<Ret(Args...) const volatile &&> : TrueType { }; +template<class Ret, class... Args> struct IsFunction<Ret(Args......) const volatile &&> : TrueType { }; + +template<class T> struct IsRvalueReference : FalseType { }; +template<class T> struct IsRvalueReference<T&&> : TrueType { }; + +template<class T> struct RemovePointer { typedef T Type; }; +template<class T> struct RemovePointer<T*> { typedef T Type; }; +template<class T> struct RemovePointer<T* const> { typedef T Type; }; +template<class T> struct RemovePointer<T* volatile> { typedef T Type; }; +template<class T> struct RemovePointer<T* const volatile> { typedef T Type; }; + } using AK::min; diff --git a/AK/String.cpp b/AK/String.cpp index 601076d7ff..201bc8d7c1 100644 --- a/AK/String.cpp +++ b/AK/String.cpp @@ -1,5 +1,5 @@ #include "String.h" -#include <cstring> +#include "StdLib.h" namespace AK { diff --git a/AK/String.h b/AK/String.h index bb18494986..4def06f2e6 100644 --- a/AK/String.h +++ b/AK/String.h @@ -5,7 +5,7 @@ #include "StringImpl.h" #include "Traits.h" #include "Vector.h" -#include <cstdio> +#include "kstdio.h" namespace AK { @@ -20,7 +20,7 @@ public: } String(String&& other) - : m_impl(std::move(other.m_impl)) + : m_impl(move(other.m_impl)) { } @@ -40,7 +40,7 @@ public: } String(RetainPtr<StringImpl>&& impl) - : m_impl(std::move(impl)) + : m_impl(move(impl)) { } @@ -77,7 +77,7 @@ public: String& operator=(String&& other) { if (this != &other) { - m_impl = std::move(other.m_impl); + m_impl = move(other.m_impl); } return *this; } @@ -91,7 +91,7 @@ private: template<> struct Traits<String> { static unsigned hash(const String& s) { return s.impl() ? s.impl()->hash() : 0; } - static void dump(const String& s) { printf("%s", s.characters()); } + static void dump(const String& s) { kprintf("%s", s.characters()); } }; } diff --git a/AK/StringImpl.cpp b/AK/StringImpl.cpp index 6276c20a0e..1c00f5a35e 100644 --- a/AK/StringImpl.cpp +++ b/AK/StringImpl.cpp @@ -1,15 +1,14 @@ #include "StringImpl.h" -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <new> +#include "StdLib.h" #include "kmalloc.h" namespace AK { StringImpl& StringImpl::theEmptyStringImpl() { - static StringImpl* s = new StringImpl(ConstructTheEmptyStringImpl); + static StringImpl* s = nullptr; + if (!s) + s = new StringImpl(ConstructTheEmptyStringImpl); return *s; } diff --git a/AK/Traits.h b/AK/Traits.h index 1dfe3c4c19..aa0d307e57 100644 --- a/AK/Traits.h +++ b/AK/Traits.h @@ -1,6 +1,6 @@ #pragma once -#include <cstdio> +#include "kstdio.h" namespace AK { @@ -12,19 +12,19 @@ struct Traits template<> struct Traits<int> { static unsigned hash(int i) { return i; } - static void dump(int i) { printf("%d", i); } + static void dump(int i) { kprintf("%d", i); } }; template<> struct Traits<unsigned> { static unsigned hash(unsigned u) { return u; } - static void dump(unsigned u) { printf("%u", u); } + static void dump(unsigned u) { kprintf("%u", u); } }; template<typename T> struct Traits<T*> { static unsigned hash(const T* p) { return (unsigned)p; } - static void dump(const T* p) { printf("%p", p); } + static void dump(const T* p) { kprintf("%p", p); } }; } diff --git a/AK/Vector.h b/AK/Vector.h index 971e45f192..959b5c9b02 100644 --- a/AK/Vector.h +++ b/AK/Vector.h @@ -3,7 +3,6 @@ #include "Assertions.h" #include "OwnPtr.h" #include "kmalloc.h" -#include <new> namespace AK { diff --git a/AK/kmalloc.cpp b/AK/kmalloc.cpp index 5540bfa091..448b2ca6db 100644 --- a/AK/kmalloc.cpp +++ b/AK/kmalloc.cpp @@ -1,6 +1,6 @@ #include <cstdio> #include "SimpleMalloc.h" -#include <new> +#include "kmalloc.h" #include <cstdlib> #define USE_SYSTEM_MALLOC diff --git a/AK/kmalloc.h b/AK/kmalloc.h index 2c30774456..d90e6150e0 100644 --- a/AK/kmalloc.h +++ b/AK/kmalloc.h @@ -1,13 +1,20 @@ #pragma once +#ifdef SERENITY_KERNEL +#include <Kernel/kmalloc.h> +#else +#include <new> + #include "Types.h" extern "C" { void* kcalloc(size_t nmemb, size_t size); -void* kmalloc(size_t size); +void* kmalloc(size_t size) __attribute__ ((malloc)); void kfree(void* ptr); void* krealloc(void* ptr, size_t size); } +#endif + diff --git a/AK/ktime.h b/AK/ktime.h new file mode 100644 index 0000000000..b5f5e639a8 --- /dev/null +++ b/AK/ktime.h @@ -0,0 +1,15 @@ +#pragma once + +#ifdef SERENITY_KERNEL +inline time_t time(time_t* tloc) +{ + if (tloc) + *tloc = 123; + return 123; +} +#else +#include <time.h> +#define ktime time +#define klocaltime localtime +#endif + |