diff --git a/libraries/libstratosphere/include/stratosphere/ddsf/ddsf_device_code_entry.hpp b/libraries/libstratosphere/include/stratosphere/ddsf/ddsf_device_code_entry.hpp index 6b49706ea..df82b6445 100644 --- a/libraries/libstratosphere/include/stratosphere/ddsf/ddsf_device_code_entry.hpp +++ b/libraries/libstratosphere/include/stratosphere/ddsf/ddsf_device_code_entry.hpp @@ -52,9 +52,9 @@ namespace ams::ddsf { util::TypedStorage m_entry_storage; bool m_is_constructed; public: - using ListTraits = util::IntrusiveListMemberTraitsDeferredAssert<&DeviceCodeEntryHolder::m_list_node>; + using ListTraits = util::IntrusiveListMemberTraits<&DeviceCodeEntryHolder::m_list_node>; using List = typename ListTraits::ListType; - friend class util::IntrusiveList>; + friend class util::IntrusiveList>; public: DeviceCodeEntryHolder() : m_list_node(), m_entry_storage(), m_is_constructed(false) { /* ... */ @@ -105,6 +105,5 @@ namespace ams::ddsf { return GetReference(m_entry_storage); } }; - static_assert(DeviceCodeEntryHolder::ListTraits::IsValid()); } diff --git a/libraries/libstratosphere/include/stratosphere/ddsf/ddsf_i_device.hpp b/libraries/libstratosphere/include/stratosphere/ddsf/ddsf_i_device.hpp index 1eeb99775..0bd8d7b2d 100644 --- a/libraries/libstratosphere/include/stratosphere/ddsf/ddsf_i_device.hpp +++ b/libraries/libstratosphere/include/stratosphere/ddsf/ddsf_i_device.hpp @@ -38,9 +38,9 @@ namespace ams::ddsf { mutable os::SdkMutex m_session_list_lock; bool m_is_exclusive_write; public: - using ListTraits = util::IntrusiveListMemberTraitsDeferredAssert<&IDevice::m_list_node>; + using ListTraits = util::IntrusiveListMemberTraits<&IDevice::m_list_node>; using List = typename ListTraits::ListType; - friend class util::IntrusiveList>; + friend class util::IntrusiveList>; private: Result AttachSession(ISession *session) { AMS_ASSERT(session != nullptr); @@ -135,6 +135,5 @@ namespace ams::ddsf { return !m_session_list.empty(); } }; - static_assert(IDevice::ListTraits::IsValid()); } diff --git a/libraries/libstratosphere/include/stratosphere/ddsf/ddsf_i_driver.hpp b/libraries/libstratosphere/include/stratosphere/ddsf/ddsf_i_driver.hpp index f1feef57a..ace3266a4 100644 --- a/libraries/libstratosphere/include/stratosphere/ddsf/ddsf_i_driver.hpp +++ b/libraries/libstratosphere/include/stratosphere/ddsf/ddsf_i_driver.hpp @@ -31,9 +31,9 @@ namespace ams::ddsf { IDevice::List m_device_list; mutable os::SdkMutex m_device_list_lock; public: - using ListTraits = util::IntrusiveListMemberTraitsDeferredAssert<&IDriver::m_list_node>; + using ListTraits = util::IntrusiveListMemberTraits<&IDriver::m_list_node>; using List = typename ListTraits::ListType; - friend class util::IntrusiveList>; + friend class util::IntrusiveList>; private: public: IDriver() : m_list_node(), m_device_list(), m_device_list_lock() { @@ -94,6 +94,5 @@ namespace ams::ddsf { return impl::ForEach(m_device_list_lock, m_device_list, f); } }; - static_assert(IDriver::ListTraits::IsValid()); } diff --git a/libraries/libstratosphere/include/stratosphere/ddsf/ddsf_i_session.hpp b/libraries/libstratosphere/include/stratosphere/ddsf/ddsf_i_session.hpp index 5705b6f85..b5ade44c1 100644 --- a/libraries/libstratosphere/include/stratosphere/ddsf/ddsf_i_session.hpp +++ b/libraries/libstratosphere/include/stratosphere/ddsf/ddsf_i_session.hpp @@ -37,9 +37,9 @@ namespace ams::ddsf { IDevice *m_device; AccessMode m_access_mode; public: - using ListTraits = util::IntrusiveListMemberTraitsDeferredAssert<&ISession::m_list_node>; + using ListTraits = util::IntrusiveListMemberTraits<&ISession::m_list_node>; using List = typename ListTraits::ListType; - friend class util::IntrusiveList>; + friend class util::IntrusiveList>; private: void AttachDevice(IDevice *dev, AccessMode mode) { AMS_ASSERT(dev != nullptr); @@ -95,6 +95,5 @@ namespace ams::ddsf { return this->CheckAccess(AccessMode_Write) && !this->CheckAccess(AccessMode_Shared); } }; - static_assert(ISession::ListTraits::IsValid()); } diff --git a/libraries/libstratosphere/include/stratosphere/i2c/driver/i2c_i2c_device_property.hpp b/libraries/libstratosphere/include/stratosphere/i2c/driver/i2c_i2c_device_property.hpp index 53d9bedfc..43ab1f650 100644 --- a/libraries/libstratosphere/include/stratosphere/i2c/driver/i2c_i2c_device_property.hpp +++ b/libraries/libstratosphere/include/stratosphere/i2c/driver/i2c_i2c_device_property.hpp @@ -29,9 +29,9 @@ namespace ams::i2c::driver { AddressingMode m_addressing_mode; util::IntrusiveListNode m_device_property_list_node; public: - using DevicePropertyListTraits = util::IntrusiveListMemberTraitsDeferredAssert<&I2cDeviceProperty::m_device_property_list_node>; + using DevicePropertyListTraits = util::IntrusiveListMemberTraits<&I2cDeviceProperty::m_device_property_list_node>; using DevicePropertyList = typename DevicePropertyListTraits::ListType; - friend class util::IntrusiveList>; + friend class util::IntrusiveList>; public: I2cDeviceProperty() : IDevice(false), m_address(0), m_addressing_mode(AddressingMode_SevenBit), m_device_property_list_node() { /* ... */ } I2cDeviceProperty(u16 addr, AddressingMode m) : IDevice(false), m_address(addr), m_addressing_mode(m), m_device_property_list_node() { /* ... */ } diff --git a/libraries/libstratosphere/include/stratosphere/lmem/impl/lmem_impl_common.hpp b/libraries/libstratosphere/include/stratosphere/lmem/impl/lmem_impl_common.hpp index 16522f938..00ce87537 100644 --- a/libraries/libstratosphere/include/stratosphere/lmem/impl/lmem_impl_common.hpp +++ b/libraries/libstratosphere/include/stratosphere/lmem/impl/lmem_impl_common.hpp @@ -79,7 +79,7 @@ namespace ams::lmem::impl { u32 magic; util::IntrusiveListNode list_node; - using ChildListTraits = util::IntrusiveListMemberTraitsDeferredAssert<&HeapHead::list_node>; + using ChildListTraits = util::IntrusiveListMemberTraits<&HeapHead::list_node>; using ChildList = ChildListTraits::ListType; ChildList child_list; @@ -90,6 +90,5 @@ namespace ams::lmem::impl { ImplementationHeapHead impl_head; }; static_assert(std::is_trivially_destructible::value); - static_assert(HeapHead::ChildListTraits::IsValid()); } diff --git a/libraries/libstratosphere/source/gpio/driver/board/nintendo/nx/impl/gpio_tegra_pad.hpp b/libraries/libstratosphere/source/gpio/driver/board/nintendo/nx/impl/gpio_tegra_pad.hpp index 51d1a72a3..d39b4a98c 100644 --- a/libraries/libstratosphere/source/gpio/driver/board/nintendo/nx/impl/gpio_tegra_pad.hpp +++ b/libraries/libstratosphere/source/gpio/driver/board/nintendo/nx/impl/gpio_tegra_pad.hpp @@ -355,9 +355,9 @@ namespace ams::gpio::driver::board::nintendo::nx::impl { PadInfo m_info; PadStatus m_status; public: - using InterruptListTraits = util::IntrusiveListMemberTraitsDeferredAssert<&TegraPad::m_interrupt_list_node>; + using InterruptListTraits = util::IntrusiveListMemberTraits<&TegraPad::m_interrupt_list_node>; using InterruptList = typename InterruptListTraits::ListType; - friend class util::IntrusiveList>; + friend class util::IntrusiveList>; public: TegraPad() : Pad(), m_interrupt_list_node(), m_info(), m_status() { /* ... */ } diff --git a/libraries/libstratosphere/source/i2c/driver/board/nintendo/nx/impl/i2c_bus_accessor.hpp b/libraries/libstratosphere/source/i2c/driver/board/nintendo/nx/impl/i2c_bus_accessor.hpp index d40e69bab..f2c4453d5 100644 --- a/libraries/libstratosphere/source/i2c/driver/board/nintendo/nx/impl/i2c_bus_accessor.hpp +++ b/libraries/libstratosphere/source/i2c/driver/board/nintendo/nx/impl/i2c_bus_accessor.hpp @@ -54,9 +54,9 @@ namespace ams::i2c::driver::board::nintendo::nx::impl { DeviceCode m_device_code; util::IntrusiveListNode m_bus_accessor_list_node; public: - using BusAccessorListTraits = util::IntrusiveListMemberTraitsDeferredAssert<&I2cBusAccessor::m_bus_accessor_list_node>; + using BusAccessorListTraits = util::IntrusiveListMemberTraits<&I2cBusAccessor::m_bus_accessor_list_node>; using BusAccessorList = typename BusAccessorListTraits::ListType; - friend class util::IntrusiveList>; + friend class util::IntrusiveList>; public: I2cBusAccessor() : m_registers(nullptr), m_speed_mode(SpeedMode_Fast), m_user_count(0), m_user_count_mutex(), diff --git a/libraries/libstratosphere/source/lmem/impl/lmem_impl_exp_heap.cpp b/libraries/libstratosphere/source/lmem/impl/lmem_impl_exp_heap.cpp index 0da7a0663..21b5d1189 100644 --- a/libraries/libstratosphere/source/lmem/impl/lmem_impl_exp_heap.cpp +++ b/libraries/libstratosphere/source/lmem/impl/lmem_impl_exp_heap.cpp @@ -38,51 +38,51 @@ namespace ams::lmem::impl { void *end; }; - constexpr inline bool IsValidHeapHandle(HeapHandle handle) { + inline bool IsValidHeapHandle(HeapHandle handle) { return handle->magic == ExpHeapMagic; } - constexpr inline ExpHeapHead *GetExpHeapHead(HeapHead *heap_head) { + inline ExpHeapHead *GetExpHeapHead(HeapHead *heap_head) { return std::addressof(heap_head->impl_head.exp_heap_head); } - constexpr inline const ExpHeapHead *GetExpHeapHead(const HeapHead *heap_head) { + inline const ExpHeapHead *GetExpHeapHead(const HeapHead *heap_head) { return std::addressof(heap_head->impl_head.exp_heap_head); } - constexpr inline HeapHead *GetHeapHead(ExpHeapHead *exp_heap_head) { + inline HeapHead *GetHeapHead(ExpHeapHead *exp_heap_head) { return util::GetParentPointer<&HeapHead::impl_head>(util::GetParentPointer<&ImplementationHeapHead::exp_heap_head>(exp_heap_head)); } - constexpr inline const HeapHead *GetHeapHead(const ExpHeapHead *exp_heap_head) { + inline const HeapHead *GetHeapHead(const ExpHeapHead *exp_heap_head) { return util::GetParentPointer<&HeapHead::impl_head>(util::GetParentPointer<&ImplementationHeapHead::exp_heap_head>(exp_heap_head)); } - constexpr inline void *GetExpHeapMemoryStart(ExpHeapHead *exp_heap_head) { + inline void *GetExpHeapMemoryStart(ExpHeapHead *exp_heap_head) { return reinterpret_cast(reinterpret_cast(exp_heap_head) + sizeof(ImplementationHeapHead)); } - constexpr inline void *GetMemoryBlockStart(ExpHeapMemoryBlockHead *head) { + inline void *GetMemoryBlockStart(ExpHeapMemoryBlockHead *head) { return reinterpret_cast(reinterpret_cast(head) + sizeof(*head)); } - constexpr inline const void *GetMemoryBlockStart(const ExpHeapMemoryBlockHead *head) { + inline const void *GetMemoryBlockStart(const ExpHeapMemoryBlockHead *head) { return reinterpret_cast(reinterpret_cast(head) + sizeof(*head)); } - constexpr inline void *GetMemoryBlockEnd(ExpHeapMemoryBlockHead *head) { + inline void *GetMemoryBlockEnd(ExpHeapMemoryBlockHead *head) { return reinterpret_cast(reinterpret_cast(GetMemoryBlockStart(head)) + head->block_size); } - constexpr inline const void *GetMemoryBlockEnd(const ExpHeapMemoryBlockHead *head) { + inline const void *GetMemoryBlockEnd(const ExpHeapMemoryBlockHead *head) { return reinterpret_cast(reinterpret_cast(GetMemoryBlockStart(head)) + head->block_size); } - constexpr inline ExpHeapMemoryBlockHead *GetHeadForMemoryBlock(const void *block) { + inline ExpHeapMemoryBlockHead *GetHeadForMemoryBlock(const void *block) { return reinterpret_cast(reinterpret_cast(block) - sizeof(ExpHeapMemoryBlockHead)); } - constexpr inline bool IsValidUsedMemoryBlock(const HeapHead *heap, const void *block) { + inline bool IsValidUsedMemoryBlock(const HeapHead *heap, const void *block) { /* Block must fall within the heap range. */ if (heap != nullptr) { if (block < heap->heap_start || heap->heap_end <= block) { @@ -106,7 +106,7 @@ namespace ams::lmem::impl { return true; } - constexpr inline u16 GetMemoryBlockAlignmentPadding(const ExpHeapMemoryBlockHead *block_head) { + inline u16 GetMemoryBlockAlignmentPadding(const ExpHeapMemoryBlockHead *block_head) { return static_cast((block_head->attributes >> 8) & 0x7F); } @@ -115,7 +115,7 @@ namespace ams::lmem::impl { block_head->attributes |= static_castattributes)>(padding & 0x7F) << 8; } - constexpr inline u16 GetMemoryBlockGroupId(const ExpHeapMemoryBlockHead *block_head) { + inline u16 GetMemoryBlockGroupId(const ExpHeapMemoryBlockHead *block_head) { return static_cast(block_head->attributes & 0xFF); } @@ -124,7 +124,7 @@ namespace ams::lmem::impl { block_head->attributes |= static_castattributes)>(group_id & 0xFF); } - constexpr inline AllocationDirection GetMemoryBlockAllocationDirection(const ExpHeapMemoryBlockHead *block_head) { + inline AllocationDirection GetMemoryBlockAllocationDirection(const ExpHeapMemoryBlockHead *block_head) { return static_cast((block_head->attributes >> 15) & 1); } @@ -138,7 +138,7 @@ namespace ams::lmem::impl { out->end = GetMemoryBlockEnd(head); } - constexpr inline AllocationMode GetAllocationModeImpl(const ExpHeapHead *head) { + inline AllocationMode GetAllocationModeImpl(const ExpHeapHead *head) { return static_cast(head->mode); } diff --git a/libraries/libstratosphere/source/os/impl/os_multiple_wait_impl.hpp b/libraries/libstratosphere/source/os/impl/os_multiple_wait_impl.hpp index a6fa60815..6afa41376 100644 --- a/libraries/libstratosphere/source/os/impl/os_multiple_wait_impl.hpp +++ b/libraries/libstratosphere/source/os/impl/os_multiple_wait_impl.hpp @@ -30,7 +30,7 @@ namespace ams::os::impl { static constexpr s32 WaitInvalid = -3; static constexpr s32 WaitCancelled = -2; static constexpr s32 WaitTimedOut = -1; - using MultiWaitList = util::IntrusiveListMemberTraits<&MultiWaitHolderBase::m_multi_wait_node>::ListType; + using MultiWaitList = util::IntrusiveListMemberTraitsByNonConstexprOffsetOf<&MultiWaitHolderBase::m_multi_wait_node>::ListType; private: MultiWaitList m_multi_wait_list; MultiWaitHolderBase *m_signaled_holder; diff --git a/libraries/libstratosphere/source/os/impl/os_multiple_wait_object_list.hpp b/libraries/libstratosphere/source/os/impl/os_multiple_wait_object_list.hpp index cd493a365..7284f5863 100644 --- a/libraries/libstratosphere/source/os/impl/os_multiple_wait_object_list.hpp +++ b/libraries/libstratosphere/source/os/impl/os_multiple_wait_object_list.hpp @@ -21,7 +21,7 @@ namespace ams::os::impl { class MultiWaitObjectList { public: - using ListType = util::IntrusiveListMemberTraits<&MultiWaitHolderBase::m_object_list_node>::ListType; + using ListType = util::IntrusiveListMemberTraitsByNonConstexprOffsetOf<&MultiWaitHolderBase::m_object_list_node>::ListType; private: ListType m_object_list; public: diff --git a/libraries/libstratosphere/source/os/impl/os_thread_manager_types.hpp b/libraries/libstratosphere/source/os/impl/os_thread_manager_types.hpp index 39285e34f..e4de4b738 100644 --- a/libraries/libstratosphere/source/os/impl/os_thread_manager_types.hpp +++ b/libraries/libstratosphere/source/os/impl/os_thread_manager_types.hpp @@ -34,20 +34,22 @@ namespace ams::os::impl { private: friend class util::IntrusiveList; - static constexpr util::IntrusiveListNode &GetNode(ThreadType &parent) { + static util::IntrusiveListNode &GetNode(ThreadType &parent) { return GetReference(parent.all_threads_node); } - static constexpr util::IntrusiveListNode const &GetNode(ThreadType const &parent) { + static util::IntrusiveListNode const &GetNode(ThreadType const &parent) { return GetReference(parent.all_threads_node); } + static constexpr size_t Offset = OFFSETOF(ThreadType, all_threads_node); + static ThreadType &GetParent(util::IntrusiveListNode &node) { - return *reinterpret_cast(reinterpret_cast(std::addressof(node)) - OFFSETOF(ThreadType, all_threads_node)); + return *reinterpret_cast(reinterpret_cast(std::addressof(node)) - Offset); } static ThreadType const &GetParent(util::IntrusiveListNode const &node) { - return *reinterpret_cast(reinterpret_cast(std::addressof(node)) - OFFSETOF(ThreadType, all_threads_node)); + return *reinterpret_cast(reinterpret_cast(std::addressof(node)) - Offset); } }; diff --git a/libraries/libvapours/include/vapours/util/util_intrusive_list.hpp b/libraries/libvapours/include/vapours/util/util_intrusive_list.hpp index 5438d9dfe..5d9576430 100644 --- a/libraries/libvapours/include/vapours/util/util_intrusive_list.hpp +++ b/libraries/libvapours/include/vapours/util/util_intrusive_list.hpp @@ -45,13 +45,13 @@ namespace ams::util { return m_next != this; } private: - ALWAYS_INLINE void LinkPrev(IntrusiveListNode *node) { + constexpr ALWAYS_INLINE void LinkPrev(IntrusiveListNode *node) { /* We can't link an already linked node. */ AMS_ASSERT(!node->IsLinked()); this->SplicePrev(node, node); } - ALWAYS_INLINE void SplicePrev(IntrusiveListNode *first, IntrusiveListNode *last) { + constexpr ALWAYS_INLINE void SplicePrev(IntrusiveListNode *first, IntrusiveListNode *last) { /* Splice a range into the list. */ auto last_prev = last->m_prev; first->m_prev = m_prev; @@ -60,13 +60,13 @@ namespace ams::util { m_prev = last_prev; } - ALWAYS_INLINE void LinkNext(IntrusiveListNode *node) { + constexpr ALWAYS_INLINE void LinkNext(IntrusiveListNode *node) { /* We can't link an already linked node. */ AMS_ASSERT(!node->IsLinked()); return this->SpliceNext(node, node); } - ALWAYS_INLINE void SpliceNext(IntrusiveListNode *first, IntrusiveListNode *last) { + constexpr ALWAYS_INLINE void SpliceNext(IntrusiveListNode *first, IntrusiveListNode *last) { /* Splice a range into the list. */ auto last_prev = last->m_prev; first->m_prev = this; @@ -75,11 +75,11 @@ namespace ams::util { m_next = first; } - ALWAYS_INLINE void Unlink() { + constexpr ALWAYS_INLINE void Unlink() { this->Unlink(m_next); } - ALWAYS_INLINE void Unlink(IntrusiveListNode *last) { + constexpr ALWAYS_INLINE void Unlink(IntrusiveListNode *last) { /* Unlink a node from a next node. */ auto last_prev = last->m_prev; m_prev->m_next = last; @@ -88,19 +88,19 @@ namespace ams::util { m_prev = last_prev; } - ALWAYS_INLINE IntrusiveListNode *GetPrev() { + constexpr ALWAYS_INLINE IntrusiveListNode *GetPrev() { return m_prev; } - ALWAYS_INLINE const IntrusiveListNode *GetPrev() const { + constexpr ALWAYS_INLINE const IntrusiveListNode *GetPrev() const { return m_prev; } - ALWAYS_INLINE IntrusiveListNode *GetNext() { + constexpr ALWAYS_INLINE IntrusiveListNode *GetNext() { return m_next; } - ALWAYS_INLINE const IntrusiveListNode *GetNext() const { + constexpr ALWAYS_INLINE const IntrusiveListNode *GetNext() const { return m_next; } }; @@ -139,51 +139,51 @@ namespace ams::util { private: pointer m_node; public: - ALWAYS_INLINE explicit Iterator(pointer n) : m_node(n) { /* ... */ } + constexpr ALWAYS_INLINE explicit Iterator(pointer n) : m_node(n) { /* ... */ } - ALWAYS_INLINE bool operator==(const Iterator &rhs) const { + constexpr ALWAYS_INLINE bool operator==(const Iterator &rhs) const { return m_node == rhs.m_node; } - ALWAYS_INLINE bool operator!=(const Iterator &rhs) const { + constexpr ALWAYS_INLINE bool operator!=(const Iterator &rhs) const { return !(*this == rhs); } - ALWAYS_INLINE pointer operator->() const { + constexpr ALWAYS_INLINE pointer operator->() const { return m_node; } - ALWAYS_INLINE reference operator*() const { + constexpr ALWAYS_INLINE reference operator*() const { return *m_node; } - ALWAYS_INLINE Iterator &operator++() { + constexpr ALWAYS_INLINE Iterator &operator++() { m_node = m_node->m_next; return *this; } - ALWAYS_INLINE Iterator &operator--() { + constexpr ALWAYS_INLINE Iterator &operator--() { m_node = m_node->m_prev; return *this; } - ALWAYS_INLINE Iterator operator++(int) { + constexpr ALWAYS_INLINE Iterator operator++(int) { const Iterator it{*this}; ++(*this); return it; } - ALWAYS_INLINE Iterator operator--(int) { + constexpr ALWAYS_INLINE Iterator operator--(int) { const Iterator it{*this}; --(*this); return it; } - ALWAYS_INLINE operator Iterator() const { + constexpr ALWAYS_INLINE operator Iterator() const { return Iterator(m_node); } - ALWAYS_INLINE Iterator GetNonConstIterator() const { + constexpr ALWAYS_INLINE Iterator GetNonConstIterator() const { return Iterator(const_cast(m_node)); } }; @@ -191,97 +191,97 @@ namespace ams::util { constexpr ALWAYS_INLINE IntrusiveListImpl() : m_root_node() { /* ... */ } /* Iterator accessors. */ - ALWAYS_INLINE iterator begin() { + constexpr ALWAYS_INLINE iterator begin() { return iterator(m_root_node.GetNext()); } - ALWAYS_INLINE const_iterator begin() const { + constexpr ALWAYS_INLINE const_iterator begin() const { return const_iterator(m_root_node.GetNext()); } - ALWAYS_INLINE iterator end() { + constexpr ALWAYS_INLINE iterator end() { return iterator(std::addressof(m_root_node)); } - ALWAYS_INLINE const_iterator end() const { + constexpr ALWAYS_INLINE const_iterator end() const { return const_iterator(std::addressof(m_root_node)); } - ALWAYS_INLINE iterator iterator_to(reference v) { + constexpr ALWAYS_INLINE iterator iterator_to(reference v) { /* Only allow iterator_to for values in lists. */ AMS_ASSERT(v.IsLinked()); return iterator(std::addressof(v)); } - ALWAYS_INLINE const_iterator iterator_to(const_reference v) const { + constexpr ALWAYS_INLINE const_iterator iterator_to(const_reference v) const { /* Only allow iterator_to for values in lists. */ AMS_ASSERT(v.IsLinked()); return const_iterator(std::addressof(v)); } /* Content management. */ - ALWAYS_INLINE bool empty() const { + constexpr ALWAYS_INLINE bool empty() const { return !m_root_node.IsLinked(); } - ALWAYS_INLINE size_type size() const { + constexpr ALWAYS_INLINE size_type size() const { return static_cast(std::distance(this->begin(), this->end())); } - ALWAYS_INLINE reference back() { + constexpr ALWAYS_INLINE reference back() { return *m_root_node.GetPrev(); } - ALWAYS_INLINE const_reference back() const { + constexpr ALWAYS_INLINE const_reference back() const { return *m_root_node.GetPrev(); } - ALWAYS_INLINE reference front() { + constexpr ALWAYS_INLINE reference front() { return *m_root_node.GetNext(); } - ALWAYS_INLINE const_reference front() const { + constexpr ALWAYS_INLINE const_reference front() const { return *m_root_node.GetNext(); } - ALWAYS_INLINE void push_back(reference node) { + constexpr ALWAYS_INLINE void push_back(reference node) { m_root_node.LinkPrev(std::addressof(node)); } - ALWAYS_INLINE void push_front(reference node) { + constexpr ALWAYS_INLINE void push_front(reference node) { m_root_node.LinkNext(std::addressof(node)); } - ALWAYS_INLINE void pop_back() { + constexpr ALWAYS_INLINE void pop_back() { m_root_node.GetPrev()->Unlink(); } - ALWAYS_INLINE void pop_front() { + constexpr ALWAYS_INLINE void pop_front() { m_root_node.GetNext()->Unlink(); } - ALWAYS_INLINE iterator insert(const_iterator pos, reference node) { + constexpr ALWAYS_INLINE iterator insert(const_iterator pos, reference node) { pos.GetNonConstIterator()->LinkPrev(std::addressof(node)); return iterator(std::addressof(node)); } - ALWAYS_INLINE void splice(const_iterator pos, IntrusiveListImpl &o) { + constexpr ALWAYS_INLINE void splice(const_iterator pos, IntrusiveListImpl &o) { splice_impl(pos, o.begin(), o.end()); } - ALWAYS_INLINE void splice(const_iterator pos, IntrusiveListImpl &o, const_iterator first) { + constexpr ALWAYS_INLINE void splice(const_iterator pos, IntrusiveListImpl &o, const_iterator first) { AMS_UNUSED(o); const_iterator last(first); std::advance(last, 1); splice_impl(pos, first, last); } - ALWAYS_INLINE void splice(const_iterator pos, IntrusiveListImpl &o, const_iterator first, const_iterator last) { + constexpr ALWAYS_INLINE void splice(const_iterator pos, IntrusiveListImpl &o, const_iterator first, const_iterator last) { AMS_UNUSED(o); splice_impl(pos, first, last); } - ALWAYS_INLINE iterator erase(const_iterator pos) { + constexpr ALWAYS_INLINE iterator erase(const_iterator pos) { if (pos == this->end()) { return this->end(); } @@ -290,13 +290,13 @@ namespace ams::util { return it; } - ALWAYS_INLINE void clear() { + constexpr ALWAYS_INLINE void clear() { while (!this->empty()) { this->pop_front(); } } private: - ALWAYS_INLINE void splice_impl(const_iterator _pos, const_iterator _first, const_iterator _last) { + constexpr ALWAYS_INLINE void splice_impl(const_iterator _pos, const_iterator _first, const_iterator _last) { if (_first == _last) { return; } @@ -306,7 +306,6 @@ namespace ams::util { first->Unlink(std::addressof(*last)); pos->SplicePrev(std::addressof(*first), std::addressof(*first)); } - }; } @@ -347,51 +346,51 @@ namespace ams::util { private: ImplIterator m_iterator; private: - explicit ALWAYS_INLINE Iterator(ImplIterator it) : m_iterator(it) { /* ... */ } + constexpr explicit ALWAYS_INLINE Iterator(ImplIterator it) : m_iterator(it) { /* ... */ } - ALWAYS_INLINE ImplIterator GetImplIterator() const { + constexpr ALWAYS_INLINE ImplIterator GetImplIterator() const { return m_iterator; } public: - ALWAYS_INLINE bool operator==(const Iterator &rhs) const { + constexpr ALWAYS_INLINE bool operator==(const Iterator &rhs) const { return m_iterator == rhs.m_iterator; } - ALWAYS_INLINE bool operator!=(const Iterator &rhs) const { + constexpr ALWAYS_INLINE bool operator!=(const Iterator &rhs) const { return !(*this == rhs); } - ALWAYS_INLINE pointer operator->() const { + constexpr ALWAYS_INLINE pointer operator->() const { return std::addressof(Traits::GetParent(*m_iterator)); } - ALWAYS_INLINE reference operator*() const { + constexpr ALWAYS_INLINE reference operator*() const { return Traits::GetParent(*m_iterator); } - ALWAYS_INLINE Iterator &operator++() { + constexpr ALWAYS_INLINE Iterator &operator++() { ++m_iterator; return *this; } - ALWAYS_INLINE Iterator &operator--() { + constexpr ALWAYS_INLINE Iterator &operator--() { --m_iterator; return *this; } - ALWAYS_INLINE Iterator operator++(int) { + constexpr ALWAYS_INLINE Iterator operator++(int) { const Iterator it{*this}; ++m_iterator; return it; } - ALWAYS_INLINE Iterator operator--(int) { + constexpr ALWAYS_INLINE Iterator operator--(int) { const Iterator it{*this}; --m_iterator; return it; } - ALWAYS_INLINE operator Iterator() const { + constexpr ALWAYS_INLINE operator Iterator() const { return Iterator(m_iterator); } }; @@ -415,130 +414,130 @@ namespace ams::util { constexpr ALWAYS_INLINE IntrusiveList() : m_impl() { /* ... */ } /* Iterator accessors. */ - ALWAYS_INLINE iterator begin() { + constexpr ALWAYS_INLINE iterator begin() { return iterator(m_impl.begin()); } - ALWAYS_INLINE const_iterator begin() const { + constexpr ALWAYS_INLINE const_iterator begin() const { return const_iterator(m_impl.begin()); } - ALWAYS_INLINE iterator end() { + constexpr ALWAYS_INLINE iterator end() { return iterator(m_impl.end()); } - ALWAYS_INLINE const_iterator end() const { + constexpr ALWAYS_INLINE const_iterator end() const { return const_iterator(m_impl.end()); } - ALWAYS_INLINE const_iterator cbegin() const { + constexpr ALWAYS_INLINE const_iterator cbegin() const { return this->begin(); } - ALWAYS_INLINE const_iterator cend() const { + constexpr ALWAYS_INLINE const_iterator cend() const { return this->end(); } - ALWAYS_INLINE reverse_iterator rbegin() { + constexpr ALWAYS_INLINE reverse_iterator rbegin() { return reverse_iterator(this->end()); } - ALWAYS_INLINE const_reverse_iterator rbegin() const { + constexpr ALWAYS_INLINE const_reverse_iterator rbegin() const { return const_reverse_iterator(this->end()); } - ALWAYS_INLINE reverse_iterator rend() { + constexpr ALWAYS_INLINE reverse_iterator rend() { return reverse_iterator(this->begin()); } - ALWAYS_INLINE const_reverse_iterator rend() const { + constexpr ALWAYS_INLINE const_reverse_iterator rend() const { return const_reverse_iterator(this->begin()); } - ALWAYS_INLINE const_reverse_iterator crbegin() const { + constexpr ALWAYS_INLINE const_reverse_iterator crbegin() const { return this->rbegin(); } - ALWAYS_INLINE const_reverse_iterator crend() const { + constexpr ALWAYS_INLINE const_reverse_iterator crend() const { return this->rend(); } - ALWAYS_INLINE iterator iterator_to(reference v) { + constexpr ALWAYS_INLINE iterator iterator_to(reference v) { return iterator(m_impl.iterator_to(GetNode(v))); } - ALWAYS_INLINE const_iterator iterator_to(const_reference v) const { + constexpr ALWAYS_INLINE const_iterator iterator_to(const_reference v) const { return const_iterator(m_impl.iterator_to(GetNode(v))); } /* Content management. */ - ALWAYS_INLINE bool empty() const { + constexpr ALWAYS_INLINE bool empty() const { return m_impl.empty(); } - ALWAYS_INLINE size_type size() const { + constexpr ALWAYS_INLINE size_type size() const { return m_impl.size(); } - ALWAYS_INLINE reference back() { + constexpr ALWAYS_INLINE reference back() { AMS_ASSERT(!m_impl.empty()); return GetParent(m_impl.back()); } - ALWAYS_INLINE const_reference back() const { + constexpr ALWAYS_INLINE const_reference back() const { AMS_ASSERT(!m_impl.empty()); return GetParent(m_impl.back()); } - ALWAYS_INLINE reference front() { + constexpr ALWAYS_INLINE reference front() { AMS_ASSERT(!m_impl.empty()); return GetParent(m_impl.front()); } - ALWAYS_INLINE const_reference front() const { + constexpr ALWAYS_INLINE const_reference front() const { AMS_ASSERT(!m_impl.empty()); return GetParent(m_impl.front()); } - ALWAYS_INLINE void push_back(reference ref) { + constexpr ALWAYS_INLINE void push_back(reference ref) { m_impl.push_back(GetNode(ref)); } - ALWAYS_INLINE void push_front(reference ref) { + constexpr ALWAYS_INLINE void push_front(reference ref) { m_impl.push_front(GetNode(ref)); } - ALWAYS_INLINE void pop_back() { + constexpr ALWAYS_INLINE void pop_back() { AMS_ASSERT(!m_impl.empty()); m_impl.pop_back(); } - ALWAYS_INLINE void pop_front() { + constexpr ALWAYS_INLINE void pop_front() { AMS_ASSERT(!m_impl.empty()); m_impl.pop_front(); } - ALWAYS_INLINE iterator insert(const_iterator pos, reference ref) { + constexpr ALWAYS_INLINE iterator insert(const_iterator pos, reference ref) { return iterator(m_impl.insert(pos.GetImplIterator(), GetNode(ref))); } - ALWAYS_INLINE void splice(const_iterator pos, IntrusiveList &o) { + constexpr ALWAYS_INLINE void splice(const_iterator pos, IntrusiveList &o) { m_impl.splice(pos.GetImplIterator(), o.m_impl); } - ALWAYS_INLINE void splice(const_iterator pos, IntrusiveList &o, const_iterator first) { + constexpr ALWAYS_INLINE void splice(const_iterator pos, IntrusiveList &o, const_iterator first) { m_impl.splice(pos.GetImplIterator(), o.m_impl, first.GetImplIterator()); } - ALWAYS_INLINE void splice(const_iterator pos, IntrusiveList &o, const_iterator first, const_iterator last) { + constexpr ALWAYS_INLINE void splice(const_iterator pos, IntrusiveList &o, const_iterator first, const_iterator last) { m_impl.splice(pos.GetImplIterator(), o.m_impl, first.GetImplIterator(), last.GetImplIterator()); } - ALWAYS_INLINE iterator erase(const_iterator pos) { + constexpr ALWAYS_INLINE iterator erase(const_iterator pos) { return iterator(m_impl.erase(pos.GetImplIterator())); } - ALWAYS_INLINE void clear() { + constexpr ALWAYS_INLINE void clear() { m_impl.clear(); } }; @@ -561,32 +560,24 @@ namespace ams::util { return parent.*Member; } - static constexpr ALWAYS_INLINE Derived &GetParent(IntrusiveListNode &node) { + static ALWAYS_INLINE Derived &GetParent(IntrusiveListNode &node) { return util::GetParentReference(std::addressof(node)); } - static constexpr ALWAYS_INLINE Derived const &GetParent(IntrusiveListNode const &node) { + static ALWAYS_INLINE Derived const &GetParent(IntrusiveListNode const &node) { return util::GetParentReference(std::addressof(node)); } - private: - static constexpr TypedStorage DerivedStorage = {}; - static_assert(std::addressof(GetParent(GetNode(GetReference(DerivedStorage)))) == GetPointer(DerivedStorage)); }; template> - class IntrusiveListMemberTraitsDeferredAssert; + class IntrusiveListMemberTraitsByNonConstexprOffsetOf; template - class IntrusiveListMemberTraitsDeferredAssert { + class IntrusiveListMemberTraitsByNonConstexprOffsetOf { public: - using ListType = IntrusiveList; - - static constexpr bool IsValid() { - TypedStorage DerivedStorage = {}; - return std::addressof(GetParent(GetNode(GetReference(DerivedStorage)))) == GetPointer(DerivedStorage); - } + using ListType = IntrusiveList; private: - friend class IntrusiveList; + friend class IntrusiveList; static constexpr ALWAYS_INLINE IntrusiveListNode &GetNode(Derived &parent) { return parent.*Member; @@ -596,12 +587,16 @@ namespace ams::util { return parent.*Member; } - static constexpr ALWAYS_INLINE Derived &GetParent(IntrusiveListNode &node) { - return util::GetParentReference(std::addressof(node)); + static ALWAYS_INLINE Derived &GetParent(IntrusiveListNode &node) { + return *reinterpret_cast(reinterpret_cast(std::addressof(node)) - GetOffset()); } - static constexpr ALWAYS_INLINE Derived const &GetParent(IntrusiveListNode const &node) { - return util::GetParentReference(std::addressof(node)); + static ALWAYS_INLINE Derived const &GetParent(IntrusiveListNode const &node) { + return *reinterpret_cast(reinterpret_cast(std::addressof(node)) - GetOffset()); + } + + static ALWAYS_INLINE uintptr_t GetOffset() { + return reinterpret_cast(std::addressof(reinterpret_cast(0)->*Member)); } }; @@ -616,19 +611,19 @@ namespace ams::util { friend class IntrusiveList; static constexpr ALWAYS_INLINE IntrusiveListNode &GetNode(Derived &parent) { - return static_cast(parent); + return static_cast(static_cast &>(parent)); } static constexpr ALWAYS_INLINE IntrusiveListNode const &GetNode(Derived const &parent) { - return static_cast(parent); + return static_cast(static_cast &>(parent)); } static constexpr ALWAYS_INLINE Derived &GetParent(IntrusiveListNode &node) { - return static_cast(node); + return static_cast(static_cast &>(node)); } static constexpr ALWAYS_INLINE Derived const &GetParent(IntrusiveListNode const &node) { - return static_cast(node); + return static_cast(static_cast &>(node)); } }; diff --git a/libraries/libvapours/include/vapours/util/util_intrusive_red_black_tree.hpp b/libraries/libvapours/include/vapours/util/util_intrusive_red_black_tree.hpp index e82e880fd..9eb5b23c5 100644 --- a/libraries/libvapours/include/vapours/util/util_intrusive_red_black_tree.hpp +++ b/libraries/libvapours/include/vapours/util/util_intrusive_red_black_tree.hpp @@ -494,17 +494,15 @@ namespace ams::util { return std::addressof(parent->*Member); } - static constexpr ALWAYS_INLINE Derived *GetParent(IntrusiveRedBlackTreeNode *node) { + static ALWAYS_INLINE Derived *GetParent(IntrusiveRedBlackTreeNode *node) { return util::GetParentPointer(node); } - static constexpr ALWAYS_INLINE Derived const *GetParent(IntrusiveRedBlackTreeNode const *node) { + static ALWAYS_INLINE Derived const *GetParent(IntrusiveRedBlackTreeNode const *node) { return util::GetParentPointer(node); } private: - static constexpr TypedStorage DerivedStorage = {}; - static_assert(GetParent(GetNode(GetPointer(DerivedStorage))) == GetPointer(DerivedStorage)); - static_assert(util::IsAligned(util::impl::OffsetOf, alignof(void *))); + static_assert(util::IsAligned(util::impl::OffsetOf::Value, alignof(void *))); }; template> @@ -518,8 +516,7 @@ namespace ams::util { using TreeTypeImpl = impl::IntrusiveRedBlackTreeImpl; static constexpr bool IsValid() { - TypedStorage DerivedStorage = {}; - return GetParent(GetNode(GetPointer(DerivedStorage))) == GetPointer(DerivedStorage) && util::IsAligned(util::impl::OffsetOf, alignof(void *)); + return util::IsAligned(util::impl::OffsetOf::Value, alignof(void *)); } private: template @@ -535,11 +532,11 @@ namespace ams::util { return std::addressof(parent->*Member); } - static constexpr ALWAYS_INLINE Derived *GetParent(IntrusiveRedBlackTreeNode *node) { + static ALWAYS_INLINE Derived *GetParent(IntrusiveRedBlackTreeNode *node) { return util::GetParentPointer(node); } - static constexpr ALWAYS_INLINE Derived const *GetParent(IntrusiveRedBlackTreeNode const *node) { + static ALWAYS_INLINE Derived const *GetParent(IntrusiveRedBlackTreeNode const *node) { return util::GetParentPointer(node); } }; @@ -547,14 +544,14 @@ namespace ams::util { template class alignas(void *) IntrusiveRedBlackTreeBaseNode : public IntrusiveRedBlackTreeNode { public: - constexpr ALWAYS_INLINE Derived *GetPrev() { return static_cast< Derived *>(impl::IntrusiveRedBlackTreeImpl::GetPrev(this)); } - constexpr ALWAYS_INLINE const Derived *GetPrev() const { return static_cast(impl::IntrusiveRedBlackTreeImpl::GetPrev(this)); } + constexpr ALWAYS_INLINE Derived *GetPrev() { return static_cast< Derived *>(static_cast< IntrusiveRedBlackTreeBaseNode *>(impl::IntrusiveRedBlackTreeImpl::GetPrev(this))); } + constexpr ALWAYS_INLINE const Derived *GetPrev() const { return static_cast(static_cast(impl::IntrusiveRedBlackTreeImpl::GetPrev(this))); } - constexpr ALWAYS_INLINE Derived *GetNext() { return static_cast< Derived *>(impl::IntrusiveRedBlackTreeImpl::GetNext(this)); } - constexpr ALWAYS_INLINE const Derived *GetNext() const { return static_cast(impl::IntrusiveRedBlackTreeImpl::GetNext(this)); } + constexpr ALWAYS_INLINE Derived *GetNext() { return static_cast< Derived *>(static_cast< IntrusiveRedBlackTreeBaseNode *>(impl::IntrusiveRedBlackTreeImpl::GetNext(this))); } + constexpr ALWAYS_INLINE const Derived *GetNext() const { return static_cast(static_cast(impl::IntrusiveRedBlackTreeImpl::GetNext(this))); } }; - template requires std::derived_from + template class IntrusiveRedBlackTreeBaseTraits { public: template @@ -567,19 +564,19 @@ namespace ams::util { friend class impl::IntrusiveRedBlackTreeImpl; static constexpr ALWAYS_INLINE IntrusiveRedBlackTreeNode *GetNode(Derived *parent) { - return static_cast(parent); + return static_cast(static_cast *>(parent)); } static constexpr ALWAYS_INLINE IntrusiveRedBlackTreeNode const *GetNode(Derived const *parent) { - return static_cast(parent); + return static_cast(static_cast *>(parent)); } static constexpr ALWAYS_INLINE Derived *GetParent(IntrusiveRedBlackTreeNode *node) { - return static_cast(node); + return static_cast(static_cast *>(node)); } static constexpr ALWAYS_INLINE Derived const *GetParent(IntrusiveRedBlackTreeNode const *node) { - return static_cast(node); + return static_cast(static_cast *>(node)); } }; diff --git a/libraries/libvapours/include/vapours/util/util_parent_of_member.hpp b/libraries/libvapours/include/vapours/util/util_parent_of_member.hpp index df5c93ab7..6a899a65d 100644 --- a/libraries/libvapours/include/vapours/util/util_parent_of_member.hpp +++ b/libraries/libvapours/include/vapours/util/util_parent_of_member.hpp @@ -43,16 +43,6 @@ namespace ams::util { UnionImpl next_union; }; - template - union UnionImpl { - static constexpr size_t GetOffset() { return 0; } - - struct { - MemberType members[(sizeof(ParentType) / sizeof(MemberType)) + 1]; - } data; - UnionImpl next_union; - }; - template union UnionImpl { /* Empty ... */ }; }; @@ -63,10 +53,11 @@ namespace ams::util { union Union { char c; UnionHolder first_union; - TypedStorage parent; + ParentType parent; /* This coerces the active member to be c. */ constexpr Union() : c() { /* ... */ } + constexpr ~Union() { std::destroy_at(std::addressof(c)); } }; static constexpr Union U = {}; @@ -84,7 +75,7 @@ namespace ams::util { template static constexpr std::ptrdiff_t OffsetOfImpl(MemberType ParentType::*member, CurUnion &cur_union) { constexpr size_t Offset = CurUnion::GetOffset(); - const auto target = std::addressof(GetPointer(U.parent)->*member); + const auto target = std::addressof(U.parent.*member); const auto start = std::addressof(cur_union.data.members[0]); const auto next = GetNextAddress(start, target); @@ -107,11 +98,20 @@ namespace ams::util { #else + template + union HelperUnion { + T v; + char c; + + constexpr HelperUnion() : c() { /* ... */ } + constexpr ~HelperUnion() { std::destroy_at(std::addressof(c)); } + }; + template struct OffsetOfCalculator { static constexpr std::ptrdiff_t OffsetOf(MemberType ParentType::*member) { - constexpr TypedStorage Holder = {}; - const auto *parent = GetPointer(Holder); + constexpr HelperUnion Holder = {}; + const auto *parent = std::addressof(Holder.v); const auto *target = std::addressof(parent->*member); return static_cast(static_cast(target)) - static_cast(static_cast(parent)); } @@ -134,141 +134,63 @@ namespace ams::util { template using GetMemberType = typename GetMemberPointerTraits::Member; - template> - constexpr inline std::ptrdiff_t OffsetOf = [] { - using DeducedParentType = GetParentType; - using MemberType = GetMemberType; - static_assert(std::is_base_of::value || std::is_same::value); - /* DEPRECATED: static_assert(std::is_literal_type::value); */ - - return OffsetOfCalculator::OffsetOf(MemberPtr); - }(); + template> requires (std::derived_from> || std::same_as>) + struct OffsetOf { + using MemberType = GetMemberType; + static constexpr std::ptrdiff_t Value = OffsetOfCalculator::OffsetOf(MemberPtr); + }; } template> - constexpr ALWAYS_INLINE RealParentType &GetParentReference(impl::GetMemberType *member) { - constexpr std::ptrdiff_t Offset = impl::OffsetOf; + ALWAYS_INLINE RealParentType &GetParentReference(impl::GetMemberType *member) { + constexpr std::ptrdiff_t Offset = impl::OffsetOf::Value; return *static_cast(static_cast(static_cast(static_cast(member)) - Offset)); } template> - constexpr ALWAYS_INLINE RealParentType const &GetParentReference(impl::GetMemberType const *member) { - constexpr std::ptrdiff_t Offset = impl::OffsetOf; + ALWAYS_INLINE RealParentType const &GetParentReference(impl::GetMemberType const *member) { + constexpr std::ptrdiff_t Offset = impl::OffsetOf::Value; return *static_cast(static_cast(static_cast(static_cast(member)) - Offset)); } template> - constexpr ALWAYS_INLINE RealParentType *GetParentPointer(impl::GetMemberType *member) { + ALWAYS_INLINE RealParentType *GetParentPointer(impl::GetMemberType *member) { return std::addressof(GetParentReference(member)); } template> - constexpr ALWAYS_INLINE RealParentType const *GetParentPointer(impl::GetMemberType const *member) { + ALWAYS_INLINE RealParentType const *GetParentPointer(impl::GetMemberType const *member) { return std::addressof(GetParentReference(member)); } template> - constexpr ALWAYS_INLINE RealParentType &GetParentReference(impl::GetMemberType &member) { + ALWAYS_INLINE RealParentType &GetParentReference(impl::GetMemberType &member) { return GetParentReference(std::addressof(member)); } template> - constexpr ALWAYS_INLINE RealParentType const &GetParentReference(impl::GetMemberType const &member) { + ALWAYS_INLINE RealParentType const &GetParentReference(impl::GetMemberType const &member) { return GetParentReference(std::addressof(member)); } template> - constexpr ALWAYS_INLINE RealParentType *GetParentPointer(impl::GetMemberType &member) { + ALWAYS_INLINE RealParentType *GetParentPointer(impl::GetMemberType &member) { return std::addressof(GetParentReference(member)); } template> - constexpr ALWAYS_INLINE RealParentType const *GetParentPointer(impl::GetMemberType const &member) { + ALWAYS_INLINE RealParentType const *GetParentPointer(impl::GetMemberType const &member) { return std::addressof(GetParentReference(member)); } -/* Defines, for use by other code. */ + /* Defines, for use by other code. */ -#define OFFSETOF(parent, member) (::ams::util::impl::OffsetOf<&parent::member, parent>) + #define OFFSETOF(parent, member) (::ams::util::impl::OffsetOf<&parent::member, parent>::Value) -#define GET_PARENT_PTR(parent, member, _arg) (::ams::util::GetParentPointer<&parent::member, parent>(_arg)) + #define GET_PARENT_PTR(parent, member, _arg) (::ams::util::GetParentPointer<&parent::member, parent>(_arg)) -#define GET_PARENT_REF(parent, member, _arg) (::ams::util::GetParentReference<&parent::member, parent>(_arg)) - - namespace test { - - struct Struct1 { - uint32_t a; - }; - - struct Struct2 { - uint32_t b; - }; - - struct Struct3 : public Struct1, Struct2 { - uint32_t c; - }; - - static_assert(impl::OffsetOf<&Struct1::a> == 0); - static_assert(impl::OffsetOf<&Struct2::b> == 0); - static_assert(impl::OffsetOf<&Struct3::a> == 0); - static_assert(impl::OffsetOf<&Struct3::b> == 0); - - - static_assert(impl::OffsetOf<&Struct3::a, Struct3> == 0 || impl::OffsetOf<&Struct3::b, Struct3> == 0); - static_assert(impl::OffsetOf<&Struct3::a, Struct3> == sizeof(Struct2) || impl::OffsetOf<&Struct3::b, Struct3> == sizeof(Struct1)); - static_assert(impl::OffsetOf<&Struct3::c> == sizeof(Struct1) + sizeof(Struct2)); - - constexpr Struct3 TestStruct3 = {}; - - static_assert(std::addressof(TestStruct3) == GET_PARENT_PTR(Struct3, a, TestStruct3.a)); - static_assert(std::addressof(TestStruct3) == GET_PARENT_PTR(Struct3, a, std::addressof(TestStruct3.a))); - static_assert(std::addressof(TestStruct3) == GET_PARENT_PTR(Struct3, b, TestStruct3.b)); - static_assert(std::addressof(TestStruct3) == GET_PARENT_PTR(Struct3, b, std::addressof(TestStruct3.b))); - static_assert(std::addressof(TestStruct3) == GET_PARENT_PTR(Struct3, c, TestStruct3.c)); - static_assert(std::addressof(TestStruct3) == GET_PARENT_PTR(Struct3, c, std::addressof(TestStruct3.c))); - - struct CharArray { - char c0; - char c1; - char c2; - char c3; - char c4; - char c5; - char c6; - char c7; - }; - - static_assert(impl::OffsetOf<&CharArray::c0> == 0); - static_assert(impl::OffsetOf<&CharArray::c1> == 1); - static_assert(impl::OffsetOf<&CharArray::c2> == 2); - static_assert(impl::OffsetOf<&CharArray::c3> == 3); - static_assert(impl::OffsetOf<&CharArray::c4> == 4); - static_assert(impl::OffsetOf<&CharArray::c5> == 5); - static_assert(impl::OffsetOf<&CharArray::c6> == 6); - static_assert(impl::OffsetOf<&CharArray::c7> == 7); - - constexpr CharArray TestCharArray = {}; - - static_assert(std::addressof(TestCharArray) == GET_PARENT_PTR(CharArray, c0, TestCharArray.c0)); - static_assert(std::addressof(TestCharArray) == GET_PARENT_PTR(CharArray, c0, std::addressof(TestCharArray.c0))); - static_assert(std::addressof(TestCharArray) == GET_PARENT_PTR(CharArray, c1, TestCharArray.c1)); - static_assert(std::addressof(TestCharArray) == GET_PARENT_PTR(CharArray, c1, std::addressof(TestCharArray.c1))); - static_assert(std::addressof(TestCharArray) == GET_PARENT_PTR(CharArray, c2, TestCharArray.c2)); - static_assert(std::addressof(TestCharArray) == GET_PARENT_PTR(CharArray, c2, std::addressof(TestCharArray.c2))); - static_assert(std::addressof(TestCharArray) == GET_PARENT_PTR(CharArray, c3, TestCharArray.c3)); - static_assert(std::addressof(TestCharArray) == GET_PARENT_PTR(CharArray, c3, std::addressof(TestCharArray.c3))); - static_assert(std::addressof(TestCharArray) == GET_PARENT_PTR(CharArray, c4, TestCharArray.c4)); - static_assert(std::addressof(TestCharArray) == GET_PARENT_PTR(CharArray, c4, std::addressof(TestCharArray.c4))); - static_assert(std::addressof(TestCharArray) == GET_PARENT_PTR(CharArray, c5, TestCharArray.c5)); - static_assert(std::addressof(TestCharArray) == GET_PARENT_PTR(CharArray, c5, std::addressof(TestCharArray.c5))); - static_assert(std::addressof(TestCharArray) == GET_PARENT_PTR(CharArray, c6, TestCharArray.c6)); - static_assert(std::addressof(TestCharArray) == GET_PARENT_PTR(CharArray, c6, std::addressof(TestCharArray.c6))); - static_assert(std::addressof(TestCharArray) == GET_PARENT_PTR(CharArray, c7, TestCharArray.c7)); - static_assert(std::addressof(TestCharArray) == GET_PARENT_PTR(CharArray, c7, std::addressof(TestCharArray.c7))); - - } + #define GET_PARENT_REF(parent, member, _arg) (::ams::util::GetParentReference<&parent::member, parent>(_arg)) } diff --git a/libraries/libvapours/include/vapours/util/util_typed_storage.hpp b/libraries/libvapours/include/vapours/util/util_typed_storage.hpp index 84ddc692f..40b20c591 100644 --- a/libraries/libvapours/include/vapours/util/util_typed_storage.hpp +++ b/libraries/libvapours/include/vapours/util/util_typed_storage.hpp @@ -26,32 +26,32 @@ namespace ams::util { }; template - static constexpr ALWAYS_INLINE T *GetPointer(TypedStorage &ts) { - return static_cast(static_cast(std::addressof(ts._storage))); + static ALWAYS_INLINE T *GetPointer(TypedStorage &ts) { + return std::launder(reinterpret_cast(std::addressof(ts._storage))); } template - static constexpr ALWAYS_INLINE const T *GetPointer(const TypedStorage &ts) { - return static_cast(static_cast(std::addressof(ts._storage))); + static ALWAYS_INLINE const T *GetPointer(const TypedStorage &ts) { + return std::launder(reinterpret_cast(std::addressof(ts._storage))); } template - static constexpr ALWAYS_INLINE T &GetReference(TypedStorage &ts) { + static ALWAYS_INLINE T &GetReference(TypedStorage &ts) { return *GetPointer(ts); } template - static constexpr ALWAYS_INLINE const T &GetReference(const TypedStorage &ts) { + static ALWAYS_INLINE const T &GetReference(const TypedStorage &ts) { return *GetPointer(ts); } template - static constexpr ALWAYS_INLINE T *ConstructAt(TypedStorage &ts, Args &&... args) { - return std::construct_at(GetPointer(ts), std::forward(args)...); + static ALWAYS_INLINE T *ConstructAt(TypedStorage &ts, Args &&... args) { + return std::construct_at(reinterpret_cast(std::addressof(ts._storage)), std::forward(args)...); } template - static constexpr ALWAYS_INLINE void DestroyAt(TypedStorage &ts) { + static ALWAYS_INLINE void DestroyAt(TypedStorage &ts) { return std::destroy_at(GetPointer(ts)); } @@ -65,7 +65,7 @@ namespace ams::util { bool m_active; public: template - constexpr ALWAYS_INLINE TypedStorageGuard(TypedStorage &ts, Args &&... args) : m_ts(ts), m_active(true) { + ALWAYS_INLINE TypedStorageGuard(TypedStorage &ts, Args &&... args) : m_ts(ts), m_active(true) { ConstructAt(m_ts, std::forward(args)...); } @@ -83,7 +83,7 @@ namespace ams::util { } template - static constexpr ALWAYS_INLINE impl::TypedStorageGuard ConstructAtGuarded(TypedStorage &ts, Args &&... args) { + static ALWAYS_INLINE impl::TypedStorageGuard ConstructAtGuarded(TypedStorage &ts, Args &&... args) { return impl::TypedStorageGuard(ts, std::forward(args)...); }