diff --git a/libstratosphere/include/stratosphere/pgl/srv/pgl_srv_api.hpp b/libstratosphere/include/stratosphere/pgl/srv/pgl_srv_api.hpp index ab49b14a..723ddad5 100644 --- a/libstratosphere/include/stratosphere/pgl/srv/pgl_srv_api.hpp +++ b/libstratosphere/include/stratosphere/pgl/srv/pgl_srv_api.hpp @@ -20,6 +20,6 @@ namespace ams::pgl::srv { - void Initialize(ShellInterface *interface, MemoryResource *mr); + void Initialize(); } diff --git a/libstratosphere/include/stratosphere/pgl/srv/pgl_srv_shell_interface.hpp b/libstratosphere/include/stratosphere/pgl/srv/pgl_srv_shell_interface.hpp index f3e4b39f..1c510a1a 100644 --- a/libstratosphere/include/stratosphere/pgl/srv/pgl_srv_shell_interface.hpp +++ b/libstratosphere/include/stratosphere/pgl/srv/pgl_srv_shell_interface.hpp @@ -20,18 +20,16 @@ namespace ams::pgl::srv { - class ShellInterface final { + class ShellInterface { NON_COPYABLE(ShellInterface); NON_MOVEABLE(ShellInterface); private: - MemoryResource *memory_resource; + using Allocator = ams::sf::ExpHeapAllocator; + using ObjectFactory = ams::sf::ObjectFactory; + private: + Allocator *m_allocator; public: - constexpr ShellInterface() : memory_resource(nullptr) { /* ... */ } - - void Initialize(MemoryResource *mr) { - AMS_ASSERT(this->memory_resource == nullptr); - this->memory_resource = mr; - } + constexpr ShellInterface(Allocator *a) : m_allocator(a) { /* ... */ } public: /* Interface commands. */ Result LaunchProgram(ams::sf::Out out, const ncm::ProgramLocation &loc, u32 pm_flags, u8 pgl_flags); diff --git a/libstratosphere/include/stratosphere/sf/sf_object_factory.hpp b/libstratosphere/include/stratosphere/sf/sf_object_factory.hpp index ec3b0033..5e44c2be 100644 --- a/libstratosphere/include/stratosphere/sf/sf_object_factory.hpp +++ b/libstratosphere/include/stratosphere/sf/sf_object_factory.hpp @@ -156,7 +156,7 @@ namespace ams::sf { constexpr virtual void AddReference() override { /* ... */ } constexpr virtual void Release() override { /* ... */ } - constexpr Impl &GetImpl() { return impl::UnmanagedEmplacedImplHolder::GetImplPointer(this); } + constexpr Impl &GetImpl() { return *impl::UnmanagedEmplacedImplHolder::GetImplPointer(this); } constexpr SharedPointer GetShared() { return SharedPointer(this, false); } }; diff --git a/libstratosphere/source/ncm/ncm_fs_utils.cpp b/libstratosphere/source/ncm/ncm_fs_utils.cpp index 848ace07..231ec89a 100644 --- a/libstratosphere/source/ncm/ncm_fs_utils.cpp +++ b/libstratosphere/source/ncm/ncm_fs_utils.cpp @@ -24,17 +24,17 @@ namespace ams::ncm::impl { } - bool PathView::HasPrefix(std::string_view prefix) const { + bool PathView::HasPrefix(util::string_view prefix) const { return this->path.compare(0, prefix.length(), prefix) == 0; } - bool PathView::HasSuffix(std::string_view suffix) const { + bool PathView::HasSuffix(util::string_view suffix) const { return this->path.compare(this->path.length() - suffix.length(), suffix.length(), suffix) == 0; } - std::string_view PathView::GetFileName() const { + util::string_view PathView::GetFileName() const { auto pos = this->path.find_last_of("/"); - return pos != std::string_view::npos ? this->path.substr(pos + 1) : this->path; + return pos != util::string_view::npos ? this->path.substr(pos + 1) : this->path; } MountName CreateUniqueMountName() { diff --git a/libstratosphere/source/ncm/ncm_fs_utils.hpp b/libstratosphere/source/ncm/ncm_fs_utils.hpp index d6c4dbf2..b6dcb0f8 100644 --- a/libstratosphere/source/ncm/ncm_fs_utils.hpp +++ b/libstratosphere/source/ncm/ncm_fs_utils.hpp @@ -22,12 +22,12 @@ namespace ams::ncm::impl { class PathView { private: - std::string_view path; /* Nintendo uses util::string_view here. */ + util::string_view path; /* Nintendo uses util::string_view here. */ public: - PathView(std::string_view p) : path(p) { /* ...*/ } - bool HasPrefix(std::string_view prefix) const; - bool HasSuffix(std::string_view suffix) const; - std::string_view GetFileName() const; + PathView(util::string_view p) : path(p) { /* ...*/ } + bool HasPrefix(util::string_view prefix) const; + bool HasSuffix(util::string_view suffix) const; + util::string_view GetFileName() const; }; struct MountName { diff --git a/libstratosphere/source/pgl/srv/pgl_srv_api.cpp b/libstratosphere/source/pgl/srv/pgl_srv_api.cpp index 330d1155..c6c63441 100644 --- a/libstratosphere/source/pgl/srv/pgl_srv_api.cpp +++ b/libstratosphere/source/pgl/srv/pgl_srv_api.cpp @@ -18,10 +18,7 @@ namespace ams::pgl::srv { - void Initialize(ShellInterface *interface, MemoryResource *mr) { - /* Set the memory resource for the interface. */ - interface->Initialize(mr); - + void Initialize() { /* Enable extra application threads, if we should. */ u8 enable_application_extra_thread; const size_t sz = settings::fwdbg::GetSettingsItemValue(std::addressof(enable_application_extra_thread), sizeof(enable_application_extra_thread), "application_extra_thread", "enable_application_extra_thread"); diff --git a/libstratosphere/source/pgl/srv/pgl_srv_shell_host_utils.cpp b/libstratosphere/source/pgl/srv/pgl_srv_shell_host_utils.cpp index a40c03d0..1047d13f 100644 --- a/libstratosphere/source/pgl/srv/pgl_srv_shell_host_utils.cpp +++ b/libstratosphere/source/pgl/srv/pgl_srv_shell_host_utils.cpp @@ -25,16 +25,16 @@ namespace ams::pgl::srv { static_assert(sizeof(HostPackageMountName) - 1 <= fs::MountNameLengthMax); struct CaseInsensitiveCharTraits : public std::char_traits { - static char to_upper(char c) { + static constexpr char to_upper(char c) { return std::toupper(static_cast(c)); } - static bool eq(char c1, char c2) { + static constexpr bool eq(char c1, char c2) { return to_upper(c1) == to_upper(c2); } - static bool lt(char c1, char c2) { + static constexpr bool lt(char c1, char c2) { return to_upper(c1) < to_upper(c2); } - static int compare(const char *s1, const char *s2, size_t n) { + static constexpr int compare(const char *s1, const char *s2, size_t n) { while ( n-- != 0 ) { if ( to_upper(*s1) < to_upper(*s2) ) return -1; if ( to_upper(*s1) > to_upper(*s2) ) return 1; @@ -42,7 +42,7 @@ namespace ams::pgl::srv { } return 0; } - static const char *find(const char *s, int n, char a) { + static constexpr const char *find(const char *s, int n, char a) { auto const ua (to_upper(a)); while ( n-- != 0 ) { @@ -54,7 +54,7 @@ namespace ams::pgl::srv { } }; - using PathView = std::basic_string_view; + using PathView = util::basic_string_view; enum class ExtensionType { None = 0, diff --git a/libstratosphere/source/pgl/srv/pgl_srv_shell_interface.cpp b/libstratosphere/source/pgl/srv/pgl_srv_shell_interface.cpp index 1ececce1..4d4b3480 100644 --- a/libstratosphere/source/pgl/srv/pgl_srv_shell_interface.cpp +++ b/libstratosphere/source/pgl/srv/pgl_srv_shell_interface.cpp @@ -20,12 +20,6 @@ namespace ams::pgl::srv { - namespace { - - using ShellEventObjectFactory = ams::sf::ObjectFactory; - - } - Result ShellInterface::LaunchProgram(ams::sf::Out out, const ncm::ProgramLocation &loc, u32 pm_flags, u8 pgl_flags) { return pgl::srv::LaunchProgram(out.GetPointer(), loc, pm_flags, pgl_flags); } @@ -76,7 +70,7 @@ namespace ams::pgl::srv { Result ShellInterface::GetShellEventObserver(ams::sf::Out> out) { /* Allocate a new interface. */ - auto session = ShellEventObjectFactory::CreateSharedEmplaced(this->memory_resource); + auto session = ObjectFactory::CreateSharedEmplaced(m_allocator); R_UNLESS(session != nullptr, pgl::ResultOutOfMemory()); *out = std::move(session); diff --git a/libvapours/include/vapours/util.hpp b/libvapours/include/vapours/util.hpp index 344926fc..7260a93e 100644 --- a/libvapours/include/vapours/util.hpp +++ b/libvapours/include/vapours/util.hpp @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include diff --git a/libvapours/include/vapours/util/util_string_view.hpp b/libvapours/include/vapours/util/util_string_view.hpp new file mode 100644 index 00000000..382b9cf8 --- /dev/null +++ b/libvapours/include/vapours/util/util_string_view.hpp @@ -0,0 +1,347 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include +#include + +namespace ams::util { + + template> + class basic_string_view { + static_assert(!std::is_array<_CharT>::value); + static_assert(std::is_trivial<_CharT>::value && std::is_standard_layout<_CharT>::value); + static_assert(std::same_as<_CharT, typename _Traits::char_type>); + public: + using traits_type = _Traits; + using value_type = _CharT; + using pointer = value_type *; + using const_pointer = const value_type *; + using reference = value_type &; + using const_reference = const value_type &; + using const_iterator = const value_type *; + using iterator = const_iterator; + using const_reverse_iterator = std::reverse_iterator; + using reverse_iterator = const_reverse_iterator; + using size_type = size_t; + using difference_type = ptrdiff_t; + static constexpr size_type npos = size_type(-1); + private: + static constexpr int _s_compare(size_type lhs, size_type rhs) noexcept { + const difference_type diff = lhs - rhs; + if (diff > std::numeric_limits::max()) { + return std::numeric_limits::max(); + } + if (diff < std::numeric_limits::min()) { + return std::numeric_limits::min(); + } + return static_cast(diff); + } + private: + const_pointer m_str; + size_type m_len; + public: + constexpr basic_string_view() noexcept : m_str(nullptr), m_len(0) { /* ... */ } + constexpr basic_string_view(const _CharT *str, size_type len) noexcept : m_str(str), m_len(len) { /* ... */ } + constexpr basic_string_view(const _CharT *str) noexcept : m_str(str), m_len(str ? traits_type::length(str) : 0) { /* ... */ } + + template _End> requires std::same_as, _CharT> && (!std::convertible_to<_End, size_type>) + constexpr basic_string_view(_It first, _End last) noexcept : m_str(std::to_address(first)), m_len(last - first) { /* ... */ } + + constexpr basic_string_view(const basic_string_view &) noexcept = default; + constexpr basic_string_view &operator=(const basic_string_view &) noexcept = default; + + constexpr const_iterator begin() const noexcept { return m_str; } + constexpr const_iterator end() const noexcept { return m_str + m_len; } + + constexpr const_iterator cbegin() const noexcept { return m_str; } + constexpr const_iterator cend() const noexcept { return m_str + m_len; } + + constexpr const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator(this->end()); } + constexpr const_reverse_iterator rend() const noexcept { return const_reverse_iterator(this->begin()); } + + constexpr const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(this->cend()); } + constexpr const_reverse_iterator crend() const noexcept { return const_reverse_iterator(this->cbegin()); } + + constexpr size_type size() const noexcept { return m_len; } + constexpr size_type length() const noexcept { return m_len; } + + constexpr size_type max_size() const noexcept { return (npos - sizeof(size_type) - sizeof(void *)) / sizeof(value_type) / 4; } + + [[nodiscard]] constexpr bool empty() const noexcept { return m_len == 0; } + + constexpr const_reference operator[](size_type pos) const noexcept { + AMS_ASSERT(pos < m_len); + return *(m_str + pos); + } + + constexpr const_reference at(size_type pos) const noexcept { + AMS_ASSERT(pos < m_len); + AMS_ABORT_UNLESS(pos < m_len); + return *(m_str + pos); + } + + constexpr const_reference front() const noexcept { + AMS_ASSERT(m_len > 0); + return *m_str; + } + + constexpr const_reference back() const noexcept { + AMS_ASSERT(m_len > 0); + return *(m_str + m_len - 1); + } + + constexpr const_pointer data() const noexcept { return m_str; } + + constexpr void remove_prefix(size_type n) noexcept { + AMS_ASSERT(m_len >= n); + m_str += n; + m_len -= n; + } + + constexpr void remove_suffix(size_type n) noexcept { + AMS_ASSERT(m_len >= n); + m_len -= n; + } + + constexpr void swap(basic_string_view &rhs) noexcept { + auto tmp = *this; + *this = rhs; + rhs = tmp; + } + + constexpr size_type copy(_CharT *str, size_type n, size_type pos = 0) const noexcept { + AMS_ASSERT(pos <= this->size()); + const size_type rlen = std::min(n, m_len - pos); + traits_type::copy(str, this->data() + pos, rlen); + return rlen; + } + + constexpr basic_string_view substr(size_type pos = 0, size_type n = npos) const noexcept { + AMS_ASSERT(pos <= this->size()); + const size_type rlen = std::min(n, m_len - pos); + return basic_string_view{m_str + pos, rlen}; + } + + constexpr int compare(basic_string_view str) const noexcept { + const size_type rlen = std::min(m_len, str.m_len); + int ret = traits_type::compare(m_str, str.m_str, rlen); + if (ret == 0) { + ret = _s_compare(m_len, str.m_len); + } + return ret; + } + + constexpr int compare(size_type pos, size_type n, basic_string_view str) const noexcept { + return this->substr(pos, n).compare(str); + } + + constexpr int compare(size_type pos1, size_type n1, basic_string_view str, size_type pos2, size_type n2) const { + return this->substr(pos1, n1).compare(str.substr(pos2, n2)); + } + + constexpr int compare(const _CharT *str) const noexcept { + return this->compare(basic_string_view(str)); + } + + constexpr int compare(size_type pos, size_type n, const _CharT *str) const noexcept { + return this->substr(pos, n).compare(basic_string_view(str)); + } + + constexpr int compare(size_type pos, size_type n, const _CharT *str, size_type n2) const noexcept { + return this->substr(pos, n).compare(basic_string_view(str, n2)); + } + + constexpr bool starts_with(basic_string_view x) const noexcept { return this->substr(0, x.size()) == x; } + constexpr bool starts_with(_CharT x) const noexcept { return !this->empty() && traits_type::eq(this->front(), x); } + constexpr bool starts_with(const _CharT *x) const noexcept { return this->starts_with(basic_string_view(x)); } + + constexpr bool ends_with(basic_string_view x) const noexcept { return this->size() >= x.size() && this->compare(this->size() - x.size(), npos, x) == 0; } + constexpr bool ends_with(_CharT x) const noexcept { return !this->empty() && traits_type::eq(this->back(), x); } + constexpr bool ends_with(const _CharT *x) const noexcept { return this->ends_with(basic_string_view(x)); } + + constexpr size_type find(const _CharT *str, size_type pos, size_type n) const noexcept { + if (n == 0) { + return pos + m_len ? pos : npos; + } + + if (n <= m_len) { + for (/* ... */; pos <= m_len - n; ++pos) { + if (traits_type::eq(m_str[pos], str[0]) && traits_type::compare(m_str + pos + 1, str + 1, n - 1) == 0) { + return pos; + } + } + } + + return npos; + } + + constexpr size_type find(_CharT c, size_type pos = 0) const noexcept { + size_type ret = npos; + if (pos < m_len) { + const size_type n = m_len - pos; + if (const _CharT *p = traits_type::find(m_str + pos, n, c); p) { + ret = p - m_str; + } + } + return ret; + } + + constexpr size_type find(basic_string_view str, size_type pos = 0) const noexcept { return this->find(str.m_str, pos, str.m_len); } + + __attribute__((nonnull(1))) + constexpr size_type find(const _CharT *str, size_type pos = 0) const noexcept { return this->find(str, pos, traits_type::length(str)); } + + constexpr size_type rfind(const _CharT *str, size_type pos, size_type n) const noexcept { + if (n <= m_len) { + pos = std::min(size_type(m_len - n), pos); + do { + if (traits_type::compare(m_str + pos, str, n) == 0) { + return pos; + } + } while (pos-- > 0); + } + + return npos; + } + + constexpr size_type rfind(_CharT c, size_type pos = 0) const noexcept { + size_type size = m_len; + if (size > 0) { + if (--size > pos) { + size = pos; + } + for (++size; size-- > 0; /* ... */) { + if (traits_type::eq(m_str[size], c)) { + return size; + } + } + } + return npos; + } + + constexpr size_type rfind(basic_string_view str, size_type pos = 0) const noexcept { return this->rfind(str.m_str, pos, str.m_len); } + + __attribute__((nonnull(1))) + constexpr size_type rfind(const _CharT *str, size_type pos = 0) const noexcept { return this->rfind(str, pos, traits_type::length(str)); } + + constexpr size_type find_first_of(const _CharT *str, size_type pos, size_t n) const noexcept { + for (/* ... */; n && pos < m_len; ++pos) { + if (const _CharT *p = traits_type::find(str, n, m_str[pos]); p) { + return pos; + } + } + return npos; + } + + constexpr size_type find_first_of(basic_string_view str, size_type pos = 0) const noexcept { return this->find_first_of(str.m_str, pos, str.m_len); } + constexpr size_type find_first_of(_CharT c, size_type pos = 0) const noexcept { return this->find(c, pos); } + + __attribute__((nonnull(1))) + constexpr size_type find_first_of(const _CharT *str, size_type pos = 0) const noexcept { return this->find_first_of(str, pos, traits_type::length(str)); } + + constexpr size_type find_last_of(const _CharT *str, size_type pos, size_t n) const noexcept { + size_type size = this->size(); + if (size && n) { + if (--size > pos) { + size = pos; + } + do { + if (traits_type::find(str, n, m_str[size])) { + return size; + } + } while (size-- != 0); + } + return npos; + } + + constexpr size_type find_last_of(basic_string_view str, size_type pos = 0) const noexcept { return this->find_last_of(str.m_str, pos, str.m_len); } + constexpr size_type find_last_of(_CharT c, size_type pos = 0) const noexcept { return this->rfind(c, pos); } + + __attribute__((nonnull(1))) + constexpr size_type find_last_of(const _CharT *str, size_type pos = 0) const noexcept { return this->find_first_of(str, pos, traits_type::length(str)); } + + constexpr size_type find_first_not_of(const _CharT *str, size_type pos, size_t n) const noexcept { + for (/* ... */; pos < m_len; ++pos) { + if (!traits_type::find(str, n, m_str[pos])) { + return pos; + } + } + return npos; + } + + constexpr size_type find_first_not_of(_CharT c, size_type pos = 0) const noexcept { + for (/* ... */; pos < m_len; ++pos) { + if (!traits_type::eq(m_str[pos], c)) { + return pos; + } + } + return npos; + } + + constexpr size_type find_first_not_of(basic_string_view str, size_type pos = 0) const noexcept { return this->find_first_not_of(str.m_str, pos, str.m_len); } + + __attribute__((nonnull(1))) + constexpr size_type find_first_not_of(const _CharT *str, size_type pos = 0) const noexcept { return this->find_first_not_of(str, pos, traits_type::length(str)); } + + constexpr size_type find_last_not_of(const _CharT *str, size_type pos, size_t n) const noexcept { + size_type size = this->size(); + if (size) { + if (--size > pos) { + size = pos; + } + do { + if (!traits_type::find(str, n, m_str[size])) { + return size; + } + } while (size-- != 0); + } + return npos; + } + + constexpr size_type find_last_not_of(_CharT c, size_type pos = 0) const noexcept { + size_type size = this->size(); + if (size) { + if (--size > pos) { + size = pos; + } + do { + if (!traits_type::eq(m_str[size], c)) { + return size; + } + } while (size-- != 0); + } + return npos; + } + + constexpr size_type find_last_not_of(basic_string_view str, size_type pos = 0) const noexcept { return this->find_last_not_of(str.m_str, pos, str.m_len); } + + __attribute__((nonnull(1))) + constexpr size_type find_last_not_of(const _CharT *str, size_type pos = 0) const noexcept { return this->find_last_not_of(str, pos, traits_type::length(str)); } + + constexpr friend bool operator==(const basic_string_view &lhs, const basic_string_view &rhs) noexcept { return lhs.compare(rhs) == 0; } + constexpr friend bool operator!=(const basic_string_view &lhs, const basic_string_view &rhs) noexcept { return lhs.compare(rhs) != 0; } + constexpr friend bool operator<=(const basic_string_view &lhs, const basic_string_view &rhs) noexcept { return lhs.compare(rhs) <= 0; } + constexpr friend bool operator>=(const basic_string_view &lhs, const basic_string_view &rhs) noexcept { return lhs.compare(rhs) >= 0; } + constexpr friend bool operator< (const basic_string_view &lhs, const basic_string_view &rhs) noexcept { return lhs.compare(rhs) < 0; } + constexpr friend bool operator> (const basic_string_view &lhs, const basic_string_view &rhs) noexcept { return lhs.compare(rhs) > 0; } + }; + + template _End> + basic_string_view(_It, _End) -> basic_string_view>; + + using string_view = basic_string_view; + +}