From 232203f4c026803c10e3bd7bb693420c4da6808a Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Tue, 5 May 2020 19:53:38 -0700 Subject: [PATCH] ams: take care of most TODO C++20s --- .../include/mesosphere/kern_k_auto_object.hpp | 5 +- .../mesosphere/kern_k_capabilities.hpp | 4 +- .../mesosphere/kern_k_priority_queue.hpp | 51 ++--- .../include/mesosphere/kern_k_scheduler.hpp | 11 +- .../mesosphere/kern_k_scheduler_lock.hpp | 19 +- .../include/mesosphere/kern_k_scoped_lock.hpp | 17 +- .../svc/kern_svc_k_user_pointer.hpp | 85 ++++---- .../source/kern_k_object_name.cpp | 5 +- .../sf/impl/sf_impl_command_serialization.hpp | 8 +- .../include/stratosphere/sf/sf_out.hpp | 4 +- .../ncm/ncm_content_meta_database_impl.cpp | 2 +- .../source/os/impl/os_resource_manager.cpp | 3 +- .../crypto/crypto_rsa_oaep_decryptor.hpp | 2 +- .../crypto/crypto_rsa_oaep_encryptor.hpp | 2 +- .../crypto/crypto_rsa_pss_verifier.hpp | 2 +- .../crypto/impl/crypto_hash_function.hpp | 18 +- .../crypto/impl/crypto_rsa_oaep_impl.hpp | 2 +- .../crypto/impl/crypto_rsa_pss_impl.hpp | 2 +- .../crypto/impl/crypto_sha256_impl.hpp | 2 +- .../libvapours/include/vapours/includes.hpp | 3 + libraries/libvapours/include/vapours/span.hpp | 202 +----------------- .../codegen/impl/svc_codegen_impl_layout.hpp | 6 +- .../svc_codegen_impl_layout_conversion.hpp | 7 +- .../include/vapours/util/util_bitutil.hpp | 42 ++-- .../include/vapours/util/util_endian.hpp | 30 +-- .../include/vapours/util/util_fourcc.hpp | 15 +- .../source/kern_kernel_instantiations.cpp | 26 +-- .../ams_mitm/source/amsmitm_module.hpp | 26 ++- .../source/amsmitm_module_management.cpp | 2 +- stratosphere/pgl/source/pgl_main.cpp | 2 +- 30 files changed, 174 insertions(+), 431 deletions(-) diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_auto_object.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_auto_object.hpp index 2ffc28691..01648d3ec 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_auto_object.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_auto_object.hpp @@ -185,10 +185,7 @@ namespace ams::kern { T *obj; private: constexpr ALWAYS_INLINE void Swap(KScopedAutoObject &rhs) { - /* TODO: C++20 constexpr std::swap */ - T *tmp = rhs.obj; - rhs.obj = this->obj; - this->obj = tmp; + std::swap(this->obj, rhs.obj); } public: constexpr ALWAYS_INLINE KScopedAutoObject() : obj(nullptr) { /* ... */ } diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_capabilities.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_capabilities.hpp index bac44a218..72d48666a 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_capabilities.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_capabilities.hpp @@ -64,7 +64,7 @@ namespace ams::kern { static constexpr u32 GetCapabilityId(CapabilityType type) { const u32 flag = GetCapabilityFlag(type); - if (true /* C++20: std::is_constant_evaluated() */) { + if (std::is_constant_evaluated()) { return CountTrailingZero(flag); } else { return static_cast(__builtin_ctz(flag)); @@ -84,7 +84,7 @@ namespace ams::kern { template static constexpr inline u32 CapabilityId = []() -> u32 { const u32 flag = static_cast(Type) + 1; - if (true /* C++20: std::is_constant_evaluated() */) { + if (std::is_constant_evaluated()) { for (u32 i = 0; i < BITSIZEOF(u32); i++) { if (flag & (1u << i)) { return i; diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_priority_queue.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_priority_queue.hpp index 3b471b4d0..033c59373 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_priority_queue.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_priority_queue.hpp @@ -18,39 +18,34 @@ namespace ams::kern { - /* - TODO: C++20 + template + concept KPriorityQueueAffinityMask = !std::is_reference::value && requires (T &t) { + { t.GetAffinityMask() } -> std::convertible_to; + { t.SetAffinityMask(std::declval()) }; - template - concept KPriorityQueueAffinityMask = !std::is_reference::value && requires (T &t) { - { t.GetAffinityMask() } -> std::convertible_to; - { t.SetAffinityMask(std::declval()) }; + { t.GetAffinity(std::declval()) } -> std::same_as; + { t.SetAffinity(std::declval(), std::declval()) }; + { t.SetAll() }; + }; - { t.GetAffinity(std::declval()) } -> std::same_as; - { t.SetAffinity(std::declval(), std::declval()) }; - { t.SetAll() }; - }; + template + concept KPriorityQueueMember = !std::is_reference::value && requires (T &t) { + { typename T::QueueEntry() }; + { (typename T::QueueEntry()).Initialize() }; + { (typename T::QueueEntry()).SetPrev(std::addressof(t)) }; + { (typename T::QueueEntry()).SetNext(std::addressof(t)) }; + { (typename T::QueueEntry()).GetNext() } -> std::same_as; + { (typename T::QueueEntry()).GetPrev() } -> std::same_as; + { t.GetPriorityQueueEntry(std::declval()) } -> std::same_as; - template - concept KPriorityQueueMember = !std::is_reference::value && requires (T &t) { - { typename T::QueueEntry() }; - { (typename T::QueueEntry()).Initialize() }; - { (typename T::QueueEntry()).SetPrev(std::addressof(t)) }; - { (typename T::QueueEntry()).SetNext(std::addressof(t)) }; - { (typename T::QueueEntry()).GetNext() } -> std::same_as; - { (typename T::QueueEntry()).GetPrev() } -> std::same_as; - { t.GetPriorityQueueEntry(std::declval()) } -> std::same_as; + { t.GetAffinityMask() }; + { typename std::remove_cvref::type() } -> KPriorityQueueAffinityMask; - { t.GetAffinityMask() }; - { typename std::remove_cvref::type() } -> KPriorityQueueAffinityMask; + { t.GetActiveCore() } -> std::convertible_to; + { t.GetPriority() } -> std::convertible_to; + }; - { t.GetActiveCore() } -> std::convertible_to; - { t.GetPriority() } -> std::convertible_to; - }; - */ - - - template /* TODO C++20: requires KPriorityQueueMember */ + template requires KPriorityQueueMember class KPriorityQueue { public: using AffinityMaskType = typename std::remove_cv().GetAffinityMask())>::type>::type; diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_scheduler.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_scheduler.hpp index 5fb57ad2f..2e8247f5a 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_scheduler.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_scheduler.hpp @@ -33,8 +33,6 @@ namespace ams::kern { NON_COPYABLE(KScheduler); NON_MOVEABLE(KScheduler); public: - using LockType = KAbstractSchedulerLock; - static constexpr s32 HighestCoreMigrationAllowedPriority = 2; static_assert(ams::svc::LowestThreadPriority >= HighestCoreMigrationAllowedPriority); static_assert(ams::svc::HighestThreadPriority <= HighestCoreMigrationAllowedPriority); @@ -50,9 +48,6 @@ namespace ams::kern { private: friend class KScopedSchedulerLock; friend class KScopedSchedulerLockAndSleep; - static bool s_scheduler_update_needed; - static LockType s_scheduler_lock; - static KSchedulerPriorityQueue s_priority_queue; private: SchedulingState state; bool is_active; @@ -160,6 +155,12 @@ namespace ams::kern { } NOINLINE u64 UpdateHighestPriorityThread(KThread *thread); + public: + using LockType = KAbstractSchedulerLock; + private: + static bool s_scheduler_update_needed; + static KSchedulerPriorityQueue s_priority_queue; + static LockType s_scheduler_lock; }; class KScopedSchedulerLock : KScopedLock { diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_scheduler_lock.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_scheduler_lock.hpp index 3be30f901..355719f13 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_scheduler_lock.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_scheduler_lock.hpp @@ -23,19 +23,14 @@ namespace ams::kern { class KThread; - /* - TODO: C++20 + template + concept KSchedulerLockable = !std::is_reference::value && requires(T) { + { T::DisableScheduling() } -> std::same_as; + { T::EnableScheduling(std::declval()) } -> std::same_as; + { T::UpdateHighestPriorityThreads() } -> std::convertible_to; + }; - template - concept KSchedulerLockable = !std::is_reference::value && requires { - { T::DisableScheduling() } -> std::same_as; - { T::EnableScheduling(std::declval()) } -> std::same_as; - { T::UpdateHighestPriorityThreads() } -> std::convertible_to; - }; - - */ - - template /* TODO C++20: requires KSchedulerLockable */ + template requires KSchedulerLockable class KAbstractSchedulerLock { private: KAlignedSpinLock spin_lock; diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_scoped_lock.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_scoped_lock.hpp index fd6756b2c..8ae0fecbc 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_scoped_lock.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_scoped_lock.hpp @@ -18,18 +18,13 @@ namespace ams::kern { - /* - TODO: C++20 + template + concept KLockable = !std::is_reference::value && requires (T &t) { + { t.Lock() } -> std::same_as; + { t.Unlock() } -> std::same_as; + }; - template - concept KLockable = !std::is_reference::value && requires (T &t) { - { t.Lock() } -> std::same_as; - { t.Unlock() } -> std::same_as; - }; - - */ - - template /* TODO C++20: requires KLockable */ + template requires KLockable class KScopedLock { NON_COPYABLE(KScopedLock); NON_MOVEABLE(KScopedLock); diff --git a/libraries/libmesosphere/include/mesosphere/svc/kern_svc_k_user_pointer.hpp b/libraries/libmesosphere/include/mesosphere/svc/kern_svc_k_user_pointer.hpp index fce28f594..5d707d52e 100644 --- a/libraries/libmesosphere/include/mesosphere/svc/kern_svc_k_user_pointer.hpp +++ b/libraries/libmesosphere/include/mesosphere/svc/kern_svc_k_user_pointer.hpp @@ -22,47 +22,35 @@ namespace ams::kern::svc { namespace impl { - /* TODO: C++20 - template - concept Pointer = std::is_pointer::value; - - template - concept NonConstPointer = Pointer && !std::is_const::type>::value; - - template - concept ConstPointer = Pointer && std::is_const::type>::value; - - template - concept AlignedNPointer = Pointer && alignof(typename std::remove_pointer::type) >= N && util::IsAligned(sizeof(typename std::remove_pointer::type), N); - - template - concept Aligned8Pointer = AlignedNPointer; - - template - concept Aligned16Pointer = AlignedNPointer && Aligned8; - - template - concept Aligned32Pointer = AlignedNPointer && Aligned16; - - template - concept Aligned64Pointer = AlignedNPointer && Aligned32; - */ + template + concept Pointer = std::is_pointer::value; template - constexpr inline bool IsPointer = std::is_pointer::value; + concept NonConstPointer = Pointer && !std::is_const::type>::value; template - constexpr inline bool IsConstPointer = IsPointer && std::is_const::type>::value; - - template - constexpr inline bool IsNonConstPointer = IsPointer && !std::is_const::type>::value; + concept ConstPointer = Pointer && std::is_const::type>::value; template - constexpr inline bool IsAlignedNPointer = IsPointer && alignof(typename std::remove_pointer::type) >= N && util::IsAligned(sizeof(typename std::remove_pointer::type), N); + concept AlignedNPointer = Pointer && alignof(typename std::remove_pointer::type) >= N && util::IsAligned(sizeof(typename std::remove_pointer::type), N); - template /* requires Aligned8Pointer<_T> */ - class KUserPointerImplTraits { - static_assert(IsAlignedNPointer<_T, sizeof(u8)>); + template + concept Aligned8Pointer = AlignedNPointer; + + template + concept Aligned16Pointer = AlignedNPointer && Aligned8Pointer; + + template + concept Aligned32Pointer = AlignedNPointer && Aligned16Pointer; + + template + concept Aligned64Pointer = AlignedNPointer && Aligned32Pointer; + + template + class KUserPointerImplTraits; + + template requires Aligned8Pointer<_T> + class KUserPointerImplTraits<_T> { public: using T = typename std::remove_const::type>::type; public: @@ -77,9 +65,8 @@ namespace ams::kern::svc { } }; - template /* requires Aligned32Pointer<_T> */ - class KUserPointerImplTraits<_T, typename std::enable_if && !IsAlignedNPointer<_T, sizeof(u64)>>::type> { - static_assert(IsAlignedNPointer<_T, sizeof(u32)>); + template requires Aligned32Pointer<_T> + class KUserPointerImplTraits<_T> { public: using T = typename std::remove_const::type>::type; public: @@ -94,9 +81,8 @@ namespace ams::kern::svc { } }; - template /* requires Aligned64Pointer<_T> */ - class KUserPointerImplTraits<_T, typename std::enable_if>::type> { - static_assert(IsAlignedNPointer<_T, sizeof(u64)>); + template requires Aligned64Pointer<_T> + class KUserPointerImplTraits<_T> { public: using T = typename std::remove_const::type>::type; public: @@ -111,8 +97,11 @@ namespace ams::kern::svc { } }; - template /* requires Aligned8Pointer<_T> */ - class KUserPointerImpl : impl::KUserPointerTag { + template + class KUserPointerImpl; + + template requires Aligned8Pointer<_T> + class KUserPointerImpl<_T> : impl::KUserPointerTag { private: using Traits = KUserPointerImplTraits<_T>; protected: @@ -170,11 +159,11 @@ namespace ams::kern::svc { } - template - class KUserPointer; + template + struct KUserPointer; - template /* requires impl::ConstPointer */ - struct KUserPointer>::type> : public impl::KUserPointerImpl { + template requires impl::ConstPointer + struct KUserPointer : public impl::KUserPointerImpl { public: static constexpr bool IsInput = true; public: @@ -186,8 +175,8 @@ namespace ams::kern::svc { using impl::KUserPointerImpl::GetUnsafePointer; }; - template /* requires impl::NonConstPointer */ - struct KUserPointer>::type> : public impl::KUserPointerImpl { + template requires impl::NonConstPointer + struct KUserPointer : public impl::KUserPointerImpl { public: static constexpr bool IsInput = false; public: diff --git a/libraries/libmesosphere/source/kern_k_object_name.cpp b/libraries/libmesosphere/source/kern_k_object_name.cpp index 763122450..b5fd505a4 100644 --- a/libraries/libmesosphere/source/kern_k_object_name.cpp +++ b/libraries/libmesosphere/source/kern_k_object_name.cpp @@ -19,9 +19,8 @@ namespace ams::kern { namespace { - /* TODO: C++20 constinit */ - KLightLock g_object_list_lock; - KObjectName::List g_object_list; + constinit KLightLock g_object_list_lock; + constinit KObjectName::List g_object_list; } diff --git a/libraries/libstratosphere/include/stratosphere/sf/impl/sf_impl_command_serialization.hpp b/libraries/libstratosphere/include/stratosphere/sf/impl/sf_impl_command_serialization.hpp index 0f3a646ce..2247d6de5 100644 --- a/libraries/libstratosphere/include/stratosphere/sf/impl/sf_impl_command_serialization.hpp +++ b/libraries/libstratosphere/include/stratosphere/sf/impl/sf_impl_command_serialization.hpp @@ -77,7 +77,7 @@ namespace ams::sf { class Out> : public impl::OutObjectTag { static_assert(std::is_base_of::value, "Out> requires ServiceObject base."); - template + template friend class Out; public: @@ -308,11 +308,7 @@ namespace ams::sf::impl { /* Use insertion sort, which is stable and optimal for small numbers of parameters. */ for (size_t i = 1; i < sizeof...(Ts); i++) { for (size_t j = i; j > 0 && values[map[j-1]] > values[map[j]]; j--) { - /* std::swap is not constexpr until c++20 :( */ - /* TODO: std::swap(map[j], map[j-1]); */ - const size_t tmp = map[j]; - map[j] = map[j-1]; - map[j-1] = tmp; + std::swap(map[j], map[j-1]); } } } diff --git a/libraries/libstratosphere/include/stratosphere/sf/sf_out.hpp b/libraries/libstratosphere/include/stratosphere/sf/sf_out.hpp index b5fb1e6f1..414c916da 100644 --- a/libraries/libstratosphere/include/stratosphere/sf/sf_out.hpp +++ b/libraries/libstratosphere/include/stratosphere/sf/sf_out.hpp @@ -33,9 +33,9 @@ namespace ams::sf { struct IsOutForceEnabled<::ams::Result> : public std::true_type{}; template - using IsOutEnabled = typename std::enable_if::value || IsOutForceEnabled::value>::type; + concept OutEnabled = (std::is_trivial::value || IsOutForceEnabled::value) && !std::is_pointer::value; - template> + template requires OutEnabled class Out : public impl::OutBaseTag { public: static constexpr size_t TypeSize = sizeof(T); diff --git a/libraries/libstratosphere/source/ncm/ncm_content_meta_database_impl.cpp b/libraries/libstratosphere/source/ncm/ncm_content_meta_database_impl.cpp index a9cad8536..30d5ac10d 100644 --- a/libraries/libstratosphere/source/ncm/ncm_content_meta_database_impl.cpp +++ b/libraries/libstratosphere/source/ncm/ncm_content_meta_database_impl.cpp @@ -451,7 +451,7 @@ namespace ams::ncm { /* Ensure this type of key has an owner. */ R_UNLESS(key.type == ContentMetaType::Application || key.type == ContentMetaType::Patch || key.type == ContentMetaType::AddOnContent, ncm::ResultInvalidContentMetaKey()); - + /* Applications are their own owner. */ if (key.type == ContentMetaType::Application) { out_id.SetValue({key.id}); diff --git a/libraries/libstratosphere/source/os/impl/os_resource_manager.cpp b/libraries/libstratosphere/source/os/impl/os_resource_manager.cpp index 6585ea6c4..6ff528a31 100644 --- a/libraries/libstratosphere/source/os/impl/os_resource_manager.cpp +++ b/libraries/libstratosphere/source/os/impl/os_resource_manager.cpp @@ -18,7 +18,6 @@ namespace ams::os::impl { - /* TODO: C++20 constinit */ - TYPED_STORAGE(OsResourceManager) ResourceManagerHolder::s_resource_manager_storage = {}; + constinit TYPED_STORAGE(OsResourceManager) ResourceManagerHolder::s_resource_manager_storage = {}; } diff --git a/libraries/libvapours/include/vapours/crypto/crypto_rsa_oaep_decryptor.hpp b/libraries/libvapours/include/vapours/crypto/crypto_rsa_oaep_decryptor.hpp index 73bbeacf3..86b3750b7 100644 --- a/libraries/libvapours/include/vapours/crypto/crypto_rsa_oaep_decryptor.hpp +++ b/libraries/libvapours/include/vapours/crypto/crypto_rsa_oaep_decryptor.hpp @@ -23,7 +23,7 @@ namespace ams::crypto { - template /* requires HashFunction */ + template requires impl::HashFunction class RsaOaepDecryptor { NON_COPYABLE(RsaOaepDecryptor); NON_MOVEABLE(RsaOaepDecryptor); diff --git a/libraries/libvapours/include/vapours/crypto/crypto_rsa_oaep_encryptor.hpp b/libraries/libvapours/include/vapours/crypto/crypto_rsa_oaep_encryptor.hpp index bd29e4e2a..bcda34713 100644 --- a/libraries/libvapours/include/vapours/crypto/crypto_rsa_oaep_encryptor.hpp +++ b/libraries/libvapours/include/vapours/crypto/crypto_rsa_oaep_encryptor.hpp @@ -23,7 +23,7 @@ namespace ams::crypto { - template /* requires HashFunction */ + template requires impl::HashFunction class RsaOaepEncryptor { NON_COPYABLE(RsaOaepEncryptor); NON_MOVEABLE(RsaOaepEncryptor); diff --git a/libraries/libvapours/include/vapours/crypto/crypto_rsa_pss_verifier.hpp b/libraries/libvapours/include/vapours/crypto/crypto_rsa_pss_verifier.hpp index bd7ddcea6..273854489 100644 --- a/libraries/libvapours/include/vapours/crypto/crypto_rsa_pss_verifier.hpp +++ b/libraries/libvapours/include/vapours/crypto/crypto_rsa_pss_verifier.hpp @@ -23,7 +23,7 @@ namespace ams::crypto { - template /* requires HashFunction */ + template requires impl::HashFunction class RsaPssVerifier { NON_COPYABLE(RsaPssVerifier); NON_MOVEABLE(RsaPssVerifier); diff --git a/libraries/libvapours/include/vapours/crypto/impl/crypto_hash_function.hpp b/libraries/libvapours/include/vapours/crypto/impl/crypto_hash_function.hpp index b598b46f6..68ca106a3 100644 --- a/libraries/libvapours/include/vapours/crypto/impl/crypto_hash_function.hpp +++ b/libraries/libvapours/include/vapours/crypto/impl/crypto_hash_function.hpp @@ -23,15 +23,13 @@ namespace ams::crypto::impl { - /* TODO: C++20 - template - concept HashFunction = requires(T &t, const void *cv, void *v, size_t sz) { - { T::HashSize } -> std::same_as; - { T::BlockSize } -> std::same_as; - { t.Initialize() } -> std::same_as; - { t.Update(cv, sz) } -> std::same_as; - { t.GetHash(v, sz) } -> std::same_as; - }; - */ + template + concept HashFunction = requires(T &t, const void *cv, void *v, size_t sz) { + { T::HashSize } -> std::convertible_to; + { T::BlockSize } -> std::convertible_to; + { t.Initialize() } -> std::same_as; + { t.Update(cv, sz) } -> std::same_as; + { t.GetHash(v, sz) } -> std::same_as; + }; } diff --git a/libraries/libvapours/include/vapours/crypto/impl/crypto_rsa_oaep_impl.hpp b/libraries/libvapours/include/vapours/crypto/impl/crypto_rsa_oaep_impl.hpp index d925f16a8..cc0e59563 100644 --- a/libraries/libvapours/include/vapours/crypto/impl/crypto_rsa_oaep_impl.hpp +++ b/libraries/libvapours/include/vapours/crypto/impl/crypto_rsa_oaep_impl.hpp @@ -22,7 +22,7 @@ namespace ams::crypto::impl { - template /* requires HashFunction */ + template requires HashFunction class RsaOaepImpl { NON_COPYABLE(RsaOaepImpl); NON_MOVEABLE(RsaOaepImpl); diff --git a/libraries/libvapours/include/vapours/crypto/impl/crypto_rsa_pss_impl.hpp b/libraries/libvapours/include/vapours/crypto/impl/crypto_rsa_pss_impl.hpp index 1ce73e726..3febb5aba 100644 --- a/libraries/libvapours/include/vapours/crypto/impl/crypto_rsa_pss_impl.hpp +++ b/libraries/libvapours/include/vapours/crypto/impl/crypto_rsa_pss_impl.hpp @@ -22,7 +22,7 @@ namespace ams::crypto::impl { - template /* requires HashFunction */ + template requires HashFunction class RsaPssImpl { NON_COPYABLE(RsaPssImpl); NON_MOVEABLE(RsaPssImpl); diff --git a/libraries/libvapours/include/vapours/crypto/impl/crypto_sha256_impl.hpp b/libraries/libvapours/include/vapours/crypto/impl/crypto_sha256_impl.hpp index bbd145efb..ab9b69710 100644 --- a/libraries/libvapours/include/vapours/crypto/impl/crypto_sha256_impl.hpp +++ b/libraries/libvapours/include/vapours/crypto/impl/crypto_sha256_impl.hpp @@ -66,6 +66,6 @@ namespace ams::crypto::impl { } }; - /* static_assert(HashFunction); */ + static_assert(HashFunction); } diff --git a/libraries/libvapours/include/vapours/includes.hpp b/libraries/libvapours/include/vapours/includes.hpp index 713d7d4c5..577e2c458 100644 --- a/libraries/libvapours/include/vapours/includes.hpp +++ b/libraries/libvapours/include/vapours/includes.hpp @@ -28,6 +28,7 @@ /* C++ headers. */ #include +#include #include #include #include @@ -38,6 +39,8 @@ #include #include #include +#include +#include /* Stratosphere wants additional libstdc++ headers, others do not. */ #ifdef ATMOSPHERE_IS_STRATOSPHERE diff --git a/libraries/libvapours/include/vapours/span.hpp b/libraries/libvapours/include/vapours/span.hpp index ee0a07a2d..dc94f5f31 100644 --- a/libraries/libvapours/include/vapours/span.hpp +++ b/libraries/libvapours/include/vapours/span.hpp @@ -19,207 +19,7 @@ namespace ams { - /* TODO C++20 switch to template using Span = std::span */ - - namespace impl { - - template - class SpanConstIterator; - - template - class SpanIteratorImpl { - public: - friend class SpanConstIterator; - - using index_type = typename Span::index_type; - using difference_type = typename Span::difference_type; - using value_type = typename std::remove_cv::type; - using pointer = typename std::add_pointer::type; - using reference = Reference; - using iterator_category = std::random_access_iterator_tag; - private: - const Span *span = nullptr; - index_type index = 0; - public: - constexpr ALWAYS_INLINE SpanIteratorImpl() = default; - constexpr ALWAYS_INLINE SpanIteratorImpl(const Span *s, index_type idx) : span(s), index(idx) { /* ... */ } - - constexpr ALWAYS_INLINE pointer operator->() const { - return this->span->data() + this->index; - } - - constexpr ALWAYS_INLINE reference operator*() const { - return *this->operator->(); - } - - constexpr ALWAYS_INLINE Derived operator++(int) { - auto prev = static_cast(*this); - ++(*this); - return prev; - } - - constexpr ALWAYS_INLINE Derived operator--(int) { - auto prev = static_cast(*this); - --(*this); - return prev; - } - - constexpr ALWAYS_INLINE Derived &operator++() { ++this->index; return static_cast(*this); } - constexpr ALWAYS_INLINE Derived &operator--() { --this->index; return static_cast(*this); } - - constexpr ALWAYS_INLINE Derived &operator+=(difference_type n) { this->index += n; return static_cast(*this); } - constexpr ALWAYS_INLINE Derived &operator-=(difference_type n) { this->index -= n; return static_cast(*this); } - - constexpr ALWAYS_INLINE Derived operator+(difference_type n) const { auto r = static_cast(*this); return r += n; } - constexpr ALWAYS_INLINE Derived operator-(difference_type n) const { auto r = static_cast(*this); return r -= n; } - - constexpr ALWAYS_INLINE friend Derived operator+(difference_type n, Derived it) { return it + n; } - constexpr ALWAYS_INLINE difference_type operator-(Derived rhs) const { AMS_ASSERT(this->span == rhs.span); return this->index - rhs.index; } - - constexpr ALWAYS_INLINE reference operator[](difference_type n) const { return *(*this + n); } - - constexpr ALWAYS_INLINE friend bool operator==(Derived lhs, Derived rhs) { - return lhs.span == rhs.span && lhs.index == rhs.index; - } - - constexpr ALWAYS_INLINE friend bool operator<(Derived lhs, Derived rhs) { - AMS_ASSERT(lhs.span == rhs.span); - return lhs.index < rhs.index; - } - - constexpr ALWAYS_INLINE friend bool operator!=(Derived lhs, Derived rhs) { return !(lhs == rhs); } - - constexpr ALWAYS_INLINE friend bool operator>(Derived lhs, Derived rhs) { return rhs < lhs; } - - constexpr ALWAYS_INLINE friend bool operator<=(Derived lhs, Derived rhs) { return !(lhs > rhs); } - constexpr ALWAYS_INLINE friend bool operator>=(Derived lhs, Derived rhs) { return !(lhs < rhs); } - }; - - template - class SpanIterator : public SpanIteratorImpl, typename Span::element_type&> { - public: - using SpanIteratorImpl, typename Span::element_type&>::SpanIteratorImpl; - }; - - template - class SpanConstIterator : public SpanIteratorImpl, const typename Span::element_type&> { - public: - using SpanIteratorImpl, const typename Span::element_type&>::SpanIteratorImpl; - - constexpr ALWAYS_INLINE SpanConstIterator() = default; - constexpr ALWAYS_INLINE SpanConstIterator(const SpanIterator &rhs) : SpanConstIterator(rhs.span, rhs.index) { /* ... */ } - }; - - } - template - class Span { - public: - using element_type = T; - using value_type = typename std::remove_cv::type; - using index_type = std::ptrdiff_t; - using difference_type = std::ptrdiff_t; - using pointer = element_type *; - using reference = element_type &; - using iterator = ::ams::impl::SpanIterator; - using const_iterator = ::ams::impl::SpanConstIterator; - using reverse_iterator = std::reverse_iterator; - using const_reverse_iterator = std::reverse_iterator; - private: - T *ptr; - index_type num_elements; - public: - constexpr ALWAYS_INLINE Span() : ptr(), num_elements() { /* ... */ } - - constexpr ALWAYS_INLINE Span(T *p, index_type size) : ptr(p), num_elements(size) { - AMS_ASSERT(this->num_elements > 0 || this->ptr == nullptr); - } - - constexpr ALWAYS_INLINE Span(T *start, T *end) : Span(start, end - start) { /* ... */ } - - template - constexpr ALWAYS_INLINE Span(T (&arr)[Size]) : Span(static_cast(arr), static_cast(Size)) { /* ... */ } - - template - constexpr ALWAYS_INLINE Span(std::array &arr) : Span(arr.data(), static_cast(Size)) { /* ... */ } - - template - constexpr ALWAYS_INLINE Span(const std::array &arr) : Span(arr.data(), static_cast(Size)) { /* ... */ } - - template::value>::type> - constexpr ALWAYS_INLINE Span(const Span &rhs) : Span(rhs.data(), rhs.size()) { /* ... */ } - public: - constexpr ALWAYS_INLINE iterator begin() const { return { this, 0 }; } - constexpr ALWAYS_INLINE iterator end() const { return { this, this->num_elements }; } - - constexpr ALWAYS_INLINE const_iterator cbegin() const { return { this, 0 }; } - constexpr ALWAYS_INLINE const_iterator cend() const { return { this, this->num_elements }; } - - constexpr ALWAYS_INLINE reverse_iterator rbegin() const { return reverse_iterator(this->end()); } - constexpr ALWAYS_INLINE reverse_iterator rend() const { return reverse_iterator(this->begin()); } - - constexpr ALWAYS_INLINE const_reverse_iterator crbegin() const { return reverse_iterator(this->cend()); } - constexpr ALWAYS_INLINE const_reverse_iterator crend() const { return reverse_iterator(this->cbegin()); } - - constexpr ALWAYS_INLINE pointer data() const { return this->ptr; } - - constexpr ALWAYS_INLINE index_type size() const { return this->num_elements; } - constexpr ALWAYS_INLINE index_type size_bytes() const { return this->size() * sizeof(T); } - - constexpr ALWAYS_INLINE bool empty() const { return this->size() == 0; } - - constexpr ALWAYS_INLINE T &operator[](index_type idx) const { - AMS_ASSERT(idx < this->size()); - return this->ptr[idx]; - } - - constexpr ALWAYS_INLINE T &operator()(index_type idx) const { return (*this)[idx]; } - - constexpr ALWAYS_INLINE Span first(index_type size) const { - AMS_ASSERT(size <= this->size()); - return { this->ptr, size }; - } - - constexpr ALWAYS_INLINE Span last(index_type size) const { - AMS_ASSERT(size <= this->size()); - return { this->ptr + (this->size() - size), size }; - } - - constexpr ALWAYS_INLINE Span subspan(index_type idx, index_type size) const { - AMS_ASSERT(size <= this->size()); - AMS_ASSERT(this->size() - size >= idx); - return { this->ptr + idx, size }; - } - - constexpr ALWAYS_INLINE Span subspan(index_type idx) const { - AMS_ASSERT(idx <= this->size()); - return { this->ptr + idx, this->size() - idx }; - } - }; - - template - constexpr ALWAYS_INLINE Span MakeSpan(T *start, T *end) { - return { start, end }; - } - - template - constexpr ALWAYS_INLINE Span MakeSpan(T *p, typename Span::index_type size) { - return { p, size }; - } - - template - constexpr ALWAYS_INLINE Span MakeSpan(T (&arr)[Size]) { - return Span(arr); - } - - template - constexpr ALWAYS_INLINE Span MakeSpan(std::array &arr) { - return Span(arr); - } - - template - constexpr ALWAYS_INLINE Span MakeSpan(const std::array &arr) { - return Span(arr); - } + using Span = std::span; } diff --git a/libraries/libvapours/include/vapours/svc/codegen/impl/svc_codegen_impl_layout.hpp b/libraries/libvapours/include/vapours/svc/codegen/impl/svc_codegen_impl_layout.hpp index 5edd6e1f9..4a6adadd8 100644 --- a/libraries/libvapours/include/vapours/svc/codegen/impl/svc_codegen_impl_layout.hpp +++ b/libraries/libvapours/include/vapours/svc/codegen/impl/svc_codegen_impl_layout.hpp @@ -220,11 +220,7 @@ namespace ams::svc::codegen::impl { } for (size_t i = 1; i < num_parameters; i++) { for (size_t j = i; j > 0 && param_layout.GetParameter(map[j-1]).GetLocation(0) > param_layout.GetParameter(map[j]).GetLocation(0); j--) { - /* std::swap is not constexpr until c++20 :( */ - /* TODO: std::swap(map[j], map[j-1]); */ - const size_t tmp = map[j]; - map[j] = map[j-1]; - map[j-1] = tmp; + std::swap(map[j], map[j-1]); } } diff --git a/libraries/libvapours/include/vapours/svc/codegen/impl/svc_codegen_impl_layout_conversion.hpp b/libraries/libvapours/include/vapours/svc/codegen/impl/svc_codegen_impl_layout_conversion.hpp index f15601790..1b0189925 100644 --- a/libraries/libvapours/include/vapours/svc/codegen/impl/svc_codegen_impl_layout_conversion.hpp +++ b/libraries/libvapours/include/vapours/svc/codegen/impl/svc_codegen_impl_layout_conversion.hpp @@ -313,11 +313,7 @@ namespace ams::svc::codegen::impl { } for (size_t i = 1; i < num_parameters; i++) { for (size_t j = i; j > 0 && CapturedSvc.GetParameter(map[j-1]).GetLocation(0) > CapturedSvc.GetParameter(map[j]).GetLocation(0); j--) { - /* std::swap is not constexpr until c++20 :( */ - /* TODO: std::swap(map[j], map[j-1]); */ - const size_t tmp = map[j]; - map[j] = map[j-1]; - map[j-1] = tmp; + std::swap(map[j], map[j-1]); } } return map; @@ -376,7 +372,6 @@ namespace ams::svc::codegen::impl { constexpr size_t RegisterSize = SvcAbiType::RegisterSize; constexpr size_t PassedSize = ProcedureParam.GetTypeSize(); - /* TODO: C++20 templated lambdas. For now, use GCC extension syntax. */ constexpr auto SvcIndexSequence = [](std::index_sequence) { return std::index_sequence{}; }.template operator()(std::make_index_sequence()); diff --git a/libraries/libvapours/include/vapours/util/util_bitutil.hpp b/libraries/libvapours/include/vapours/util/util_bitutil.hpp index de8e78983..cf974f62d 100644 --- a/libraries/libvapours/include/vapours/util/util_bitutil.hpp +++ b/libraries/libvapours/include/vapours/util/util_bitutil.hpp @@ -30,11 +30,9 @@ namespace ams::util { } - template + template requires std::integral class BitsOf { private: - static_assert(std::is_integral::value); - static constexpr ALWAYS_INLINE int GetLsbPos(T v) { return __builtin_ctzll(static_cast(v)); } @@ -78,69 +76,68 @@ namespace ams::util { } }; - template + template requires std::integral constexpr ALWAYS_INLINE T CombineBits(Args... args) { return (... | (T(1u) << args)); } - template + template requires std::integral constexpr ALWAYS_INLINE T ResetLeastSignificantOneBit(T x) { return x & (x - 1); } - template + template requires std::integral constexpr ALWAYS_INLINE T SetLeastSignificantZeroBit(T x) { return x | (x + 1); } - template + template requires std::integral constexpr ALWAYS_INLINE T LeastSignificantOneBit(T x) { return x & ~(x - 1); } - template + template requires std::integral constexpr ALWAYS_INLINE T LeastSignificantZeroBit(T x) { return ~x & (x + 1); } - template + template requires std::integral constexpr ALWAYS_INLINE T ResetTrailingOnes(T x) { return x & (x + 1); } - template + template requires std::integral constexpr ALWAYS_INLINE T SetTrailingZeros(T x) { return x | (x - 1); } - template + template requires std::integral constexpr ALWAYS_INLINE T MaskTrailingZeros(T x) { return (~x) & (x - 1); } - template + template requires std::integral constexpr ALWAYS_INLINE T MaskTrailingOnes(T x) { return ~((~x) | (x + 1)); } - template + template requires std::integral constexpr ALWAYS_INLINE T MaskTrailingZerosAndLeastSignificantOneBit(T x) { return x ^ (x - 1); } - template + template requires std::integral constexpr ALWAYS_INLINE T MaskTrailingOnesAndLeastSignificantZeroBit(T x) { return x ^ (x + 1); } - template + template requires std::integral constexpr ALWAYS_INLINE int PopCount(T x) { /* TODO: C++20 std::bit_cast */ using U = typename std::make_unsigned::type; U u = static_cast(x); - /* TODO: C++20 std::is_constant_evaluated */ - if (false) { + if (std::is_constant_evaluated()) { /* https://en.wikipedia.org/wiki/Hamming_weight */ constexpr U m1 = U(-1) / 0x03; constexpr U m2 = U(-1) / 0x05; @@ -168,10 +165,9 @@ namespace ams::util { } } - template + template requires std::integral constexpr ALWAYS_INLINE int CountLeadingZeros(T x) { - /* TODO: C++20 std::is_constant_evaluated */ - if (false) { + if (std::is_constant_evaluated()) { for (size_t i = 0; i < impl::Log2; ++i) { const size_t shift = (0x1 << i); x |= x >> shift; @@ -195,18 +191,18 @@ namespace ams::util { } } - template + template requires std::integral constexpr ALWAYS_INLINE bool IsPowerOfTwo(T x) { return x > 0 && ResetLeastSignificantOneBit(x) == 0; } - template + template requires std::integral constexpr ALWAYS_INLINE T CeilingPowerOfTwo(T x) { AMS_ASSERT(x > 0); return T(1) << (BITSIZEOF(T) - CountLeadingZeros(T(x - 1))); } - template + template requires std::integral constexpr ALWAYS_INLINE T FloorPowerOfTwo(T x) { AMS_ASSERT(x > 0); return T(1) << (BITSIZEOF(T) - CountLeadingZeros(x) - 1); diff --git a/libraries/libvapours/include/vapours/util/util_endian.hpp b/libraries/libvapours/include/vapours/util/util_endian.hpp index fcf294baf..19844f202 100644 --- a/libraries/libvapours/include/vapours/util/util_endian.hpp +++ b/libraries/libvapours/include/vapours/util/util_endian.hpp @@ -20,27 +20,17 @@ namespace ams::util { - /* TODO: C++20 std::endian */ - constexpr bool IsLittleEndian() { - #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ - return true; - #else - return false; - #endif + return std::endian::native == std::endian::little; } constexpr bool IsBigEndian() { - #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ - return true; - #else - return false; - #endif + return std::endian::native == std::endian::big; } static_assert(IsLittleEndian() ^ IsBigEndian()); - template /* requires unsigned_integral */ + template requires std::unsigned_integral constexpr ALWAYS_INLINE U SwapBytes(const U u) { static_assert(BITSIZEOF(u8) == 8); constexpr U ByteMask = 0xFFu; @@ -85,14 +75,14 @@ namespace ams::util { ((u & (ByteMask << 0)) << 40); } - template /* requires integral */ + template requires std::integral constexpr ALWAYS_INLINE void SwapBytes(T *ptr) { using U = typename std::make_unsigned::type; *ptr = static_cast(SwapBytes(static_cast(*ptr))); } - template /* requires integral */ + template requires std::integral constexpr ALWAYS_INLINE T ConvertToBigEndian(const T val) { using U = typename std::make_unsigned::type; @@ -104,7 +94,7 @@ namespace ams::util { } } - template /* requires integral */ + template requires std::integral constexpr ALWAYS_INLINE T ConvertToLittleEndian(const T val) { using U = typename std::make_unsigned::type; @@ -116,7 +106,7 @@ namespace ams::util { } } - template /* requires integral */ + template requires std::integral constexpr ALWAYS_INLINE T ConvertToBigEndian48(const T val) { using U = typename std::make_unsigned::type; static_assert(sizeof(T) == sizeof(u64)); @@ -130,7 +120,7 @@ namespace ams::util { } } - template /* requires integral */ + template requires std::integral constexpr ALWAYS_INLINE T ConvertToLittleEndian48(const T val) { using U = typename std::make_unsigned::type; static_assert(sizeof(T) == sizeof(u64)); @@ -144,12 +134,12 @@ namespace ams::util { } } - template /* requires integral */ + template requires std::integral constexpr ALWAYS_INLINE T LoadBigEndian(T *ptr) { return ConvertToBigEndian(*ptr); } - template /* requires integral */ + template requires std::integral constexpr ALWAYS_INLINE T LoadLittleEndian(T *ptr) { return ConvertToLittleEndian(*ptr); } diff --git a/libraries/libvapours/include/vapours/util/util_fourcc.hpp b/libraries/libvapours/include/vapours/util/util_fourcc.hpp index 5b805e03b..08e8b3c08 100644 --- a/libraries/libvapours/include/vapours/util/util_fourcc.hpp +++ b/libraries/libvapours/include/vapours/util/util_fourcc.hpp @@ -17,16 +17,14 @@ #pragma once #include #include +#include namespace ams::util { template struct FourCC { - /* TODO: C++20 std::endian */ - static constexpr u32 Code = (static_cast(A) << 0x00) | - (static_cast(B) << 0x08) | - (static_cast(C) << 0x10) | - (static_cast(D) << 0x18); + static constexpr u32 Code = IsLittleEndian() ? ((static_cast(A) << 0x00) | (static_cast(B) << 0x08) | (static_cast(C) << 0x10) | (static_cast(D) << 0x18)) + : ((static_cast(A) << 0x18) | (static_cast(B) << 0x10) | (static_cast(C) << 0x08) | (static_cast(D) << 0x00)); static constexpr const char String[] = {A, B, C, D}; @@ -36,11 +34,8 @@ namespace ams::util { template struct ReverseFourCC { - /* TODO: C++20 std::endian */ - static constexpr u32 Code = (static_cast(A) << 0x18) | - (static_cast(B) << 0x10) | - (static_cast(C) << 0x08) | - (static_cast(D) << 0x00); + static constexpr u32 Code = IsLittleEndian() ? ((static_cast(A) << 0x18) | (static_cast(B) << 0x10) | (static_cast(C) << 0x08) | (static_cast(D) << 0x00)) + : ((static_cast(A) << 0x00) | (static_cast(B) << 0x08) | (static_cast(C) << 0x10) | (static_cast(D) << 0x18)); static constexpr const char String[] = {D, C, B, A}; diff --git a/mesosphere/kernel/source/kern_kernel_instantiations.cpp b/mesosphere/kernel/source/kern_kernel_instantiations.cpp index 743dc5596..5bed676ec 100644 --- a/mesosphere/kernel/source/kern_kernel_instantiations.cpp +++ b/mesosphere/kernel/source/kern_kernel_instantiations.cpp @@ -18,22 +18,22 @@ namespace ams::kern { /* Declare kernel data members in kernel TU. */ - Kernel::State Kernel::s_state = Kernel::State::Invalid; - KResourceLimit Kernel::s_system_resource_limit; - KMemoryManager Kernel::s_memory_manager; - KPageTableManager Kernel::s_page_table_manager; - KMemoryBlockSlabManager Kernel::s_app_memory_block_manager; - KMemoryBlockSlabManager Kernel::s_sys_memory_block_manager; - KBlockInfoManager Kernel::s_block_info_manager; - KSupervisorPageTable Kernel::s_supervisor_page_table; - KSynchronization Kernel::s_synchronization; - KUnsafeMemory Kernel::s_unsafe_memory; - KWorkerTaskManager Kernel::s_worker_task_managers[KWorkerTaskManager::WorkerType_Count]; + constinit Kernel::State Kernel::s_state = Kernel::State::Invalid; + constinit KResourceLimit Kernel::s_system_resource_limit; + KMemoryManager Kernel::s_memory_manager; + constinit KPageTableManager Kernel::s_page_table_manager; + constinit KMemoryBlockSlabManager Kernel::s_app_memory_block_manager; + constinit KMemoryBlockSlabManager Kernel::s_sys_memory_block_manager; + constinit KBlockInfoManager Kernel::s_block_info_manager; + constinit KSupervisorPageTable Kernel::s_supervisor_page_table; + constinit KSynchronization Kernel::s_synchronization; + constinit KUnsafeMemory Kernel::s_unsafe_memory; + constinit KWorkerTaskManager Kernel::s_worker_task_managers[KWorkerTaskManager::WorkerType_Count]; namespace { - /* TODO: C++20 constinit */ std::array g_main_threads; - /* TODO: C++20 constinit */ std::array g_idle_threads; + constinit std::array g_main_threads; + constinit std::array g_idle_threads; } KThread &Kernel::GetMainThread(s32 core_id) { return g_main_threads[core_id]; } diff --git a/stratosphere/ams_mitm/source/amsmitm_module.hpp b/stratosphere/ams_mitm/source/amsmitm_module.hpp index 75333f47b..1c68f3200 100644 --- a/stratosphere/ams_mitm/source/amsmitm_module.hpp +++ b/stratosphere/ams_mitm/source/amsmitm_module.hpp @@ -19,21 +19,25 @@ namespace ams::mitm { /* TODO: C++20 Concepts will make this a lot less stupid. */ - class ModuleBase {}; + template + concept IsModule = requires(T, void *arg) { + { T::ThreadPriority } -> std::convertible_to; + { T::StackSize } -> std::convertible_to; + { T::Stack } -> std::convertible_to; + { T::ThreadFunction(arg) } -> std::same_as; + }; - #define DEFINE_MITM_MODULE_CLASS(ss, prio) class MitmModule : public ::ams::mitm::ModuleBase { \ - public: \ - static constexpr s32 ThreadPriority = prio; \ - static constexpr size_t StackSize = ss; \ - alignas(os::ThreadStackAlignment) static inline u8 Stack[StackSize]; \ - public: \ - static void ThreadFunction(void *); \ + #define DEFINE_MITM_MODULE_CLASS(ss, prio) class MitmModule { \ + public: \ + static constexpr s32 ThreadPriority = prio; \ + static constexpr size_t StackSize = ss; \ + alignas(os::ThreadStackAlignment) static inline u8 Stack[StackSize]; \ + public: \ + static void ThreadFunction(void *); \ } - template + template requires IsModule struct ModuleTraits { - static_assert(std::is_base_of::value, "Mitm Modules must inherit from ams::mitm::Module"); - static constexpr void *Stack = &M::Stack[0]; static constexpr size_t StackSize = M::StackSize; diff --git a/stratosphere/ams_mitm/source/amsmitm_module_management.cpp b/stratosphere/ams_mitm/source/amsmitm_module_management.cpp index e139c557a..ffa792fb9 100644 --- a/stratosphere/ams_mitm/source/amsmitm_module_management.cpp +++ b/stratosphere/ams_mitm/source/amsmitm_module_management.cpp @@ -54,7 +54,7 @@ namespace ams::mitm { .main = Traits::ThreadFunction, .stack_mem = Traits::Stack, .priority = Traits::ThreadPriority, - .stack_size = Traits::StackSize, + .stack_size = static_cast(Traits::StackSize), }; } diff --git a/stratosphere/pgl/source/pgl_main.cpp b/stratosphere/pgl/source/pgl_main.cpp index 03a75f246..bd56bebc1 100644 --- a/stratosphere/pgl/source/pgl_main.cpp +++ b/stratosphere/pgl/source/pgl_main.cpp @@ -64,7 +64,7 @@ namespace ams::pgl { constexpr sm::ServiceName ShellServiceName = sm::ServiceName::Encode("pgl"); constexpr size_t ShellMaxSessions = 8; /* Official maximum is 8. */ - /* TODO: C++20 constinit */ pgl::srv::ShellInterface g_shell_interface; + constinit pgl::srv::ShellInterface g_shell_interface; ALWAYS_INLINE std::shared_ptr GetSharedPointerToShellInterface() { return ams::sf::ServiceObjectTraits::SharedPointerHelper::GetEmptyDeleteSharedPointer(std::addressof(g_shell_interface));