core: backport some ResultCode updates (#6645)

Co-authored-by: Lioncash <mathew1800@gmail.com>
Co-authored-by: Morph <39850852+Morph1984@users.noreply.github.com>
This commit is contained in:
GPUCode 2023-07-03 03:23:53 +03:00 committed by GitHub
parent 0b37c1da57
commit 2126c240cd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
34 changed files with 1204 additions and 277 deletions

View file

@ -73,6 +73,7 @@ add_library(citra_common STATIC
dynamic_library/ffmpeg.h
error.cpp
error.h
expected.h
file_util.cpp
file_util.h
hash.h

987
src/common/expected.h Normal file
View file

@ -0,0 +1,987 @@
// Copyright 2021 yuzu Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
// This is based on the proposed implementation of std::expected (P0323)
// https://github.com/TartanLlama/expected/blob/master/include/tl/expected.hpp
#pragma once
#include <type_traits>
#include <utility>
namespace Common {
template <typename T, typename E>
class Expected;
template <typename E>
class Unexpected {
public:
Unexpected() = delete;
constexpr explicit Unexpected(const E& e) : m_val{e} {}
constexpr explicit Unexpected(E&& e) : m_val{std::move(e)} {}
constexpr E& value() & {
return m_val;
}
constexpr const E& value() const& {
return m_val;
}
constexpr E&& value() && {
return std::move(m_val);
}
constexpr const E&& value() const&& {
return std::move(m_val);
}
private:
E m_val;
};
template <typename E>
constexpr auto operator<=>(const Unexpected<E>& lhs, const Unexpected<E>& rhs) {
return lhs.value() <=> rhs.value();
}
struct unexpect_t {
constexpr explicit unexpect_t() = default;
};
namespace detail {
struct no_init_t {
constexpr explicit no_init_t() = default;
};
/**
* This specialization is for when T is not trivially destructible,
* so the destructor must be called on destruction of `expected'
* Additionally, this requires E to be trivially destructible
*/
template <typename T, typename E, bool = std::is_trivially_destructible_v<T>>
requires std::is_trivially_destructible_v<E>
struct expected_storage_base {
constexpr expected_storage_base() : m_val{T{}}, m_has_val{true} {}
constexpr expected_storage_base(no_init_t) : m_has_val{false} {}
template <typename... Args, std::enable_if_t<std::is_constructible_v<T, Args&&...>>* = nullptr>
constexpr expected_storage_base(std::in_place_t, Args&&... args)
: m_val{std::forward<Args>(args)...}, m_has_val{true} {}
template <typename U, typename... Args,
std::enable_if_t<std::is_constructible_v<T, std::initializer_list<U>&, Args&&...>>* =
nullptr>
constexpr expected_storage_base(std::in_place_t, std::initializer_list<U> il, Args&&... args)
: m_val{il, std::forward<Args>(args)...}, m_has_val{true} {}
template <typename... Args, std::enable_if_t<std::is_constructible_v<E, Args&&...>>* = nullptr>
constexpr explicit expected_storage_base(unexpect_t, Args&&... args)
: m_unexpect{std::forward<Args>(args)...}, m_has_val{false} {}
template <typename U, typename... Args,
std::enable_if_t<std::is_constructible_v<E, std::initializer_list<U>&, Args&&...>>* =
nullptr>
constexpr explicit expected_storage_base(unexpect_t, std::initializer_list<U> il,
Args&&... args)
: m_unexpect{il, std::forward<Args>(args)...}, m_has_val{false} {}
~expected_storage_base() {
if (m_has_val) {
m_val.~T();
}
}
union {
T m_val;
Unexpected<E> m_unexpect;
};
bool m_has_val;
};
/**
* This specialization is for when T is trivially destructible,
* so the destructor of `expected` can be trivial
* Additionally, this requires E to be trivially destructible
*/
template <typename T, typename E>
requires std::is_trivially_destructible_v<E>
struct expected_storage_base<T, E, true> {
constexpr expected_storage_base() : m_val{T{}}, m_has_val{true} {}
constexpr expected_storage_base(no_init_t) : m_has_val{false} {}
template <typename... Args, std::enable_if_t<std::is_constructible_v<T, Args&&...>>* = nullptr>
constexpr expected_storage_base(std::in_place_t, Args&&... args)
: m_val{std::forward<Args>(args)...}, m_has_val{true} {}
template <typename U, typename... Args,
std::enable_if_t<std::is_constructible_v<T, std::initializer_list<U>&, Args&&...>>* =
nullptr>
constexpr expected_storage_base(std::in_place_t, std::initializer_list<U> il, Args&&... args)
: m_val{il, std::forward<Args>(args)...}, m_has_val{true} {}
template <typename... Args, std::enable_if_t<std::is_constructible_v<E, Args&&...>>* = nullptr>
constexpr explicit expected_storage_base(unexpect_t, Args&&... args)
: m_unexpect{std::forward<Args>(args)...}, m_has_val{false} {}
template <typename U, typename... Args,
std::enable_if_t<std::is_constructible_v<E, std::initializer_list<U>&, Args&&...>>* =
nullptr>
constexpr explicit expected_storage_base(unexpect_t, std::initializer_list<U> il,
Args&&... args)
: m_unexpect{il, std::forward<Args>(args)...}, m_has_val{false} {}
~expected_storage_base() = default;
union {
T m_val;
Unexpected<E> m_unexpect;
};
bool m_has_val;
};
template <typename T, typename E>
struct expected_operations_base : expected_storage_base<T, E> {
using expected_storage_base<T, E>::expected_storage_base;
template <typename... Args>
void construct(Args&&... args) noexcept {
new (std::addressof(this->m_val)) T{std::forward<Args>(args)...};
this->m_has_val = true;
}
template <typename Rhs>
void construct_with(Rhs&& rhs) noexcept {
new (std::addressof(this->m_val)) T{std::forward<Rhs>(rhs).get()};
this->m_has_val = true;
}
template <typename... Args>
void construct_error(Args&&... args) noexcept {
new (std::addressof(this->m_unexpect)) Unexpected<E>{std::forward<Args>(args)...};
this->m_has_val = false;
}
void assign(const expected_operations_base& rhs) noexcept {
if (!this->m_has_val && rhs.m_has_val) {
geterr().~Unexpected<E>();
construct(rhs.get());
} else {
assign_common(rhs);
}
}
void assign(expected_operations_base&& rhs) noexcept {
if (!this->m_has_val && rhs.m_has_val) {
geterr().~Unexpected<E>();
construct(std::move(rhs).get());
} else {
assign_common(rhs);
}
}
template <typename Rhs>
void assign_common(Rhs&& rhs) {
if (this->m_has_val) {
if (rhs.m_has_val) {
get() = std::forward<Rhs>(rhs).get();
} else {
destroy_val();
construct_error(std::forward<Rhs>(rhs).geterr());
}
} else {
if (!rhs.m_has_val) {
geterr() = std::forward<Rhs>(rhs).geterr();
}
}
}
bool has_value() const {
return this->m_has_val;
}
constexpr T& get() & {
return this->m_val;
}
constexpr const T& get() const& {
return this->m_val;
}
constexpr T&& get() && {
return std::move(this->m_val);
}
constexpr const T&& get() const&& {
return std::move(this->m_val);
}
constexpr Unexpected<E>& geterr() & {
return this->m_unexpect;
}
constexpr const Unexpected<E>& geterr() const& {
return this->m_unexpect;
}
constexpr Unexpected<E>&& geterr() && {
return std::move(this->m_unexpect);
}
constexpr const Unexpected<E>&& geterr() const&& {
return std::move(this->m_unexpect);
}
constexpr void destroy_val() {
get().~T();
}
};
/**
* This manages conditionally having a trivial copy constructor
* This specialization is for when T is trivially copy constructible
* Additionally, this requires E to be trivially copy constructible
*/
template <typename T, typename E, bool = std::is_trivially_copy_constructible_v<T>>
requires std::is_trivially_copy_constructible_v<E>
struct expected_copy_base : expected_operations_base<T, E> {
using expected_operations_base<T, E>::expected_operations_base;
};
/**
* This specialization is for when T is not trivially copy constructible
* Additionally, this requires E to be trivially copy constructible
*/
template <typename T, typename E>
requires std::is_trivially_copy_constructible_v<E>
struct expected_copy_base<T, E, false> : expected_operations_base<T, E> {
using expected_operations_base<T, E>::expected_operations_base;
expected_copy_base() = default;
expected_copy_base(const expected_copy_base& rhs)
: expected_operations_base<T, E>{no_init_t{}} {
if (rhs.has_value()) {
this->construct_with(rhs);
} else {
this->construct_error(rhs.geterr());
}
}
expected_copy_base(expected_copy_base&&) = default;
expected_copy_base& operator=(const expected_copy_base&) = default;
expected_copy_base& operator=(expected_copy_base&&) = default;
};
/**
* This manages conditionally having a trivial move constructor
* This specialization is for when T is trivially move constructible
* Additionally, this requires E to be trivially move constructible
*/
template <typename T, typename E, bool = std::is_trivially_move_constructible_v<T>>
requires std::is_trivially_move_constructible_v<E>
struct expected_move_base : expected_copy_base<T, E> {
using expected_copy_base<T, E>::expected_copy_base;
};
/**
* This specialization is for when T is not trivially move constructible
* Additionally, this requires E to be trivially move constructible
*/
template <typename T, typename E>
requires std::is_trivially_move_constructible_v<E>
struct expected_move_base<T, E, false> : expected_copy_base<T, E> {
using expected_copy_base<T, E>::expected_copy_base;
expected_move_base() = default;
expected_move_base(const expected_move_base&) = default;
expected_move_base(expected_move_base&& rhs) noexcept(std::is_nothrow_move_constructible_v<T>)
: expected_copy_base<T, E>{no_init_t{}} {
if (rhs.has_value()) {
this->construct_with(std::move(rhs));
} else {
this->construct_error(std::move(rhs.geterr()));
}
}
expected_move_base& operator=(const expected_move_base&) = default;
expected_move_base& operator=(expected_move_base&&) = default;
};
/**
* This manages conditionally having a trivial copy assignment operator
* This specialization is for when T is trivially copy assignable
* Additionally, this requires E to be trivially copy assignable
*/
template <typename T, typename E,
bool = std::conjunction_v<std::is_trivially_copy_assignable<T>,
std::is_trivially_copy_constructible<T>,
std::is_trivially_destructible<T>>>
requires std::conjunction_v<std::is_trivially_copy_assignable<E>,
std::is_trivially_copy_constructible<E>,
std::is_trivially_destructible<E>>
struct expected_copy_assign_base : expected_move_base<T, E> {
using expected_move_base<T, E>::expected_move_base;
};
/**
* This specialization is for when T is not trivially copy assignable
* Additionally, this requires E to be trivially copy assignable
*/
template <typename T, typename E>
requires std::conjunction_v<std::is_trivially_copy_assignable<E>,
std::is_trivially_copy_constructible<E>,
std::is_trivially_destructible<E>>
struct expected_copy_assign_base<T, E, false> : expected_move_base<T, E> {
using expected_move_base<T, E>::expected_move_base;
expected_copy_assign_base() = default;
expected_copy_assign_base(const expected_copy_assign_base&) = default;
expected_copy_assign_base(expected_copy_assign_base&&) = default;
expected_copy_assign_base& operator=(const expected_copy_assign_base& rhs) {
this->assign(rhs);
return *this;
}
expected_copy_assign_base& operator=(expected_copy_assign_base&&) = default;
};
/**
* This manages conditionally having a trivial move assignment operator
* This specialization is for when T is trivially move assignable
* Additionally, this requires E to be trivially move assignable
*/
template <typename T, typename E,
bool = std::conjunction_v<std::is_trivially_move_assignable<T>,
std::is_trivially_move_constructible<T>,
std::is_trivially_destructible<T>>>
requires std::conjunction_v<std::is_trivially_move_assignable<E>,
std::is_trivially_move_constructible<E>,
std::is_trivially_destructible<E>>
struct expected_move_assign_base : expected_copy_assign_base<T, E> {
using expected_copy_assign_base<T, E>::expected_copy_assign_base;
};
/**
* This specialization is for when T is not trivially move assignable
* Additionally, this requires E to be trivially move assignable
*/
template <typename T, typename E>
requires std::conjunction_v<std::is_trivially_move_assignable<E>,
std::is_trivially_move_constructible<E>,
std::is_trivially_destructible<E>>
struct expected_move_assign_base<T, E, false> : expected_copy_assign_base<T, E> {
using expected_copy_assign_base<T, E>::expected_copy_assign_base;
expected_move_assign_base() = default;
expected_move_assign_base(const expected_move_assign_base&) = default;
expected_move_assign_base(expected_move_assign_base&&) = default;
expected_move_assign_base& operator=(const expected_move_assign_base&) = default;
expected_move_assign_base& operator=(expected_move_assign_base&& rhs) noexcept(
std::conjunction_v<std::is_nothrow_move_constructible<T>,
std::is_nothrow_move_assignable<T>>) {
this->assign(std::move(rhs));
return *this;
}
};
/**
* expected_delete_ctor_base will conditionally delete copy and move constructors
* depending on whether T is copy/move constructible
* Additionally, this requires E to be copy/move constructible
*/
template <typename T, typename E, bool EnableCopy = std::is_copy_constructible_v<T>,
bool EnableMove = std::is_move_constructible_v<T>>
requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>>
struct expected_delete_ctor_base {
expected_delete_ctor_base() = default;
expected_delete_ctor_base(const expected_delete_ctor_base&) = default;
expected_delete_ctor_base(expected_delete_ctor_base&&) noexcept = default;
expected_delete_ctor_base& operator=(const expected_delete_ctor_base&) = default;
expected_delete_ctor_base& operator=(expected_delete_ctor_base&&) noexcept = default;
};
template <typename T, typename E>
requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>>
struct expected_delete_ctor_base<T, E, true, false> {
expected_delete_ctor_base() = default;
expected_delete_ctor_base(const expected_delete_ctor_base&) = default;
expected_delete_ctor_base(expected_delete_ctor_base&&) noexcept = delete;
expected_delete_ctor_base& operator=(const expected_delete_ctor_base&) = default;
expected_delete_ctor_base& operator=(expected_delete_ctor_base&&) noexcept = default;
};
template <typename T, typename E>
requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>>
struct expected_delete_ctor_base<T, E, false, true> {
expected_delete_ctor_base() = default;
expected_delete_ctor_base(const expected_delete_ctor_base&) = delete;
expected_delete_ctor_base(expected_delete_ctor_base&&) noexcept = default;
expected_delete_ctor_base& operator=(const expected_delete_ctor_base&) = default;
expected_delete_ctor_base& operator=(expected_delete_ctor_base&&) noexcept = default;
};
template <typename T, typename E>
requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>>
struct expected_delete_ctor_base<T, E, false, false> {
expected_delete_ctor_base() = default;
expected_delete_ctor_base(const expected_delete_ctor_base&) = delete;
expected_delete_ctor_base(expected_delete_ctor_base&&) noexcept = delete;
expected_delete_ctor_base& operator=(const expected_delete_ctor_base&) = default;
expected_delete_ctor_base& operator=(expected_delete_ctor_base&&) noexcept = default;
};
/**
* expected_delete_assign_base will conditionally delete copy and move assignment operators
* depending on whether T is copy/move constructible + assignable
* Additionally, this requires E to be copy/move constructible + assignable
*/
template <
typename T, typename E,
bool EnableCopy = std::conjunction_v<std::is_copy_constructible<T>, std::is_copy_assignable<T>>,
bool EnableMove = std::conjunction_v<std::is_move_constructible<T>, std::is_move_assignable<T>>>
requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>,
std::is_copy_assignable<E>, std::is_move_assignable<E>>
struct expected_delete_assign_base {
expected_delete_assign_base() = default;
expected_delete_assign_base(const expected_delete_assign_base&) = default;
expected_delete_assign_base(expected_delete_assign_base&&) noexcept = default;
expected_delete_assign_base& operator=(const expected_delete_assign_base&) = default;
expected_delete_assign_base& operator=(expected_delete_assign_base&&) noexcept = default;
};
template <typename T, typename E>
requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>,
std::is_copy_assignable<E>, std::is_move_assignable<E>>
struct expected_delete_assign_base<T, E, true, false> {
expected_delete_assign_base() = default;
expected_delete_assign_base(const expected_delete_assign_base&) = default;
expected_delete_assign_base(expected_delete_assign_base&&) noexcept = default;
expected_delete_assign_base& operator=(const expected_delete_assign_base&) = default;
expected_delete_assign_base& operator=(expected_delete_assign_base&&) noexcept = delete;
};
template <typename T, typename E>
requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>,
std::is_copy_assignable<E>, std::is_move_assignable<E>>
struct expected_delete_assign_base<T, E, false, true> {
expected_delete_assign_base() = default;
expected_delete_assign_base(const expected_delete_assign_base&) = default;
expected_delete_assign_base(expected_delete_assign_base&&) noexcept = default;
expected_delete_assign_base& operator=(const expected_delete_assign_base&) = delete;
expected_delete_assign_base& operator=(expected_delete_assign_base&&) noexcept = default;
};
template <typename T, typename E>
requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>,
std::is_copy_assignable<E>, std::is_move_assignable<E>>
struct expected_delete_assign_base<T, E, false, false> {
expected_delete_assign_base() = default;
expected_delete_assign_base(const expected_delete_assign_base&) = default;
expected_delete_assign_base(expected_delete_assign_base&&) noexcept = default;
expected_delete_assign_base& operator=(const expected_delete_assign_base&) = delete;
expected_delete_assign_base& operator=(expected_delete_assign_base&&) noexcept = delete;
};
/**
* This is needed to be able to construct the expected_default_ctor_base which follows,
* while still conditionally deleting the default constructor.
*/
struct default_constructor_tag {
constexpr explicit default_constructor_tag() = default;
};
/**
* expected_default_ctor_base will ensure that expected
* has a deleted default constructor if T is not default constructible
* This specialization is for when T is default constructible
*/
template <typename T, typename E, bool Enable = std::is_default_constructible_v<T>>
struct expected_default_ctor_base {
constexpr expected_default_ctor_base() noexcept = default;
constexpr expected_default_ctor_base(expected_default_ctor_base const&) noexcept = default;
constexpr expected_default_ctor_base(expected_default_ctor_base&&) noexcept = default;
expected_default_ctor_base& operator=(expected_default_ctor_base const&) noexcept = default;
expected_default_ctor_base& operator=(expected_default_ctor_base&&) noexcept = default;
constexpr explicit expected_default_ctor_base(default_constructor_tag) {}
};
template <typename T, typename E>
struct expected_default_ctor_base<T, E, false> {
constexpr expected_default_ctor_base() noexcept = delete;
constexpr expected_default_ctor_base(expected_default_ctor_base const&) noexcept = default;
constexpr expected_default_ctor_base(expected_default_ctor_base&&) noexcept = default;
expected_default_ctor_base& operator=(expected_default_ctor_base const&) noexcept = default;
expected_default_ctor_base& operator=(expected_default_ctor_base&&) noexcept = default;
constexpr explicit expected_default_ctor_base(default_constructor_tag) {}
};
template <typename T, typename E, typename U>
using expected_enable_forward_value =
std::enable_if_t<std::is_constructible_v<T, U&&> &&
!std::is_same_v<std::remove_cvref_t<U>, std::in_place_t> &&
!std::is_same_v<Expected<T, E>, std::remove_cvref_t<U>> &&
!std::is_same_v<Unexpected<E>, std::remove_cvref_t<U>>>;
template <typename T, typename E, typename U, typename G, typename UR, typename GR>
using expected_enable_from_other = std::enable_if_t<
std::is_constructible_v<T, UR> && std::is_constructible_v<E, GR> &&
!std::is_constructible_v<T, Expected<U, G>&> && !std::is_constructible_v<T, Expected<U, G>&&> &&
!std::is_constructible_v<T, const Expected<U, G>&> &&
!std::is_constructible_v<T, const Expected<U, G>&&> &&
!std::is_convertible_v<Expected<U, G>&, T> && !std::is_convertible_v<Expected<U, G>&&, T> &&
!std::is_convertible_v<const Expected<U, G>&, T> &&
!std::is_convertible_v<const Expected<U, G>&&, T>>;
} // namespace detail
template <typename T, typename E>
class Expected : private detail::expected_move_assign_base<T, E>,
private detail::expected_delete_ctor_base<T, E>,
private detail::expected_delete_assign_base<T, E>,
private detail::expected_default_ctor_base<T, E> {
public:
using value_type = T;
using error_type = E;
using unexpected_type = Unexpected<E>;
constexpr Expected() = default;
constexpr Expected(const Expected&) = default;
constexpr Expected(Expected&&) = default;
Expected& operator=(const Expected&) = default;
Expected& operator=(Expected&&) = default;
template <typename... Args, std::enable_if_t<std::is_constructible_v<T, Args&&...>>* = nullptr>
constexpr Expected(std::in_place_t, Args&&... args)
: impl_base{std::in_place, std::forward<Args>(args)...},
ctor_base{detail::default_constructor_tag{}} {}
template <typename U, typename... Args,
std::enable_if_t<std::is_constructible_v<T, std::initializer_list<U>&, Args&&...>>* =
nullptr>
constexpr Expected(std::in_place_t, std::initializer_list<U> il, Args&&... args)
: impl_base{std::in_place, il, std::forward<Args>(args)...},
ctor_base{detail::default_constructor_tag{}} {}
template <typename G = E, std::enable_if_t<std::is_constructible_v<E, const G&>>* = nullptr,
std::enable_if_t<!std::is_convertible_v<const G&, E>>* = nullptr>
constexpr explicit Expected(const Unexpected<G>& e)
: impl_base{unexpect_t{}, e.value()}, ctor_base{detail::default_constructor_tag{}} {}
template <typename G = E, std::enable_if_t<std::is_constructible_v<E, const G&>>* = nullptr,
std::enable_if_t<std::is_convertible_v<const G&, E>>* = nullptr>
constexpr Expected(Unexpected<G> const& e)
: impl_base{unexpect_t{}, e.value()}, ctor_base{detail::default_constructor_tag{}} {}
template <typename G = E, std::enable_if_t<std::is_constructible_v<E, G&&>>* = nullptr,
std::enable_if_t<!std::is_convertible_v<G&&, E>>* = nullptr>
constexpr explicit Expected(Unexpected<G>&& e) noexcept(std::is_nothrow_constructible_v<E, G&&>)
: impl_base{unexpect_t{}, std::move(e.value())}, ctor_base{
detail::default_constructor_tag{}} {}
template <typename G = E, std::enable_if_t<std::is_constructible_v<E, G&&>>* = nullptr,
std::enable_if_t<std::is_convertible_v<G&&, E>>* = nullptr>
constexpr Expected(Unexpected<G>&& e) noexcept(std::is_nothrow_constructible_v<E, G&&>)
: impl_base{unexpect_t{}, std::move(e.value())}, ctor_base{
detail::default_constructor_tag{}} {}
template <typename... Args, std::enable_if_t<std::is_constructible_v<E, Args&&...>>* = nullptr>
constexpr explicit Expected(unexpect_t, Args&&... args)
: impl_base{unexpect_t{}, std::forward<Args>(args)...},
ctor_base{detail::default_constructor_tag{}} {}
template <typename U, typename... Args,
std::enable_if_t<std::is_constructible_v<E, std::initializer_list<U>&, Args&&...>>* =
nullptr>
constexpr explicit Expected(unexpect_t, std::initializer_list<U> il, Args&&... args)
: impl_base{unexpect_t{}, il, std::forward<Args>(args)...},
ctor_base{detail::default_constructor_tag{}} {}
template <typename U, typename G,
std::enable_if_t<!(std::is_convertible_v<U const&, T> &&
std::is_convertible_v<G const&, E>)>* = nullptr,
detail::expected_enable_from_other<T, E, U, G, const U&, const G&>* = nullptr>
constexpr explicit Expected(const Expected<U, G>& rhs)
: ctor_base{detail::default_constructor_tag{}} {
if (rhs.has_value()) {
this->construct(*rhs);
} else {
this->construct_error(rhs.error());
}
}
template <typename U, typename G,
std::enable_if_t<(std::is_convertible_v<U const&, T> &&
std::is_convertible_v<G const&, E>)>* = nullptr,
detail::expected_enable_from_other<T, E, U, G, const U&, const G&>* = nullptr>
constexpr Expected(const Expected<U, G>& rhs) : ctor_base{detail::default_constructor_tag{}} {
if (rhs.has_value()) {
this->construct(*rhs);
} else {
this->construct_error(rhs.error());
}
}
template <typename U, typename G,
std::enable_if_t<!(std::is_convertible_v<U&&, T> && std::is_convertible_v<G&&, E>)>* =
nullptr,
detail::expected_enable_from_other<T, E, U, G, U&&, G&&>* = nullptr>
constexpr explicit Expected(Expected<U, G>&& rhs)
: ctor_base{detail::default_constructor_tag{}} {
if (rhs.has_value()) {
this->construct(std::move(*rhs));
} else {
this->construct_error(std::move(rhs.error()));
}
}
template <typename U, typename G,
std::enable_if_t<(std::is_convertible_v<U&&, T> && std::is_convertible_v<G&&, E>)>* =
nullptr,
detail::expected_enable_from_other<T, E, U, G, U&&, G&&>* = nullptr>
constexpr Expected(Expected<U, G>&& rhs) : ctor_base{detail::default_constructor_tag{}} {
if (rhs.has_value()) {
this->construct(std::move(*rhs));
} else {
this->construct_error(std::move(rhs.error()));
}
}
template <typename U = T, std::enable_if_t<!std::is_convertible_v<U&&, T>>* = nullptr,
detail::expected_enable_forward_value<T, E, U>* = nullptr>
constexpr explicit Expected(U&& v) : Expected{std::in_place, std::forward<U>(v)} {}
template <typename U = T, std::enable_if_t<std::is_convertible_v<U&&, T>>* = nullptr,
detail::expected_enable_forward_value<T, E, U>* = nullptr>
constexpr Expected(U&& v) : Expected{std::in_place, std::forward<U>(v)} {}
template <typename U = T, typename G = T,
std::enable_if_t<std::is_nothrow_constructible_v<T, U&&>>* = nullptr,
std::enable_if_t<(
!std::is_same_v<Expected<T, E>, std::remove_cvref_t<U>> &&
!std::conjunction_v<std::is_scalar<T>, std::is_same<T, std::remove_cvref_t<U>>> &&
std::is_constructible_v<T, U> && std::is_assignable_v<G&, U> &&
std::is_nothrow_move_constructible_v<E>)>* = nullptr>
Expected& operator=(U&& v) {
if (has_value()) {
val() = std::forward<U>(v);
} else {
err().~Unexpected<E>();
new (valptr()) T{std::forward<U>(v)};
this->m_has_val = true;
}
return *this;
}
template <typename U = T, typename G = T,
std::enable_if_t<!std::is_nothrow_constructible_v<T, U&&>>* = nullptr,
std::enable_if_t<(
!std::is_same_v<Expected<T, E>, std::remove_cvref_t<U>> &&
!std::conjunction_v<std::is_scalar<T>, std::is_same<T, std::remove_cvref_t<U>>> &&
std::is_constructible_v<T, U> && std::is_assignable_v<G&, U> &&
std::is_nothrow_move_constructible_v<E>)>* = nullptr>
Expected& operator=(U&& v) {
if (has_value()) {
val() = std::forward<U>(v);
} else {
auto tmp = std::move(err());
err().~Unexpected<E>();
new (valptr()) T{std::forward<U>(v)};
this->m_has_val = true;
}
return *this;
}
template <typename G = E, std::enable_if_t<std::is_nothrow_copy_constructible_v<G> &&
std::is_assignable_v<G&, G>>* = nullptr>
Expected& operator=(const Unexpected<G>& rhs) {
if (!has_value()) {
err() = rhs;
} else {
this->destroy_val();
new (errptr()) Unexpected<E>{rhs};
this->m_has_val = false;
}
return *this;
}
template <typename G = E, std::enable_if_t<std::is_nothrow_move_constructible_v<G> &&
std::is_move_assignable_v<G>>* = nullptr>
Expected& operator=(Unexpected<G>&& rhs) noexcept {
if (!has_value()) {
err() = std::move(rhs);
} else {
this->destroy_val();
new (errptr()) Unexpected<E>{std::move(rhs)};
this->m_has_val = false;
}
return *this;
}
template <typename... Args,
std::enable_if_t<std::is_nothrow_constructible_v<T, Args&&...>>* = nullptr>
void emplace(Args&&... args) {
if (has_value()) {
val() = T{std::forward<Args>(args)...};
} else {
err().~Unexpected<E>();
new (valptr()) T{std::forward<Args>(args)...};
this->m_has_val = true;
}
}
template <typename... Args,
std::enable_if_t<!std::is_nothrow_constructible_v<T, Args&&...>>* = nullptr>
void emplace(Args&&... args) {
if (has_value()) {
val() = T{std::forward<Args>(args)...};
} else {
auto tmp = std::move(err());
err().~Unexpected<E>();
new (valptr()) T{std::forward<Args>(args)...};
this->m_has_val = true;
}
}
template <typename U, typename... Args,
std::enable_if_t<std::is_nothrow_constructible_v<T, std::initializer_list<U>&,
Args&&...>>* = nullptr>
void emplace(std::initializer_list<U> il, Args&&... args) {
if (has_value()) {
T t{il, std::forward<Args>(args)...};
val() = std::move(t);
} else {
err().~Unexpected<E>();
new (valptr()) T{il, std::forward<Args>(args)...};
this->m_has_val = true;
}
}
template <typename U, typename... Args,
std::enable_if_t<!std::is_nothrow_constructible_v<T, std::initializer_list<U>&,
Args&&...>>* = nullptr>
void emplace(std::initializer_list<U> il, Args&&... args) {
if (has_value()) {
T t{il, std::forward<Args>(args)...};
val() = std::move(t);
} else {
auto tmp = std::move(err());
err().~Unexpected<E>();
new (valptr()) T{il, std::forward<Args>(args)...};
this->m_has_val = true;
}
}
constexpr T* operator->() {
return valptr();
}
constexpr const T* operator->() const {
return valptr();
}
template <typename U = T>
constexpr U& operator*() & {
return val();
}
template <typename U = T>
constexpr const U& operator*() const& {
return val();
}
template <typename U = T>
constexpr U&& operator*() && {
return std::move(val());
}
template <typename U = T>
constexpr const U&& operator*() const&& {
return std::move(val());
}
constexpr bool has_value() const noexcept {
return this->m_has_val;
}
constexpr explicit operator bool() const noexcept {
return this->m_has_val;
}
template <typename U = T>
constexpr U& value() & {
return val();
}
template <typename U = T>
constexpr const U& value() const& {
return val();
}
template <typename U = T>
constexpr U&& value() && {
return std::move(val());
}
template <typename U = T>
constexpr const U&& value() const&& {
return std::move(val());
}
constexpr E& error() & {
return err().value();
}
constexpr const E& error() const& {
return err().value();
}
constexpr E&& error() && {
return std::move(err().value());
}
constexpr const E&& error() const&& {
return std::move(err().value());
}
template <typename U>
constexpr T value_or(U&& v) const& {
static_assert(std::is_copy_constructible_v<T> && std::is_convertible_v<U&&, T>,
"T must be copy-constructible and convertible from U&&");
return bool(*this) ? **this : static_cast<T>(std::forward<U>(v));
}
template <typename U>
constexpr T value_or(U&& v) && {
static_assert(std::is_move_constructible_v<T> && std::is_convertible_v<U&&, T>,
"T must be move-constructible and convertible from U&&");
return bool(*this) ? std::move(**this) : static_cast<T>(std::forward<U>(v));
}
private:
static_assert(!std::is_reference_v<T>, "T must not be a reference");
static_assert(!std::is_same_v<T, std::remove_cv_t<std::in_place_t>>,
"T must not be std::in_place_t");
static_assert(!std::is_same_v<T, std::remove_cv_t<unexpect_t>>, "T must not be unexpect_t");
static_assert(!std::is_same_v<T, std::remove_cv_t<Unexpected<E>>>,
"T must not be Unexpected<E>");
static_assert(!std::is_reference_v<E>, "E must not be a reference");
T* valptr() {
return std::addressof(this->m_val);
}
const T* valptr() const {
return std::addressof(this->m_val);
}
Unexpected<E>* errptr() {
return std::addressof(this->m_unexpect);
}
const Unexpected<E>* errptr() const {
return std::addressof(this->m_unexpect);
}
template <typename U = T>
constexpr U& val() {
return this->m_val;
}
template <typename U = T>
constexpr const U& val() const {
return this->m_val;
}
constexpr Unexpected<E>& err() {
return this->m_unexpect;
}
constexpr const Unexpected<E>& err() const {
return this->m_unexpect;
}
using impl_base = detail::expected_move_assign_base<T, E>;
using ctor_base = detail::expected_default_ctor_base<T, E>;
};
template <typename T, typename E, typename U, typename F>
constexpr bool operator==(const Expected<T, E>& lhs, const Expected<U, F>& rhs) {
return (lhs.has_value() != rhs.has_value())
? false
: (!lhs.has_value() ? lhs.error() == rhs.error() : *lhs == *rhs);
}
template <typename T, typename E, typename U, typename F>
constexpr bool operator!=(const Expected<T, E>& lhs, const Expected<U, F>& rhs) {
return !operator==(lhs, rhs);
}
template <typename T, typename E, typename U>
constexpr bool operator==(const Expected<T, E>& x, const U& v) {
return x.has_value() ? *x == v : false;
}
template <typename T, typename E, typename U>
constexpr bool operator==(const U& v, const Expected<T, E>& x) {
return x.has_value() ? *x == v : false;
}
template <typename T, typename E, typename U>
constexpr bool operator!=(const Expected<T, E>& x, const U& v) {
return !operator==(x, v);
}
template <typename T, typename E, typename U>
constexpr bool operator!=(const U& v, const Expected<T, E>& x) {
return !operator==(v, x);
}
template <typename T, typename E>
constexpr bool operator==(const Expected<T, E>& x, const Unexpected<E>& e) {
return x.has_value() ? false : x.error() == e.value();
}
template <typename T, typename E>
constexpr bool operator==(const Unexpected<E>& e, const Expected<T, E>& x) {
return x.has_value() ? false : x.error() == e.value();
}
template <typename T, typename E>
constexpr bool operator!=(const Expected<T, E>& x, const Unexpected<E>& e) {
return !operator==(x, e);
}
template <typename T, typename E>
constexpr bool operator!=(const Unexpected<E>& e, const Expected<T, E>& x) {
return !operator==(e, x);
}
} // namespace Common

View file

@ -42,7 +42,7 @@ public:
if (offset > size) {
return ERR_WRITE_BEYOND_END;
} else if (offset == size) {
return MakeResult<std::size_t>(0);
return 0ULL;
}
if (offset + length > size) {
@ -150,11 +150,9 @@ public:
Mode rwmode;
rwmode.write_flag.Assign(1);
rwmode.read_flag.Assign(1);
std::unique_ptr<DelayGenerator> delay_generator =
std::make_unique<ExtSaveDataDelayGenerator>();
auto disk_file =
std::make_unique<FixSizeDiskFile>(std::move(file), rwmode, std::move(delay_generator));
return MakeResult<std::unique_ptr<FileBackend>>(std::move(disk_file));
auto delay_generator = std::make_unique<ExtSaveDataDelayGenerator>();
return std::make_unique<FixSizeDiskFile>(std::move(file), rwmode,
std::move(delay_generator));
}
ResultCode CreateFile(const Path& path, u64 size) const override {
@ -255,8 +253,7 @@ ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_ExtSaveData::Open(cons
}
}
std::unique_ptr<DelayGenerator> delay_generator = std::make_unique<ExtSaveDataDelayGenerator>();
auto archive = std::make_unique<ExtSaveDataArchive>(fullpath, std::move(delay_generator));
return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive));
return std::make_unique<ExtSaveDataArchive>(fullpath, std::move(delay_generator));
}
ResultCode ArchiveFactory_ExtSaveData::Format(const Path& path,
@ -276,7 +273,7 @@ ResultCode ArchiveFactory_ExtSaveData::Format(const Path& path,
if (!file.IsOpen()) {
// TODO(Subv): Find the correct error code
return ResultCode(-1);
return RESULT_UNKNOWN;
}
file.WriteBytes(&format_info, sizeof(format_info));
@ -296,7 +293,7 @@ ResultVal<ArchiveFormatInfo> ArchiveFactory_ExtSaveData::GetFormatInfo(const Pat
ArchiveFormatInfo info = {};
file.ReadBytes(&info, sizeof(info));
return MakeResult<ArchiveFormatInfo>(info);
return info;
}
void ArchiveFactory_ExtSaveData::WriteIcon(const Path& path, const u8* icon_data,

View file

@ -170,16 +170,14 @@ ResultVal<std::unique_ptr<FileBackend>> NCCHArchive::OpenFile(const Path& path,
if (!archive_data.empty()) {
u64 romfs_offset = 0;
u64 romfs_size = archive_data.size();
std::unique_ptr<DelayGenerator> delay_generator =
std::make_unique<RomFSDelayGenerator>();
file = std::make_unique<IVFCFileInMemory>(std::move(archive_data), romfs_offset,
auto delay_generator = std::make_unique<RomFSDelayGenerator>();
return std::make_unique<IVFCFileInMemory>(std::move(archive_data), romfs_offset,
romfs_size, std::move(delay_generator));
return MakeResult<std::unique_ptr<FileBackend>>(std::move(file));
}
return ERROR_NOT_FOUND;
}
return MakeResult<std::unique_ptr<FileBackend>>(std::move(file));
return file;
}
ResultCode NCCHArchive::DeleteFile(const Path& path) const {
@ -192,21 +190,21 @@ ResultCode NCCHArchive::DeleteFile(const Path& path) const {
ResultCode NCCHArchive::RenameFile(const Path& src_path, const Path& dest_path) const {
LOG_CRITICAL(Service_FS, "Attempted to rename a file within an NCCH archive ({}).", GetName());
// TODO(wwylele): Use correct error code
return ResultCode(-1);
return RESULT_UNKNOWN;
}
ResultCode NCCHArchive::DeleteDirectory(const Path& path) const {
LOG_CRITICAL(Service_FS, "Attempted to delete a directory from an NCCH archive ({}).",
GetName());
// TODO(wwylele): Use correct error code
return ResultCode(-1);
return RESULT_UNKNOWN;
}
ResultCode NCCHArchive::DeleteDirectoryRecursively(const Path& path) const {
LOG_CRITICAL(Service_FS, "Attempted to delete a directory from an NCCH archive ({}).",
GetName());
// TODO(wwylele): Use correct error code
return ResultCode(-1);
return RESULT_UNKNOWN;
}
ResultCode NCCHArchive::CreateFile(const Path& path, u64 size) const {
@ -219,20 +217,20 @@ ResultCode NCCHArchive::CreateFile(const Path& path, u64 size) const {
ResultCode NCCHArchive::CreateDirectory(const Path& path) const {
LOG_CRITICAL(Service_FS, "Attempted to create a directory in an NCCH archive ({}).", GetName());
// TODO(wwylele): Use correct error code
return ResultCode(-1);
return RESULT_UNKNOWN;
}
ResultCode NCCHArchive::RenameDirectory(const Path& src_path, const Path& dest_path) const {
LOG_CRITICAL(Service_FS, "Attempted to rename a file within an NCCH archive ({}).", GetName());
// TODO(wwylele): Use correct error code
return ResultCode(-1);
return RESULT_UNKNOWN;
}
ResultVal<std::unique_ptr<DirectoryBackend>> NCCHArchive::OpenDirectory(const Path& path) const {
LOG_CRITICAL(Service_FS, "Attempted to open a directory within an NCCH archive ({}).",
GetName().c_str());
// TODO(shinyquagsire23): Use correct error code
return ResultCode(-1);
return RESULT_UNKNOWN;
}
u64 NCCHArchive::GetFreeBytes() const {
@ -253,14 +251,14 @@ ResultVal<std::size_t> NCCHFile::Read(const u64 offset, const std::size_t length
std::size_t copy_size = std::min(length, available_size);
memcpy(buffer, file_buffer.data() + offset, copy_size);
return MakeResult<std::size_t>(copy_size);
return copy_size;
}
ResultVal<std::size_t> NCCHFile::Write(const u64 offset, const std::size_t length, const bool flush,
const u8* buffer) {
LOG_ERROR(Service_FS, "Attempted to write to NCCH file");
// TODO(shinyquagsire23): Find error code
return MakeResult<std::size_t>(0);
return 0ULL;
}
u64 NCCHFile::GetSize() const {
@ -290,9 +288,8 @@ ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_NCCH::Open(const Path&
NCCHArchivePath open_path;
std::memcpy(&open_path, binary.data(), sizeof(NCCHArchivePath));
auto archive = std::make_unique<NCCHArchive>(
return std::make_unique<NCCHArchive>(
open_path.tid, static_cast<Service::FS::MediaType>(open_path.media_type & 0xFF));
return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive));
}
ResultCode ArchiveFactory_NCCH::Format(const Path& path,
@ -308,7 +305,7 @@ ResultVal<ArchiveFormatInfo> ArchiveFactory_NCCH::GetFormatInfo(const Path& path
u64 program_id) const {
// TODO(Subv): Implement
LOG_ERROR(Service_FS, "Unimplemented GetFormatInfo archive {}", GetName());
return ResultCode(-1);
return RESULT_UNKNOWN;
}
} // namespace FileSys

View file

@ -45,7 +45,7 @@ ResultVal<std::tuple<MediaType, u64>> ParsePath(const Path& path, T program_id_r
return ERROR_UNSUPPORTED_OPEN_FLAGS;
}
return MakeResult<std::tuple<MediaType, u64>>(media_type, program_id_reader(data));
return std::make_tuple(media_type, program_id_reader(data));
}
ResultVal<std::tuple<MediaType, u64>> ParsePathPermitted(const Path& path) {

View file

@ -108,8 +108,7 @@ ResultVal<std::unique_ptr<FileBackend>> SDMCArchive::OpenFileBase(const Path& pa
}
std::unique_ptr<DelayGenerator> delay_generator = std::make_unique<SDMCDelayGenerator>();
auto disk_file = std::make_unique<DiskFile>(std::move(file), mode, std::move(delay_generator));
return MakeResult<std::unique_ptr<FileBackend>>(std::move(disk_file));
return std::make_unique<DiskFile>(std::move(file), mode, std::move(delay_generator));
}
ResultCode SDMCArchive::DeleteFile(const Path& path) const {
@ -358,8 +357,7 @@ ResultVal<std::unique_ptr<DirectoryBackend>> SDMCArchive::OpenDirectory(const Pa
break; // Expected 'success' case
}
auto directory = std::make_unique<DiskDirectory>(full_path);
return MakeResult<std::unique_ptr<DirectoryBackend>>(std::move(directory));
return std::make_unique<DiskDirectory>(full_path);
}
u64 SDMCArchive::GetFreeBytes() const {
@ -390,8 +388,7 @@ bool ArchiveFactory_SDMC::Initialize() {
ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_SDMC::Open(const Path& path,
u64 program_id) {
std::unique_ptr<DelayGenerator> delay_generator = std::make_unique<SDMCDelayGenerator>();
auto archive = std::make_unique<SDMCArchive>(sdmc_directory, std::move(delay_generator));
return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive));
return std::make_unique<SDMCArchive>(sdmc_directory, std::move(delay_generator));
}
ResultCode ArchiveFactory_SDMC::Format(const Path& path,
@ -405,7 +402,7 @@ ResultVal<ArchiveFormatInfo> ArchiveFactory_SDMC::GetFormatInfo(const Path& path
u64 program_id) const {
// TODO(Subv): Implement
LOG_ERROR(Service_FS, "Unimplemented GetFormatInfo archive {}", GetName());
return ResultCode(-1);
return RESULT_UNKNOWN;
}
} // namespace FileSys

View file

@ -78,9 +78,7 @@ ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_SDMCWriteOnly::Open(co
u64 program_id) {
std::unique_ptr<DelayGenerator> delay_generator =
std::make_unique<SDMCWriteOnlyDelayGenerator>();
auto archive =
std::make_unique<SDMCWriteOnlyArchive>(sdmc_directory, std::move(delay_generator));
return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive));
return std::make_unique<SDMCWriteOnlyArchive>(sdmc_directory, std::move(delay_generator));
}
ResultCode ArchiveFactory_SDMCWriteOnly::Format(const Path& path,
@ -88,14 +86,14 @@ ResultCode ArchiveFactory_SDMCWriteOnly::Format(const Path& path,
u64 program_id) {
// TODO(wwylele): hwtest this
LOG_ERROR(Service_FS, "Attempted to format a SDMC write-only archive.");
return ResultCode(-1);
return RESULT_UNKNOWN;
}
ResultVal<ArchiveFormatInfo> ArchiveFactory_SDMCWriteOnly::GetFormatInfo(const Path& path,
u64 program_id) const {
// TODO(Subv): Implement
LOG_ERROR(Service_FS, "Unimplemented GetFormatInfo archive {}", GetName());
return ResultCode(-1);
return RESULT_UNKNOWN;
}
} // namespace FileSys

View file

@ -48,7 +48,7 @@ public:
}
std::memcpy(buffer, data->data(), data->size());
return MakeResult<std::size_t>(data->size());
return data->size();
}
ResultVal<std::size_t> Write(u64 offset, std::size_t length, bool flush,
@ -183,8 +183,7 @@ private:
if (ncch_data.romfs_file) {
std::unique_ptr<DelayGenerator> delay_generator =
std::make_unique<RomFSDelayGenerator>();
return MakeResult<std::unique_ptr<FileBackend>>(
std::make_unique<IVFCFile>(ncch_data.romfs_file, std::move(delay_generator)));
return std::make_unique<IVFCFile>(ncch_data.romfs_file, std::move(delay_generator));
} else {
LOG_INFO(Service_FS, "Unable to read RomFS");
return ERROR_ROMFS_NOT_FOUND;
@ -195,8 +194,8 @@ private:
if (ncch_data.update_romfs_file) {
std::unique_ptr<DelayGenerator> delay_generator =
std::make_unique<RomFSDelayGenerator>();
return MakeResult<std::unique_ptr<FileBackend>>(std::make_unique<IVFCFile>(
ncch_data.update_romfs_file, std::move(delay_generator)));
return std::make_unique<IVFCFile>(ncch_data.update_romfs_file,
std::move(delay_generator));
} else {
LOG_INFO(Service_FS, "Unable to read update RomFS");
return ERROR_ROMFS_NOT_FOUND;
@ -206,8 +205,7 @@ private:
ResultVal<std::unique_ptr<FileBackend>> OpenExeFS(const std::string& filename) const {
if (filename == "icon") {
if (ncch_data.icon) {
return MakeResult<std::unique_ptr<FileBackend>>(
std::make_unique<ExeFSSectionFile>(ncch_data.icon));
return std::make_unique<ExeFSSectionFile>(ncch_data.icon);
}
LOG_WARNING(Service_FS, "Unable to read icon");
@ -216,8 +214,7 @@ private:
if (filename == "logo") {
if (ncch_data.logo) {
return MakeResult<std::unique_ptr<FileBackend>>(
std::make_unique<ExeFSSectionFile>(ncch_data.logo));
return std::make_unique<ExeFSSectionFile>(ncch_data.logo);
}
LOG_WARNING(Service_FS, "Unable to read logo");
@ -226,8 +223,7 @@ private:
if (filename == "banner") {
if (ncch_data.banner) {
return MakeResult<std::unique_ptr<FileBackend>>(
std::make_unique<ExeFSSectionFile>(ncch_data.banner));
return std::make_unique<ExeFSSectionFile>(ncch_data.banner);
}
LOG_WARNING(Service_FS, "Unable to read banner");
@ -297,8 +293,7 @@ void ArchiveFactory_SelfNCCH::Register(Loader::AppLoader& app_loader) {
ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_SelfNCCH::Open(const Path& path,
u64 program_id) {
auto archive = std::make_unique<SelfNCCHArchive>(ncch_data[program_id]);
return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive));
return std::make_unique<SelfNCCHArchive>(ncch_data[program_id]);
}
ResultCode ArchiveFactory_SelfNCCH::Format(const Path&, const FileSys::ArchiveFormatInfo&,

View file

@ -50,8 +50,7 @@ ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveSource_SDSaveData::Open(u64 pr
return ERR_NOT_FORMATTED;
}
auto archive = std::make_unique<SaveDataArchive>(std::move(concrete_mount_point));
return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive));
return std::make_unique<SaveDataArchive>(std::move(concrete_mount_point));
}
ResultCode ArchiveSource_SDSaveData::Format(u64 program_id,
@ -83,7 +82,7 @@ ResultVal<ArchiveFormatInfo> ArchiveSource_SDSaveData::GetFormatInfo(u64 program
ArchiveFormatInfo info = {};
file.ReadBytes(&info, sizeof(info));
return MakeResult<ArchiveFormatInfo>(info);
return info;
}
std::string ArchiveSource_SDSaveData::GetSaveDataPathFor(const std::string& mount_point,

View file

@ -59,8 +59,7 @@ ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_SystemSaveData::Open(c
// TODO(Subv): Check error code, this one is probably wrong
return ERROR_NOT_FOUND;
}
auto archive = std::make_unique<SaveDataArchive>(fullpath);
return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive));
return std::make_unique<SaveDataArchive>(fullpath);
}
ResultCode ArchiveFactory_SystemSaveData::Format(const Path& path,
@ -76,7 +75,7 @@ ResultVal<ArchiveFormatInfo> ArchiveFactory_SystemSaveData::GetFormatInfo(const
u64 program_id) const {
// TODO(Subv): Implement
LOG_ERROR(Service_FS, "Unimplemented GetFormatInfo archive {}", GetName());
return ResultCode(-1);
return RESULT_UNKNOWN;
}
} // namespace FileSys

View file

@ -22,7 +22,7 @@ ResultVal<std::size_t> DiskFile::Read(const u64 offset, const std::size_t length
return ERROR_INVALID_OPEN_FLAGS;
file->Seek(offset, SEEK_SET);
return MakeResult<std::size_t>(file->ReadBytes(buffer, length));
return file->ReadBytes(buffer, length);
}
ResultVal<std::size_t> DiskFile::Write(const u64 offset, const std::size_t length, const bool flush,
@ -34,7 +34,7 @@ ResultVal<std::size_t> DiskFile::Write(const u64 offset, const std::size_t lengt
std::size_t written = file->WriteBytes(buffer, length);
if (flush)
file->Flush();
return MakeResult<std::size_t>(written);
return written;
}
u64 DiskFile::GetSize() const {

View file

@ -31,8 +31,7 @@ std::string IVFCArchive::GetName() const {
ResultVal<std::unique_ptr<FileBackend>> IVFCArchive::OpenFile(const Path& path,
const Mode& mode) const {
std::unique_ptr<DelayGenerator> delay_generator = std::make_unique<IVFCDelayGenerator>();
return MakeResult<std::unique_ptr<FileBackend>>(
std::make_unique<IVFCFile>(romfs_file, std::move(delay_generator)));
return std::make_unique<IVFCFile>(romfs_file, std::move(delay_generator));
}
ResultCode IVFCArchive::DeleteFile(const Path& path) const {
@ -45,21 +44,21 @@ ResultCode IVFCArchive::DeleteFile(const Path& path) const {
ResultCode IVFCArchive::RenameFile(const Path& src_path, const Path& dest_path) const {
LOG_CRITICAL(Service_FS, "Attempted to rename a file within an IVFC archive ({}).", GetName());
// TODO(wwylele): Use correct error code
return ResultCode(-1);
return RESULT_UNKNOWN;
}
ResultCode IVFCArchive::DeleteDirectory(const Path& path) const {
LOG_CRITICAL(Service_FS, "Attempted to delete a directory from an IVFC archive ({}).",
GetName());
// TODO(wwylele): Use correct error code
return ResultCode(-1);
return RESULT_UNKNOWN;
}
ResultCode IVFCArchive::DeleteDirectoryRecursively(const Path& path) const {
LOG_CRITICAL(Service_FS, "Attempted to delete a directory from an IVFC archive ({}).",
GetName());
// TODO(wwylele): Use correct error code
return ResultCode(-1);
return RESULT_UNKNOWN;
}
ResultCode IVFCArchive::CreateFile(const Path& path, u64 size) const {
@ -72,17 +71,17 @@ ResultCode IVFCArchive::CreateFile(const Path& path, u64 size) const {
ResultCode IVFCArchive::CreateDirectory(const Path& path) const {
LOG_CRITICAL(Service_FS, "Attempted to create a directory in an IVFC archive ({}).", GetName());
// TODO(wwylele): Use correct error code
return ResultCode(-1);
return RESULT_UNKNOWN;
}
ResultCode IVFCArchive::RenameDirectory(const Path& src_path, const Path& dest_path) const {
LOG_CRITICAL(Service_FS, "Attempted to rename a file within an IVFC archive ({}).", GetName());
// TODO(wwylele): Use correct error code
return ResultCode(-1);
return RESULT_UNKNOWN;
}
ResultVal<std::unique_ptr<DirectoryBackend>> IVFCArchive::OpenDirectory(const Path& path) const {
return MakeResult<std::unique_ptr<DirectoryBackend>>(std::make_unique<IVFCDirectory>());
return std::make_unique<IVFCDirectory>();
}
u64 IVFCArchive::GetFreeBytes() const {
@ -99,14 +98,14 @@ IVFCFile::IVFCFile(std::shared_ptr<RomFSReader> file,
ResultVal<std::size_t> IVFCFile::Read(const u64 offset, const std::size_t length,
u8* buffer) const {
LOG_TRACE(Service_FS, "called offset={}, length={}", offset, length);
return MakeResult<std::size_t>(romfs_file->ReadFile(offset, length, buffer));
return romfs_file->ReadFile(offset, length, buffer);
}
ResultVal<std::size_t> IVFCFile::Write(const u64 offset, const std::size_t length, const bool flush,
const u8* buffer) {
LOG_ERROR(Service_FS, "Attempted to write to IVFC file");
// TODO(Subv): Find error code
return MakeResult<std::size_t>(0);
return 0ULL;
}
u64 IVFCFile::GetSize() const {
@ -130,14 +129,14 @@ ResultVal<std::size_t> IVFCFileInMemory::Read(const u64 offset, const std::size_
std::size_t read_length = (std::size_t)std::min((u64)length, data_size - offset);
std::memcpy(buffer, romfs_file.data() + data_offset + offset, read_length);
return MakeResult<std::size_t>(read_length);
return read_length;
}
ResultVal<std::size_t> IVFCFileInMemory::Write(const u64 offset, const std::size_t length,
const bool flush, const u8* buffer) {
LOG_ERROR(Service_FS, "Attempted to write to IVFC file");
// TODO(Subv): Find error code
return MakeResult<std::size_t>(0);
return 0ULL;
}
u64 IVFCFileInMemory::GetSize() const {

View file

@ -90,8 +90,7 @@ ResultVal<std::unique_ptr<FileBackend>> SaveDataArchive::OpenFile(const Path& pa
}
std::unique_ptr<DelayGenerator> delay_generator = std::make_unique<SaveDataDelayGenerator>();
auto disk_file = std::make_unique<DiskFile>(std::move(file), mode, std::move(delay_generator));
return MakeResult<std::unique_ptr<FileBackend>>(std::move(disk_file));
return std::make_unique<DiskFile>(std::move(file), mode, std::move(delay_generator));
}
ResultCode SaveDataArchive::DeleteFile(const Path& path) const {
@ -343,8 +342,7 @@ ResultVal<std::unique_ptr<DirectoryBackend>> SaveDataArchive::OpenDirectory(
break; // Expected 'success' case
}
auto directory = std::make_unique<DiskDirectory>(full_path);
return MakeResult<std::unique_ptr<DirectoryBackend>>(std::move(directory));
return std::make_unique<DiskDirectory>(full_path);
}
u64 SaveDataArchive::GetFreeBytes() const {

View file

@ -40,7 +40,7 @@ ResultVal<std::shared_ptr<ClientSession>> ClientPort::Connect() {
// Wake the threads waiting on the ServerPort
server_port->WakeupAllWaitingThreads();
return MakeResult(client);
return client;
}
void ClientPort::ConnectionClosed() {

View file

@ -49,7 +49,7 @@ ResultVal<Handle> HandleTable::Create(std::shared_ptr<Object> obj) {
objects[slot] = std::move(obj);
Handle handle = generation | (slot << 15);
return MakeResult<Handle>(handle);
return handle;
}
ResultVal<Handle> HandleTable::Duplicate(Handle handle) {

View file

@ -271,7 +271,7 @@ ResultVal<VAddr> Process::HeapAllocate(VAddr target, u32 size, VMAPermission per
memory_used += size;
resource_limit->current_commit += size;
return MakeResult<VAddr>(target);
return target;
}
ResultCode Process::HeapFree(VAddr target, u32 size) {
@ -344,7 +344,7 @@ ResultVal<VAddr> Process::LinearAllocate(VAddr target, u32 size, VMAPermission p
resource_limit->current_commit += size;
LOG_DEBUG(Kernel, "Allocated at target={:08X}", target);
return MakeResult<VAddr>(target);
return target;
}
ResultCode Process::LinearFree(VAddr target, u32 size) {

View file

@ -31,7 +31,7 @@ ResultVal<std::shared_ptr<Semaphore>> KernelSystem::CreateSemaphore(s32 initial_
semaphore->available_count = initial_count;
semaphore->name = std::move(name);
return MakeResult<std::shared_ptr<Semaphore>>(std::move(semaphore));
return semaphore;
}
bool Semaphore::ShouldWait(const Thread* thread) const {
@ -53,7 +53,7 @@ ResultVal<s32> Semaphore::Release(s32 release_count) {
WakeupAllWaitingThreads();
return MakeResult<s32>(previous_count);
return previous_count;
}
} // namespace Kernel

View file

@ -31,7 +31,7 @@ ResultVal<std::shared_ptr<ServerSession>> ServerPort::Accept() {
auto session = std::move(pending_sessions.back());
pending_sessions.pop_back();
return MakeResult(std::move(session));
return session;
}
bool ServerPort::ShouldWait(const Thread* thread) const {

View file

@ -52,7 +52,7 @@ ResultVal<std::shared_ptr<ServerSession>> ServerSession::Create(KernelSystem& ke
server_session->name = std::move(name);
server_session->parent = nullptr;
return MakeResult(std::move(server_session));
return server_session;
}
bool ServerSession::ShouldWait(const Thread* thread) const {

View file

@ -69,7 +69,7 @@ ResultVal<std::shared_ptr<SharedMemory>> KernelSystem::CreateSharedMemory(
}
shared_memory->base_address = address;
return MakeResult(shared_memory);
return shared_memory;
}
std::shared_ptr<SharedMemory> KernelSystem::CreateSharedMemoryForApplet(

View file

@ -674,7 +674,7 @@ ResultCode SVC::OpenProcess(Handle* out_handle, u32 process_id) {
return ResultCode(24, ErrorModule::OS, ErrorSummary::WrongArgument, ErrorLevel::Permanent);
}
auto result_handle = kernel.GetCurrentProcess()->handle_table.Create(process);
if (result_handle.empty()) {
if (!result_handle) {
return result_handle.Code();
}
*out_handle = result_handle.Unwrap();
@ -699,7 +699,7 @@ ResultCode SVC::OpenThread(Handle* out_handle, Handle process_handle, u32 thread
for (auto& thread : thread_list) {
if (thread->owner_process.lock() == process && thread.get()->thread_id == thread_id) {
auto result_handle = kernel.GetCurrentProcess()->handle_table.Create(thread);
if (result_handle.empty()) {
if (!result_handle) {
return result_handle.Code();
}
*out_handle = result_handle.Unwrap();

View file

@ -423,7 +423,7 @@ ResultVal<std::shared_ptr<Thread>> KernelSystem::CreateThread(
thread_managers[processor_id]->ready_queue.push_back(thread->current_priority, thread.get());
thread->status = ThreadStatus::Ready;
return MakeResult<std::shared_ptr<Thread>>(std::move(thread));
return thread;
}
void Thread::SetPriority(u32 priority) {

View file

@ -96,7 +96,7 @@ ResultVal<VAddr> VMManager::MapBackingMemoryToBase(VAddr base, u32 region_size,
if (result.Failed())
return result.Code();
return MakeResult<VAddr>(target);
return target;
}
ResultVal<VMManager::VMAHandle> VMManager::MapBackingMemory(VAddr target, MemoryRef memory,
@ -115,7 +115,7 @@ ResultVal<VMManager::VMAHandle> VMManager::MapBackingMemory(VAddr target, Memory
final_vma.backing_memory = memory;
UpdatePageTableForVMA(final_vma);
return MakeResult<VMAHandle>(MergeAdjacent(vma_handle));
return MergeAdjacent(vma_handle);
}
ResultVal<VMManager::VMAHandle> VMManager::MapMMIO(VAddr target, PAddr paddr, u32 size,
@ -135,7 +135,7 @@ ResultVal<VMManager::VMAHandle> VMManager::MapMMIO(VAddr target, PAddr paddr, u3
final_vma.mmio_handler = mmio_handler;
UpdatePageTableForVMA(final_vma);
return MakeResult<VMAHandle>(MergeAdjacent(vma_handle));
return MergeAdjacent(vma_handle);
}
ResultCode VMManager::ChangeMemoryState(VAddr target, u32 size, MemoryState expected_state,
@ -294,7 +294,7 @@ ResultVal<VMManager::VMAIter> VMManager::CarveVMA(VAddr base, u32 size) {
vma_handle = SplitVMA(vma_handle, start_in_vma);
}
return MakeResult<VMAIter>(vma_handle);
return vma_handle;
}
ResultVal<VMManager::VMAIter> VMManager::CarveVMARange(VAddr target, u32 size) {
@ -322,7 +322,7 @@ ResultVal<VMManager::VMAIter> VMManager::CarveVMARange(VAddr target, u32 size) {
end_vma = SplitVMA(end_vma, target_end - end_vma->second.base);
}
return MakeResult<VMAIter>(begin_vma);
return begin_vma;
}
VMManager::VMAIter VMManager::SplitVMA(VMAIter vma_handle, u32 offset_in_vma) {
@ -409,6 +409,6 @@ ResultVal<std::vector<std::pair<MemoryRef, u32>>> VMManager::GetBackingBlocksFor
interval_target += interval_size;
}
return MakeResult(backing_blocks);
return backing_blocks;
}
} // namespace Kernel

View file

@ -4,13 +4,12 @@
#pragma once
#include <new>
#include <utility>
#include <boost/serialization/access.hpp>
#include "common/assert.h"
#include "common/bit_field.h"
#include "common/common_funcs.h"
#include "common/common_types.h"
#include "common/expected.h"
// All the constants in this file come from http://3dbrew.org/wiki/Error_codes
@ -255,12 +254,19 @@ constexpr ResultCode UnimplementedFunction(ErrorModule module) {
}
/**
* This is an optional value type. It holds a `ResultCode` and, if that code is a success code,
* also holds a result of type `T`. If the code is an error code then trying to access the inner
* value fails, thus ensuring that the ResultCode of functions is always checked properly before
* their return value is used. It is similar in concept to the `std::optional` type
* (http://en.cppreference.com/w/cpp/experimental/optional) originally proposed for inclusion in
* C++14, or the `Result` type in Rust (http://doc.rust-lang.org/std/result/index.html).
* Placeholder result code used for unknown error codes.
*
* @note This should only be used when a particular error code
* is not known yet.
*/
constexpr ResultCode RESULT_UNKNOWN(UINT32_MAX);
/**
* This is an optional value type. It holds a `ResultCode` and, if that code is ResultSuccess, it
* also holds a result of type `T`. If the code is an error code (not ResultSuccess), then trying
* to access the inner value with operator* is undefined behavior and will assert with Unwrap().
* Users of this class must be cognizant to check the status of the ResultVal with operator bool(),
* Code(), Succeeded() or Failed() prior to accessing the inner value.
*
* An example of how it could be used:
* \code
@ -271,166 +277,117 @@ constexpr ResultCode UnimplementedFunction(ErrorModule module) {
* ErrorSummary::InvalidArgument, ErrorLevel::Permanent);
* } else {
* // Frobnicated! Give caller a cookie
* return MakeResult<int>(42);
* return 42;
* }
* }
* \endcode
*
* \code
* ResultVal<int> frob_result = Frobnicate(0.75f);
* auto frob_result = Frobnicate(0.75f);
* if (frob_result) {
* // Frobbed ok
* printf("My cookie is %d\n", *frob_result);
* } else {
* printf("Guess I overdid it. :( Error code: %ux\n", frob_result.code().hex);
* printf("Guess I overdid it. :( Error code: %ux\n", frob_result.Code().raw);
* }
* \endcode
*/
template <typename T>
class ResultVal {
public:
/// Constructs an empty `ResultVal` with the given error code. The code must not be a success
/// code.
ResultVal(ResultCode error_code = ResultCode(-1)) : result_code(error_code) {
ASSERT(error_code.IsError());
}
constexpr ResultVal() : expected{} {}
/**
* Similar to the non-member function `MakeResult`, with the exception that you can manually
* specify the success code. `success_code` must not be an error code.
*/
template <typename... Args>
static ResultVal WithCode(ResultCode success_code, Args&&... args) {
ResultVal<T> result;
result.emplace(success_code, std::forward<Args>(args)...);
return result;
}
constexpr ResultVal(ResultCode code) : expected{Common::Unexpected(code)} {}
ResultVal(const ResultVal& o) : result_code(o.result_code) {
if (!o.empty()) {
new (&object) T(o.object);
}
}
ResultVal(ResultVal&& o) : result_code(o.result_code) {
if (!o.empty()) {
new (&object) T(std::move(o.object));
}
}
~ResultVal() {
if (!empty()) {
object.~T();
}
}
ResultVal& operator=(const ResultVal& o) {
if (!empty()) {
if (!o.empty()) {
object = o.object;
} else {
object.~T();
}
} else {
if (!o.empty()) {
new (&object) T(o.object);
}
}
result_code = o.result_code;
return *this;
}
/**
* Replaces the current result with a new constructed result value in-place. The code must not
* be an error code.
*/
template <typename... Args>
void emplace(ResultCode success_code, Args&&... args) {
ASSERT(success_code.IsSuccess());
if (!empty()) {
object.~T();
}
new (&object) T(std::forward<Args>(args)...);
result_code = success_code;
}
/// Returns true if the `ResultVal` contains an error code and no value.
bool empty() const {
return result_code.IsError();
}
/// Returns true if the `ResultVal` contains a return value.
bool Succeeded() const {
return result_code.IsSuccess();
}
/// Returns true if the `ResultVal` contains an error code and no value.
bool Failed() const {
return empty();
}
ResultCode Code() const {
return result_code;
}
const T& operator*() const {
return object;
}
T& operator*() {
return object;
}
const T* operator->() const {
return &object;
}
T* operator->() {
return &object;
}
/// Returns the value contained in this `ResultVal`, or the supplied default if it is missing.
template <typename U>
T ValueOr(U&& value) const {
return !empty() ? object : std::move(value);
constexpr ResultVal(U&& val) : expected{std::forward<U>(val)} {}
template <typename... Args>
constexpr ResultVal(Args&&... args) : expected{std::in_place, std::forward<Args>(args)...} {}
~ResultVal() = default;
constexpr ResultVal(const ResultVal&) = default;
constexpr ResultVal(ResultVal&&) = default;
ResultVal& operator=(const ResultVal&) = default;
ResultVal& operator=(ResultVal&&) = default;
[[nodiscard]] constexpr explicit operator bool() const noexcept {
return expected.has_value();
}
/// Asserts that the result succeeded and returns a reference to it.
T& Unwrap() & {
ASSERT_MSG(Succeeded(), "Tried to Unwrap empty ResultVal");
return **this;
[[nodiscard]] constexpr ResultCode Code() const {
return expected.has_value() ? RESULT_SUCCESS : expected.error();
}
T&& Unwrap() && {
[[nodiscard]] constexpr bool Succeeded() const {
return expected.has_value();
}
[[nodiscard]] constexpr bool Failed() const {
return !expected.has_value();
}
[[nodiscard]] constexpr T* operator->() {
return std::addressof(expected.value());
}
[[nodiscard]] constexpr const T* operator->() const {
return std::addressof(expected.value());
}
[[nodiscard]] constexpr T& operator*() & {
return *expected;
}
[[nodiscard]] constexpr const T& operator*() const& {
return *expected;
}
[[nodiscard]] constexpr T&& operator*() && {
return *expected;
}
[[nodiscard]] constexpr const T&& operator*() const&& {
return *expected;
}
[[nodiscard]] constexpr T& Unwrap() & {
ASSERT_MSG(Succeeded(), "Tried to Unwrap empty ResultVal");
return std::move(**this);
return expected.value();
}
[[nodiscard]] constexpr const T& Unwrap() const& {
ASSERT_MSG(Succeeded(), "Tried to Unwrap empty ResultVal");
return expected.value();
}
[[nodiscard]] constexpr T&& Unwrap() && {
ASSERT_MSG(Succeeded(), "Tried to Unwrap empty ResultVal");
return std::move(expected.value());
}
[[nodiscard]] constexpr const T&& Unwrap() const&& {
ASSERT_MSG(Succeeded(), "Tried to Unwrap empty ResultVal");
return std::move(expected.value());
}
template <typename U>
[[nodiscard]] constexpr T ValueOr(U&& v) const& {
return expected.value_or(v);
}
template <typename U>
[[nodiscard]] constexpr T ValueOr(U&& v) && {
return expected.value_or(v);
}
private:
// A union is used to allocate the storage for the value, while allowing us to construct and
// destruct it at will.
union {
T object;
};
ResultCode result_code;
// TODO: Replace this with std::expected once it is standardized in the STL.
Common::Expected<T, ResultCode> expected;
};
/**
* This function is a helper used to construct `ResultVal`s. It receives the arguments to construct
* `T` with and creates a success `ResultVal` contained the constructed value.
*/
template <typename T, typename... Args>
ResultVal<T> MakeResult(Args&&... args) {
return ResultVal<T>::WithCode(RESULT_SUCCESS, std::forward<Args>(args)...);
}
/**
* Deducible overload of MakeResult, allowing the template parameter to be ommited if you're just
* copy or move constructing.
*/
template <typename Arg>
ResultVal<std::remove_reference_t<Arg>> MakeResult(Arg&& arg) {
return ResultVal<std::remove_reference_t<Arg>>::WithCode(RESULT_SUCCESS,
std::forward<Arg>(arg));
}
/**
* Check for the success of `source` (which must evaluate to a ResultVal). If it succeeds, unwraps
* the contained value and assigns it to `target`, which can be either an l-value expression or a

View file

@ -92,7 +92,7 @@ CIAFile::~CIAFile() {
ResultVal<std::size_t> CIAFile::Read(u64 offset, std::size_t length, u8* buffer) const {
UNIMPLEMENTED();
return MakeResult<std::size_t>(length);
return length;
}
ResultCode CIAFile::WriteTicket() {
@ -203,7 +203,7 @@ ResultVal<std::size_t> CIAFile::WriteContentData(u64 offset, std::size_t length,
}
}
return MakeResult(length);
return length;
}
ResultVal<std::size_t> CIAFile::Write(u64 offset, std::size_t length, bool flush,
@ -235,7 +235,7 @@ ResultVal<std::size_t> CIAFile::Write(u64 offset, std::size_t length, bool flush
// If we don't have a header yet, we can't pull offsets of other sections
if (install_state == CIAInstallState::InstallStarted)
return MakeResult<std::size_t>(length);
return length;
// If we have been given data before (or including) .app content, pull it into
// our buffer, but only pull *up to* the content offset, no further.
@ -267,14 +267,14 @@ ResultVal<std::size_t> CIAFile::Write(u64 offset, std::size_t length, bool flush
// Content data sizes can only be retrieved from TMD data
if (install_state != CIAInstallState::TMDLoaded)
return MakeResult<std::size_t>(length);
return length;
// From this point forward, data will no longer be buffered in data
auto result = WriteContentData(offset, length, buffer);
if (result.Failed())
return result;
return MakeResult<std::size_t>(length);
return length;
}
u64 CIAFile::GetSize() const {
@ -1316,7 +1316,7 @@ ResultVal<std::unique_ptr<AMFileWrapper>> GetFileFromSession(
// File::OpenSubFile
std::size_t offset = file->GetSessionFileOffset(server);
std::size_t size = file->GetSessionFileSize(server);
return MakeResult(std::make_unique<AMFileWrapper>(file, offset, size));
return std::make_unique<AMFileWrapper>(file, offset, size);
}
LOG_ERROR(Service_AM, "Failed to cast handle to FSFile!");

View file

@ -291,7 +291,7 @@ ResultVal<MessageParameter> AppletManager::GlanceParameter(AppletId app_id) {
next_parameter = {};
}
return MakeResult<MessageParameter>(std::move(parameter));
return parameter;
}
ResultVal<MessageParameter> AppletManager::ReceiveParameter(AppletId app_id) {
@ -333,7 +333,7 @@ ResultVal<AppletManager::GetLockHandleResult> AppletManager::GetLockHandle(
corrected_attributes.raw);
}
return MakeResult<AppletManager::GetLockHandleResult>({corrected_attributes, 0, lock});
return GetLockHandleResult{corrected_attributes, 0, lock};
}
ResultVal<AppletManager::InitializeResult> AppletManager::Initialize(AppletId app_id,
@ -372,8 +372,7 @@ ResultVal<AppletManager::InitializeResult> AppletManager::Initialize(AppletId ap
});
}
return MakeResult<InitializeResult>(
{slot_data->notification_event, slot_data->parameter_event});
return InitializeResult{slot_data->notification_event, slot_data->parameter_event};
}
ResultCode AppletManager::Enable(AppletAttributes attributes) {
@ -420,7 +419,7 @@ ResultVal<Notification> AppletManager::InquireNotification(AppletId app_id) {
if (slot_data->registered) {
auto notification = slot_data->notification;
slot_data->notification = Notification::None;
return MakeResult<Notification>(notification);
return notification;
}
}
@ -943,12 +942,12 @@ ResultVal<AppletManager::AppletManInfo> AppletManager::GetAppletManInfo(
}
}
return MakeResult<AppletManInfo>({
return AppletManInfo{
.active_applet_pos = active_applet_pos,
.requested_applet_id = requested_applet_id,
.home_menu_applet_id = AppletId::HomeMenu,
.active_applet_id = active_applet_id,
});
};
}
ResultVal<AppletManager::AppletInfo> AppletManager::GetAppletInfo(AppletId app_id) {
@ -968,8 +967,13 @@ ResultVal<AppletManager::AppletInfo> AppletManager::GetAppletInfo(AppletId app_i
auto media_type = ((slot_data->title_id >> 32) & 0xFFFFFFFF) == 0x00040000
? Service::FS::MediaType::SDMC
: Service::FS::MediaType::NAND;
return MakeResult<AppletInfo>({slot_data->title_id, media_type, slot_data->registered,
slot_data->loaded, slot_data->attributes.raw});
return AppletInfo{
.title_id = slot_data->title_id,
.media_type = media_type,
.registered = slot_data->registered,
.loaded = slot_data->loaded,
.attributes = slot_data->attributes.raw,
};
}
ResultCode AppletManager::PrepareToDoApplicationJump(u64 title_id, FS::MediaType media_type,

View file

@ -1239,7 +1239,7 @@ void Module::CheckAndUpdateFile(const CecDataPathType path_type, const u32 ncch_
const u32 message_size = static_cast<u32>(message->GetSize());
std::vector<u8> buffer(message_size);
message->Read(0, message_size, buffer.data()).Unwrap();
void(message->Read(0, message_size, buffer.data()).Unwrap());
message->Close();
std::memcpy(&message_headers[outbox_info_header.message_num++], buffer.data(),
@ -1329,7 +1329,7 @@ void Module::CheckAndUpdateFile(const CecDataPathType path_type, const u32 ncch_
const u32 message_size = static_cast<u32>(message->GetSize());
std::vector<u8> buffer(message_size);
message->Read(0, message_size, buffer.data()).Unwrap();
void(message->Read(0, message_size, buffer.data()).Unwrap());
message->Close();
// Message id is at offset 0x20, and is 8 bytes

View file

@ -432,7 +432,7 @@ ResultVal<void*> Module::GetConfigInfoBlockPointer(u32 block_id, u32 size, u32 f
else
pointer = &cfg_config_file_buffer[itr->offset_or_data];
return MakeResult<void*>(pointer);
return pointer;
}
ResultCode Module::GetConfigInfoBlock(u32 block_id, u32 size, u32 flag, void* output) {

View file

@ -63,7 +63,7 @@ ResultVal<ArchiveHandle> ArchiveManager::OpenArchive(ArchiveIdCode id_code,
++next_handle;
}
handle_map.emplace(next_handle, std::move(res));
return MakeResult(next_handle++);
return next_handle++;
}
ResultCode ArchiveManager::CloseArchive(ArchiveHandle handle) {
@ -103,7 +103,7 @@ ArchiveManager::OpenFileFromArchive(ArchiveHandle archive_handle, const FileSys:
}
auto file = std::make_shared<File>(system.Kernel(), std::move(backend).Unwrap(), path);
return std::make_pair(MakeResult(std::move(file)), open_timeout_ns);
return std::make_pair(std::move(file), open_timeout_ns);
}
ResultCode ArchiveManager::DeleteFileFromArchive(ArchiveHandle archive_handle,
@ -197,8 +197,7 @@ ResultVal<std::shared_ptr<Directory>> ArchiveManager::OpenDirectoryFromArchive(
return backend.Code();
}
auto directory = std::make_shared<Directory>(std::move(backend).Unwrap(), path);
return MakeResult(std::move(directory));
return std::make_shared<Directory>(std::move(backend).Unwrap(), path);
}
ResultVal<u64> ArchiveManager::GetFreeBytesInArchive(ArchiveHandle archive_handle) {
@ -206,7 +205,7 @@ ResultVal<u64> ArchiveManager::GetFreeBytesInArchive(ArchiveHandle archive_handl
if (archive == nullptr) {
return FileSys::ERR_INVALID_ARCHIVE_HANDLE;
}
return MakeResult(archive->GetFreeBytes());
return archive->GetFreeBytes();
}
ResultCode ArchiveManager::FormatArchive(ArchiveIdCode id_code,
@ -314,7 +313,7 @@ ResultVal<ArchiveResource> ArchiveManager::GetArchiveResource(MediaType media_ty
resource.cluster_size_in_bytes = 16384;
resource.partition_capacity_in_clusters = 0x80000; // 8GiB capacity
resource.free_space_in_clusters = 0x80000; // 8GiB free
return MakeResult(resource);
return resource;
}
void ArchiveManager::RegisterArchiveTypes() {

View file

@ -845,11 +845,11 @@ ResultVal<u16> FS_USER::GetSpecialContentIndexFromGameCard(u64 title_id, Special
switch (type) {
case SpecialContentType::Update:
return MakeResult(static_cast<u16>(NCSDContentIndex::Update));
return static_cast<u16>(NCSDContentIndex::Update);
case SpecialContentType::Manual:
return MakeResult(static_cast<u16>(NCSDContentIndex::Manual));
return static_cast<u16>(NCSDContentIndex::Manual);
case SpecialContentType::DLPChild:
return MakeResult(static_cast<u16>(NCSDContentIndex::DLP));
return static_cast<u16>(NCSDContentIndex::DLP);
default:
UNREACHABLE();
}
@ -874,9 +874,9 @@ ResultVal<u16> FS_USER::GetSpecialContentIndexFromTMD(MediaType media_type, u64
switch (type) {
case SpecialContentType::Manual:
return MakeResult(static_cast<u16>(FileSys::TMDContentIndex::Manual));
return static_cast<u16>(FileSys::TMDContentIndex::Manual);
case SpecialContentType::DLPChild:
return MakeResult(static_cast<u16>(FileSys::TMDContentIndex::DLP));
return static_cast<u16>(FileSys::TMDContentIndex::DLP);
default:
ASSERT(false);
}

View file

@ -301,7 +301,7 @@ ResultVal<VAddr> CROHelper::RebaseSegmentTable(u32 cro_size, VAddr data_segment_
}
SetEntry(system.Memory(), i, segment);
}
return MakeResult<u32>(prev_data_segment + module_address);
return prev_data_segment + module_address;
}
ResultCode CROHelper::RebaseExportNamedSymbolTable() {
@ -776,10 +776,10 @@ ResultCode CROHelper::ApplyImportNamedSymbol(VAddr crs_address) {
return result;
}
return MakeResult<bool>(false);
return false;
}
return MakeResult<bool>(true);
return true;
});
if (result.IsError()) {
return result;
@ -897,9 +897,9 @@ ResultCode CROHelper::ApplyModuleImport(VAddr crs_address) {
return result;
}
}
return MakeResult<bool>(false);
return false;
}
return MakeResult<bool>(true);
return true;
});
if (result.IsError()) {
return result;
@ -1090,10 +1090,10 @@ ResultCode CROHelper::ApplyExitRelocations(VAddr crs_address) {
return result;
}
return MakeResult<bool>(false);
return false;
}
return MakeResult<bool>(true);
return true;
});
if (result.IsError()) {
LOG_ERROR(Service_LDR, "Error applying exit relocation {:08X}", result.raw);
@ -1317,7 +1317,7 @@ ResultCode CROHelper::Link(VAddr crs_address, bool link_on_load_bug_fix) {
if (result.IsError())
return result;
return MakeResult<bool>(true);
return true;
});
if (result.IsError()) {
LOG_ERROR(Service_LDR, "Error applying export {:08X}", result.raw);
@ -1362,7 +1362,7 @@ ResultCode CROHelper::Unlink(VAddr crs_address) {
if (result.IsError())
return result;
return MakeResult<bool>(true);
return true;
});
if (result.IsError()) {
LOG_ERROR(Service_LDR, "Error resetting export {:08X}", result.raw);

View file

@ -673,7 +673,7 @@ ResultVal<std::shared_ptr<Kernel::Event>> NWM_UDS::Initialize(
channel_data.clear();
}
return MakeResult(connection_status_event);
return connection_status_event;
}
void NWM_UDS::InitializeWithVersion(Kernel::HLERequestContext& ctx) {

View file

@ -131,7 +131,7 @@ void PLG_LDR::OnProcessExit(Kernel::Process& process, Kernel::KernelSystem& kern
ResultVal<Kernel::Handle> PLG_LDR::GetMemoryChangedHandle(Kernel::KernelSystem& kernel) {
if (plgldr_context.memory_changed_handle)
return MakeResult(plgldr_context.memory_changed_handle);
return plgldr_context.memory_changed_handle;
std::shared_ptr<Kernel::Event> evt = kernel.CreateEvent(
Kernel::ResetType::OneShot,
@ -139,7 +139,7 @@ ResultVal<Kernel::Handle> PLG_LDR::GetMemoryChangedHandle(Kernel::KernelSystem&
CASCADE_RESULT(plgldr_context.memory_changed_handle,
kernel.GetCurrentProcess()->handle_table.Create(std::move(evt)));
return MakeResult(plgldr_context.memory_changed_handle);
return plgldr_context.memory_changed_handle;
}
void PLG_LDR::OnMemoryChanged(Kernel::Process& process, Kernel::KernelSystem& kernel) {

View file

@ -44,7 +44,7 @@ ResultVal<std::shared_ptr<Kernel::ServerPort>> ServiceManager::RegisterService(
registered_services_inverse.emplace(client_port->GetObjectId(), name);
registered_services.emplace(std::move(name), std::move(client_port));
return MakeResult(std::move(server_port));
return server_port;
}
ResultVal<std::shared_ptr<Kernel::ClientPort>> ServiceManager::GetServicePort(
@ -56,7 +56,7 @@ ResultVal<std::shared_ptr<Kernel::ClientPort>> ServiceManager::GetServicePort(
return ERR_SERVICE_NOT_REGISTERED;
}
return MakeResult(it->second);
return it->second;
}
ResultVal<std::shared_ptr<Kernel::ClientSession>> ServiceManager::ConnectToService(