ams: std::optional -> util::optional

This commit is contained in:
Michael Scire 2021-07-08 02:37:26 -07:00
parent 9df13781c2
commit a7c14e03b9
59 changed files with 950 additions and 147 deletions

View file

@ -164,6 +164,6 @@ namespace ams::fs {
static_assert(util::is_pod<HashSalt>::value); static_assert(util::is_pod<HashSalt>::value);
static_assert(sizeof(HashSalt) == HashSalt::Size); static_assert(sizeof(HashSalt) == HashSalt::Size);
using SaveDataHashSalt = std::optional<HashSalt>; using SaveDataHashSalt = util::optional<HashSalt>;
} }

View file

@ -54,7 +54,7 @@ namespace ams::fssrv::impl {
return m_list.size(); return m_list.size();
} }
std::optional<fs::ProgramIndexMapInfo> Get(const ncm::ProgramId &program_id) const { util::optional<fs::ProgramIndexMapInfo> Get(const ncm::ProgramId &program_id) const {
/* Acquire exclusive access to the map. */ /* Acquire exclusive access to the map. */
std::scoped_lock lk(m_mutex); std::scoped_lock lk(m_mutex);
@ -134,9 +134,9 @@ namespace ams::fssrv::impl {
} }
template<typename F> template<typename F>
std::optional<fs::ProgramIndexMapInfo> GetImpl(F f) const { util::optional<fs::ProgramIndexMapInfo> GetImpl(F f) const {
/* Try to find an entry matching the predicate. */ /* Try to find an entry matching the predicate. */
std::optional<fs::ProgramIndexMapInfo> match = std::nullopt; util::optional<fs::ProgramIndexMapInfo> match = util::nullopt;
for (const auto &entry : m_list) { for (const auto &entry : m_list) {
/* If the predicate matches, we want to return the relevant info. */ /* If the predicate matches, we want to return the relevant info. */

View file

@ -92,7 +92,7 @@ namespace ams::fssrv::impl {
public: public:
bool IsDeepRetryEnabled() const; bool IsDeepRetryEnabled() const;
bool IsAccessFailureDetectionObserved() const; bool IsAccessFailureDetectionObserved() const;
std::optional<std::shared_lock<os::ReadWriteLock>> AcquireCacheInvalidationReadLock(); util::optional<std::shared_lock<os::ReadWriteLock>> AcquireCacheInvalidationReadLock();
os::ReadWriteLock &GetReadWriteLockForCacheInvalidation(); os::ReadWriteLock &GetReadWriteLockForCacheInvalidation();
public: public:
/* Command API. */ /* Command API. */

View file

@ -44,7 +44,7 @@ namespace ams::fssrv::impl {
~StorageInterfaceAdapter(); ~StorageInterfaceAdapter();
private: private:
std::optional<std::shared_lock<os::ReadWriteLock>> AcquireCacheInvalidationReadLock(); util::optional<std::shared_lock<os::ReadWriteLock>> AcquireCacheInvalidationReadLock();
public: public:
/* Command API. */ /* Command API. */
Result Read(s64 offset, const ams::sf::OutNonSecureBuffer &buffer, s64 size); Result Read(s64 offset, const ams::sf::OutNonSecureBuffer &buffer, s64 size);

View file

@ -34,9 +34,9 @@ namespace ams::fssystem {
virtual ~DirectoryRedirectionFileSystem(); virtual ~DirectoryRedirectionFileSystem();
protected: protected:
inline std::optional<std::scoped_lock<os::Mutex>> GetAccessorLock() const { inline util::optional<std::scoped_lock<os::Mutex>> GetAccessorLock() const {
/* No accessor lock is needed. */ /* No accessor lock is needed. */
return std::nullopt; return util::nullopt;
} }
private: private:
Result GetNormalizedDirectoryPath(char **out, size_t *out_size, const char *dir); Result GetNormalizedDirectoryPath(char **out, size_t *out_size, const char *dir);

View file

@ -33,9 +33,9 @@ namespace ams::fssystem {
virtual ~DirectorySaveDataFileSystem(); virtual ~DirectorySaveDataFileSystem();
protected: protected:
inline std::optional<std::scoped_lock<os::Mutex>> GetAccessorLock() { inline util::optional<std::scoped_lock<os::Mutex>> GetAccessorLock() {
/* We have a real accessor lock that we want to use. */ /* We have a real accessor lock that we want to use. */
return std::make_optional<std::scoped_lock<os::Mutex>>(this->accessor_mutex); return util::make_optional<std::scoped_lock<os::Mutex>>(this->accessor_mutex);
} }
private: private:
Result AllocateWorkBuffer(std::unique_ptr<u8[]> *out, size_t *out_size, size_t ideal_size); Result AllocateWorkBuffer(std::unique_ptr<u8[]> *out, size_t *out_size, size_t ideal_size);

View file

@ -107,7 +107,7 @@ namespace ams::fssystem {
class Sha256PartitionFileSystemMeta : public PartitionFileSystemMetaCore<impl::Sha256PartitionFileSystemFormat> { class Sha256PartitionFileSystemMeta : public PartitionFileSystemMetaCore<impl::Sha256PartitionFileSystemFormat> {
public: public:
using PartitionFileSystemMetaCore<impl::Sha256PartitionFileSystemFormat>::Initialize; using PartitionFileSystemMetaCore<impl::Sha256PartitionFileSystemFormat>::Initialize;
Result Initialize(fs::IStorage *base_storage, MemoryResource *allocator, const void *hash, size_t hash_size, std::optional<u8> suffix = std::nullopt); Result Initialize(fs::IStorage *base_storage, MemoryResource *allocator, const void *hash, size_t hash_size, util::optional<u8> suffix = util::nullopt);
}; };
} }

View file

@ -32,9 +32,9 @@ namespace ams::fssystem {
virtual ~SubDirectoryFileSystem(); virtual ~SubDirectoryFileSystem();
protected: protected:
inline std::optional<std::scoped_lock<os::Mutex>> GetAccessorLock() const { inline util::optional<std::scoped_lock<os::Mutex>> GetAccessorLock() const {
/* No accessor lock is needed. */ /* No accessor lock is needed. */
return std::nullopt; return util::nullopt;
} }
private: private:
Result Initialize(const char *bp); Result Initialize(const char *bp);

View file

@ -50,7 +50,7 @@ namespace ams::fssystem::impl {
char full_path[fs::EntryNameLengthMax + 1]; char full_path[fs::EntryNameLengthMax + 1];
R_TRY(static_cast<Impl*>(this)->ResolveFullPath(full_path, sizeof(full_path), path)); R_TRY(static_cast<Impl*>(this)->ResolveFullPath(full_path, sizeof(full_path), path));
std::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock(); util::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock();
return this->base_fs->CreateFile(full_path, size, option); return this->base_fs->CreateFile(full_path, size, option);
} }
@ -58,7 +58,7 @@ namespace ams::fssystem::impl {
char full_path[fs::EntryNameLengthMax + 1]; char full_path[fs::EntryNameLengthMax + 1];
R_TRY(static_cast<Impl*>(this)->ResolveFullPath(full_path, sizeof(full_path), path)); R_TRY(static_cast<Impl*>(this)->ResolveFullPath(full_path, sizeof(full_path), path));
std::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock(); util::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock();
return this->base_fs->DeleteFile(full_path); return this->base_fs->DeleteFile(full_path);
} }
@ -66,7 +66,7 @@ namespace ams::fssystem::impl {
char full_path[fs::EntryNameLengthMax + 1]; char full_path[fs::EntryNameLengthMax + 1];
R_TRY(static_cast<Impl*>(this)->ResolveFullPath(full_path, sizeof(full_path), path)); R_TRY(static_cast<Impl*>(this)->ResolveFullPath(full_path, sizeof(full_path), path));
std::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock(); util::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock();
return this->base_fs->CreateDirectory(full_path); return this->base_fs->CreateDirectory(full_path);
} }
@ -74,7 +74,7 @@ namespace ams::fssystem::impl {
char full_path[fs::EntryNameLengthMax + 1]; char full_path[fs::EntryNameLengthMax + 1];
R_TRY(static_cast<Impl*>(this)->ResolveFullPath(full_path, sizeof(full_path), path)); R_TRY(static_cast<Impl*>(this)->ResolveFullPath(full_path, sizeof(full_path), path));
std::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock(); util::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock();
return this->base_fs->DeleteDirectory(full_path); return this->base_fs->DeleteDirectory(full_path);
} }
@ -82,7 +82,7 @@ namespace ams::fssystem::impl {
char full_path[fs::EntryNameLengthMax + 1]; char full_path[fs::EntryNameLengthMax + 1];
R_TRY(static_cast<Impl*>(this)->ResolveFullPath(full_path, sizeof(full_path), path)); R_TRY(static_cast<Impl*>(this)->ResolveFullPath(full_path, sizeof(full_path), path));
std::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock(); util::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock();
return this->base_fs->DeleteDirectoryRecursively(full_path); return this->base_fs->DeleteDirectoryRecursively(full_path);
} }
@ -92,7 +92,7 @@ namespace ams::fssystem::impl {
R_TRY(static_cast<Impl*>(this)->ResolveFullPath(old_full_path, sizeof(old_full_path), old_path)); R_TRY(static_cast<Impl*>(this)->ResolveFullPath(old_full_path, sizeof(old_full_path), old_path));
R_TRY(static_cast<Impl*>(this)->ResolveFullPath(new_full_path, sizeof(new_full_path), new_path)); R_TRY(static_cast<Impl*>(this)->ResolveFullPath(new_full_path, sizeof(new_full_path), new_path));
std::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock(); util::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock();
return this->base_fs->RenameFile(old_full_path, new_full_path); return this->base_fs->RenameFile(old_full_path, new_full_path);
} }
@ -102,7 +102,7 @@ namespace ams::fssystem::impl {
R_TRY(static_cast<Impl*>(this)->ResolveFullPath(old_full_path, sizeof(old_full_path), old_path)); R_TRY(static_cast<Impl*>(this)->ResolveFullPath(old_full_path, sizeof(old_full_path), old_path));
R_TRY(static_cast<Impl*>(this)->ResolveFullPath(new_full_path, sizeof(new_full_path), new_path)); R_TRY(static_cast<Impl*>(this)->ResolveFullPath(new_full_path, sizeof(new_full_path), new_path));
std::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock(); util::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock();
return this->base_fs->RenameDirectory(old_full_path, new_full_path); return this->base_fs->RenameDirectory(old_full_path, new_full_path);
} }
@ -110,7 +110,7 @@ namespace ams::fssystem::impl {
char full_path[fs::EntryNameLengthMax + 1]; char full_path[fs::EntryNameLengthMax + 1];
R_TRY(static_cast<Impl*>(this)->ResolveFullPath(full_path, sizeof(full_path), path)); R_TRY(static_cast<Impl*>(this)->ResolveFullPath(full_path, sizeof(full_path), path));
std::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock(); util::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock();
return this->base_fs->GetEntryType(out, full_path); return this->base_fs->GetEntryType(out, full_path);
} }
@ -118,7 +118,7 @@ namespace ams::fssystem::impl {
char full_path[fs::EntryNameLengthMax + 1]; char full_path[fs::EntryNameLengthMax + 1];
R_TRY(static_cast<Impl*>(this)->ResolveFullPath(full_path, sizeof(full_path), path)); R_TRY(static_cast<Impl*>(this)->ResolveFullPath(full_path, sizeof(full_path), path));
std::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock(); util::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock();
return this->base_fs->OpenFile(out_file, full_path, mode); return this->base_fs->OpenFile(out_file, full_path, mode);
} }
@ -126,12 +126,12 @@ namespace ams::fssystem::impl {
char full_path[fs::EntryNameLengthMax + 1]; char full_path[fs::EntryNameLengthMax + 1];
R_TRY(static_cast<Impl*>(this)->ResolveFullPath(full_path, sizeof(full_path), path)); R_TRY(static_cast<Impl*>(this)->ResolveFullPath(full_path, sizeof(full_path), path));
std::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock(); util::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock();
return this->base_fs->OpenDirectory(out_dir, full_path, mode); return this->base_fs->OpenDirectory(out_dir, full_path, mode);
} }
virtual Result DoCommit() override { virtual Result DoCommit() override {
std::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock(); util::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock();
return this->base_fs->Commit(); return this->base_fs->Commit();
} }
@ -139,7 +139,7 @@ namespace ams::fssystem::impl {
char full_path[fs::EntryNameLengthMax + 1]; char full_path[fs::EntryNameLengthMax + 1];
R_TRY(static_cast<Impl*>(this)->ResolveFullPath(full_path, sizeof(full_path), path)); R_TRY(static_cast<Impl*>(this)->ResolveFullPath(full_path, sizeof(full_path), path));
std::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock(); util::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock();
return this->base_fs->GetFreeSpaceSize(out, full_path); return this->base_fs->GetFreeSpaceSize(out, full_path);
} }
@ -147,7 +147,7 @@ namespace ams::fssystem::impl {
char full_path[fs::EntryNameLengthMax + 1]; char full_path[fs::EntryNameLengthMax + 1];
R_TRY(static_cast<Impl*>(this)->ResolveFullPath(full_path, sizeof(full_path), path)); R_TRY(static_cast<Impl*>(this)->ResolveFullPath(full_path, sizeof(full_path), path));
std::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock(); util::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock();
return this->base_fs->GetTotalSpaceSize(out, full_path); return this->base_fs->GetTotalSpaceSize(out, full_path);
} }
@ -155,7 +155,7 @@ namespace ams::fssystem::impl {
char full_path[fs::EntryNameLengthMax + 1]; char full_path[fs::EntryNameLengthMax + 1];
R_TRY(static_cast<Impl*>(this)->ResolveFullPath(full_path, sizeof(full_path), path)); R_TRY(static_cast<Impl*>(this)->ResolveFullPath(full_path, sizeof(full_path), path));
std::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock(); util::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock();
return this->base_fs->CleanDirectoryRecursively(full_path); return this->base_fs->CleanDirectoryRecursively(full_path);
} }
@ -163,7 +163,7 @@ namespace ams::fssystem::impl {
char full_path[fs::EntryNameLengthMax + 1]; char full_path[fs::EntryNameLengthMax + 1];
R_TRY(static_cast<Impl*>(this)->ResolveFullPath(full_path, sizeof(full_path), path)); R_TRY(static_cast<Impl*>(this)->ResolveFullPath(full_path, sizeof(full_path), path));
std::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock(); util::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock();
return this->base_fs->GetFileTimeStampRaw(out, full_path); return this->base_fs->GetFileTimeStampRaw(out, full_path);
} }
@ -171,23 +171,23 @@ namespace ams::fssystem::impl {
char full_path[fs::EntryNameLengthMax + 1]; char full_path[fs::EntryNameLengthMax + 1];
R_TRY(static_cast<Impl*>(this)->ResolveFullPath(full_path, sizeof(full_path), path)); R_TRY(static_cast<Impl*>(this)->ResolveFullPath(full_path, sizeof(full_path), path));
std::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock(); util::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock();
return this->base_fs->QueryEntry(dst, dst_size, src, src_size, query, full_path); return this->base_fs->QueryEntry(dst, dst_size, src, src_size, query, full_path);
} }
/* These aren't accessible as commands. */ /* These aren't accessible as commands. */
virtual Result DoCommitProvisionally(s64 counter) override { virtual Result DoCommitProvisionally(s64 counter) override {
std::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock(); util::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock();
return this->base_fs->CommitProvisionally(counter); return this->base_fs->CommitProvisionally(counter);
} }
virtual Result DoRollback() override { virtual Result DoRollback() override {
std::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock(); util::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock();
return this->base_fs->Rollback(); return this->base_fs->Rollback();
} }
virtual Result DoFlush() override { virtual Result DoFlush() override {
std::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock(); util::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock();
return this->base_fs->Flush(); return this->base_fs->Flush();
} }
}; };

View file

@ -57,8 +57,8 @@ namespace ams::kvdb {
public: public:
Result Initialize(void *buffer, size_t buffer_size, size_t capacity); Result Initialize(void *buffer, size_t buffer_size, size_t capacity);
void Invalidate(); void Invalidate();
std::optional<size_t> TryGet(void *out_value, size_t max_out_size, const void *key, size_t key_size); util::optional<size_t> TryGet(void *out_value, size_t max_out_size, const void *key, size_t key_size);
std::optional<size_t> TryGetSize(const void *key, size_t key_size); util::optional<size_t> TryGetSize(const void *key, size_t key_size);
void Set(const void *key, size_t key_size, const void *value, size_t value_size); void Set(const void *key, size_t key_size, const void *value, size_t value_size);
bool Contains(const void *key, size_t key_size); bool Contains(const void *key, size_t key_size);
}; };

View file

@ -37,6 +37,6 @@ namespace ams::ncm {
void GetTicketFileStringFromRightsId(char *dst, size_t dst_size, fs::RightsId id); void GetTicketFileStringFromRightsId(char *dst, size_t dst_size, fs::RightsId id);
void GetCertificateFileStringFromRightsId(char *dst, size_t dst_size, fs::RightsId id); void GetCertificateFileStringFromRightsId(char *dst, size_t dst_size, fs::RightsId id);
std::optional<ContentId> GetContentIdFromString(const char *str, size_t len); util::optional<ContentId> GetContentIdFromString(const char *str, size_t len);
} }

View file

@ -94,7 +94,7 @@ namespace ams::ncm {
StorageId storage_id; StorageId storage_id;
SystemSaveDataInfo info; SystemSaveDataInfo info;
sf::SharedPointer<IContentMetaDatabase> content_meta_database; sf::SharedPointer<IContentMetaDatabase> content_meta_database;
std::optional<kvdb::MemoryKeyValueStore<ContentMetaKey>> kvs; util::optional<kvdb::MemoryKeyValueStore<ContentMetaKey>> kvs;
ContentMetaMemoryResource *memory_resource; ContentMetaMemoryResource *memory_resource;
u32 max_content_metas; u32 max_content_metas;

View file

@ -303,17 +303,17 @@ namespace ams::ncm {
return static_cast<StorageId>(this->GetHeader()->storage_id); return static_cast<StorageId>(this->GetHeader()->storage_id);
} }
std::optional<ApplicationId> GetApplicationId(const ContentMetaKey &key) const { util::optional<ApplicationId> GetApplicationId(const ContentMetaKey &key) const {
switch (key.type) { switch (key.type) {
case ContentMetaType::Application: return ApplicationId{ key.id }; case ContentMetaType::Application: return ApplicationId{ key.id };
case ContentMetaType::Patch: return this->GetExtendedHeader<PatchMetaExtendedHeader>()->application_id; case ContentMetaType::Patch: return this->GetExtendedHeader<PatchMetaExtendedHeader>()->application_id;
case ContentMetaType::AddOnContent: return this->GetExtendedHeader<AddOnContentMetaExtendedHeader>()->application_id; case ContentMetaType::AddOnContent: return this->GetExtendedHeader<AddOnContentMetaExtendedHeader>()->application_id;
case ContentMetaType::Delta: return this->GetExtendedHeader<DeltaMetaExtendedHeader>()->application_id; case ContentMetaType::Delta: return this->GetExtendedHeader<DeltaMetaExtendedHeader>()->application_id;
default: return std::nullopt; default: return util::nullopt;
} }
} }
std::optional<ApplicationId> GetApplicationId() const { util::optional<ApplicationId> GetApplicationId() const {
return this->GetApplicationId(this->GetKey()); return this->GetApplicationId(this->GetKey());
} }
}; };

View file

@ -131,7 +131,7 @@ namespace ams::ncm {
protected: protected:
Result Initialize(StorageId install_storage, InstallTaskDataBase *data, u32 config); Result Initialize(StorageId install_storage, InstallTaskDataBase *data, u32 config);
Result PrepareContentMeta(const InstallContentMetaInfo &meta_info, std::optional<ContentMetaKey> key, std::optional<u32> source_version); Result PrepareContentMeta(const InstallContentMetaInfo &meta_info, util::optional<ContentMetaKey> key, util::optional<u32> source_version);
Result PrepareContentMeta(ContentId content_id, s64 size, ContentMetaType meta_type, AutoBuffer *buffer); Result PrepareContentMeta(ContentId content_id, s64 size, ContentMetaType meta_type, AutoBuffer *buffer);
Result WritePlaceHolderBuffer(InstallContentInfo *content_info, const void *data, size_t data_size); Result WritePlaceHolderBuffer(InstallContentInfo *content_info, const void *data, size_t data_size);
void PrepareAgain(); void PrepareAgain();
@ -145,7 +145,7 @@ namespace ams::ncm {
Result PrepareSystemUpdateDependency(); Result PrepareSystemUpdateDependency();
virtual Result PrepareContentMetaIfLatest(const ContentMetaKey &key); /* NOTE: This is not virtual in Nintendo's code. We do so to facilitate downgrades. */ virtual Result PrepareContentMetaIfLatest(const ContentMetaKey &key); /* NOTE: This is not virtual in Nintendo's code. We do so to facilitate downgrades. */
u32 GetConfig() const { return this->config; } u32 GetConfig() const { return this->config; }
Result WriteContentMetaToPlaceHolder(InstallContentInfo *out_install_content_info, ContentStorage *storage, const InstallContentMetaInfo &meta_info, std::optional<bool> is_temporary); Result WriteContentMetaToPlaceHolder(InstallContentInfo *out_install_content_info, ContentStorage *storage, const InstallContentMetaInfo &meta_info, util::optional<bool> is_temporary);
StorageId GetInstallStorage() const { return this->install_storage; } StorageId GetInstallStorage() const { return this->install_storage; }
@ -164,7 +164,7 @@ namespace ams::ncm {
Result VerifyAllNotCommitted(const StorageContentMetaKey *keys, s32 num_keys); Result VerifyAllNotCommitted(const StorageContentMetaKey *keys, s32 num_keys);
virtual Result PrepareInstallContentMetaData() = 0; virtual Result PrepareInstallContentMetaData() = 0;
virtual Result GetLatestVersion(std::optional<u32> *out_version, u64 id) { return ncm::ResultContentMetaNotFound(); } virtual Result GetLatestVersion(util::optional<u32> *out_version, u64 id) { return ncm::ResultContentMetaNotFound(); }
virtual Result OnExecuteComplete() { return ResultSuccess(); } virtual Result OnExecuteComplete() { return ResultSuccess(); }
@ -187,9 +187,9 @@ namespace ams::ncm {
void StartThroughputMeasurement(); void StartThroughputMeasurement();
void UpdateThroughputMeasurement(s64 throughput); void UpdateThroughputMeasurement(s64 throughput);
Result GetInstallContentMetaDataFromPath(AutoBuffer *out, const Path &path, const InstallContentInfo &content_info, std::optional<u32> source_version); Result GetInstallContentMetaDataFromPath(AutoBuffer *out, const Path &path, const InstallContentInfo &content_info, util::optional<u32> source_version);
InstallContentInfo MakeInstallContentInfoFrom(const InstallContentMetaInfo &info, const PlaceHolderId &placeholder_id, std::optional<bool> is_temporary); InstallContentInfo MakeInstallContentInfoFrom(const InstallContentMetaInfo &info, const PlaceHolderId &placeholder_id, util::optional<bool> is_temporary);
Result ReadContentMetaInfoList(s32 *out_count, std::unique_ptr<ContentMetaInfo[]> *out_meta_infos, const ContentMetaKey &key); Result ReadContentMetaInfoList(s32 *out_count, std::unique_ptr<ContentMetaInfo[]> *out_meta_infos, const ContentMetaKey &key);
Result ListRightsIdsByInstallContentMeta(s32 *out_count, Span<RightsId> out_span, const InstallContentMeta &content_meta, s32 offset); Result ListRightsIdsByInstallContentMeta(s32 *out_count, Span<RightsId> out_span, const InstallContentMeta &content_meta, s32 offset);

View file

@ -31,7 +31,7 @@ namespace ams::ncm {
void Inactivate(); void Inactivate();
Result Initialize(const char *package_root, const char *context_path, void *buffer, size_t buffer_size, bool requires_exfat_driver, FirmwareVariationId firmware_variation_id); Result Initialize(const char *package_root, const char *context_path, void *buffer, size_t buffer_size, bool requires_exfat_driver, FirmwareVariationId firmware_variation_id);
std::optional<ContentMetaKey> GetSystemUpdateMetaKey(); util::optional<ContentMetaKey> GetSystemUpdateMetaKey();
protected: protected:
virtual Result PrepareInstallContentMetaData() override; virtual Result PrepareInstallContentMetaData() override;
virtual Result GetInstallContentMetaInfo(InstallContentMetaInfo *out, const ContentMetaKey &key) override; virtual Result GetInstallContentMetaInfo(InstallContentMetaInfo *out, const ContentMetaKey &key) override;

View file

@ -38,8 +38,8 @@ namespace ams::capsrv::server {
/* Destroy the server. */ /* Destroy the server. */
os::FinalizeEvent(std::addressof(this->idle_event)); os::FinalizeEvent(std::addressof(this->idle_event));
this->server_manager_holder = std::nullopt; this->server_manager_holder = util::nullopt;
this->service_holder = std::nullopt; this->service_holder = util::nullopt;
} }
void DecoderControlServerManager::StartServer() { void DecoderControlServerManager::StartServer() {

View file

@ -31,8 +31,8 @@ namespace ams::capsrv::server {
using ServerOptions = sf::hipc::DefaultServerManagerOptions; using ServerOptions = sf::hipc::DefaultServerManagerOptions;
using ServerManager = sf::hipc::ServerManager<NumServers, ServerOptions, MaxSessions>; using ServerManager = sf::hipc::ServerManager<NumServers, ServerOptions, MaxSessions>;
private: private:
std::optional<ServiceHolderType> service_holder; util::optional<ServiceHolderType> service_holder;
std::optional<ServerManager> server_manager_holder; util::optional<ServerManager> server_manager_holder;
os::EventType idle_event; os::EventType idle_event;
public: public:
constexpr DecoderControlServerManager() : service_holder(), server_manager_holder(), idle_event{} { /* ... */ } constexpr DecoderControlServerManager() : service_holder(), server_manager_holder(), idle_event{} { /* ... */ }

View file

@ -26,10 +26,10 @@ namespace ams::erpt::srv {
constinit char Reporter::s_serial_number[24] = "Unknown"; constinit char Reporter::s_serial_number[24] = "Unknown";
constinit char Reporter::s_os_version[24] = "Unknown"; constinit char Reporter::s_os_version[24] = "Unknown";
constinit char Reporter::s_private_os_version[96] = "Unknown"; constinit char Reporter::s_private_os_version[96] = "Unknown";
constinit std::optional<os::Tick> Reporter::s_application_launch_time; constinit util::optional<os::Tick> Reporter::s_application_launch_time;
constinit std::optional<os::Tick> Reporter::s_awake_time; constinit util::optional<os::Tick> Reporter::s_awake_time;
constinit std::optional<os::Tick> Reporter::s_power_on_time; constinit util::optional<os::Tick> Reporter::s_power_on_time;
constinit std::optional<time::SteadyClockTimePoint> Reporter::s_initial_launch_settings_completion_time; constinit util::optional<time::SteadyClockTimePoint> Reporter::s_initial_launch_settings_completion_time;
namespace { namespace {
@ -78,13 +78,13 @@ namespace ams::erpt::srv {
entry->suspended_duration = suspended_duration; entry->suspended_duration = suspended_duration;
} }
std::optional<TimeSpan> GetActiveDuration(ncm::ProgramId program_id) const { util::optional<TimeSpan> GetActiveDuration(ncm::ProgramId program_id) const {
/* Try to find a matching entry. */ /* Try to find a matching entry. */
const auto entry = util::range::find_if(m_list, [&](const AppletActiveTimeInfo &info) { return info.program_id == program_id; }); const auto entry = util::range::find_if(m_list, [&](const AppletActiveTimeInfo &info) { return info.program_id == program_id; });
if (entry != m_list.end()) { if (entry != m_list.end()) {
return (os::GetSystemTick() - entry->register_tick).ToTimeSpan() - entry->suspended_duration; return (os::GetSystemTick() - entry->register_tick).ToTimeSpan() - entry->suspended_duration;
} else { } else {
return std::nullopt; return util::nullopt;
} }
} }
}; };

View file

@ -25,13 +25,13 @@ namespace ams::erpt::srv {
static char s_serial_number[24]; static char s_serial_number[24];
static char s_os_version[24]; static char s_os_version[24];
static char s_private_os_version[96]; static char s_private_os_version[96];
static std::optional<os::Tick> s_application_launch_time; static util::optional<os::Tick> s_application_launch_time;
static std::optional<os::Tick> s_awake_time; static util::optional<os::Tick> s_awake_time;
static std::optional<os::Tick> s_power_on_time; static util::optional<os::Tick> s_power_on_time;
static std::optional<time::SteadyClockTimePoint> s_initial_launch_settings_completion_time; static util::optional<time::SteadyClockTimePoint> s_initial_launch_settings_completion_time;
public: public:
static void ClearApplicationLaunchTime() { s_application_launch_time = std::nullopt; } static void ClearApplicationLaunchTime() { s_application_launch_time = util::nullopt; }
static void ClearInitialLaunchSettingsCompletionTime() { s_initial_launch_settings_completion_time = std::nullopt; } static void ClearInitialLaunchSettingsCompletionTime() { s_initial_launch_settings_completion_time = util::nullopt; }
static void SetInitialLaunchSettingsCompletionTime(const time::SteadyClockTimePoint &time) { s_initial_launch_settings_completion_time = time; } static void SetInitialLaunchSettingsCompletionTime(const time::SteadyClockTimePoint &time) { s_initial_launch_settings_completion_time = time; }

View file

@ -238,7 +238,7 @@ namespace ams::fs {
class SdCardRedirectionCodeFileSystem : public OpenFileOnlyFileSystem { class SdCardRedirectionCodeFileSystem : public OpenFileOnlyFileSystem {
private: private:
std::optional<ReadOnlyFileSystem> sd_content_fs; util::optional<ReadOnlyFileSystem> sd_content_fs;
ReadOnlyFileSystem code_fs; ReadOnlyFileSystem code_fs;
bool is_redirect; bool is_redirect;
public: public:
@ -303,8 +303,8 @@ namespace ams::fs {
class AtmosphereCodeFileSystem : public OpenFileOnlyFileSystem { class AtmosphereCodeFileSystem : public OpenFileOnlyFileSystem {
private: private:
std::optional<SdCardRedirectionCodeFileSystem> code_fs; util::optional<SdCardRedirectionCodeFileSystem> code_fs;
std::optional<ReadOnlyFileSystem> hbl_fs; util::optional<ReadOnlyFileSystem> hbl_fs;
ncm::ProgramId program_id; ncm::ProgramId program_id;
bool initialized; bool initialized;
public: public:

View file

@ -154,8 +154,8 @@ namespace ams::fssrv::impl {
AMS_ABORT_UNLESS(false); AMS_ABORT_UNLESS(false);
} }
std::optional<std::shared_lock<os::ReadWriteLock>> FileSystemInterfaceAdapter::AcquireCacheInvalidationReadLock() { util::optional<std::shared_lock<os::ReadWriteLock>> FileSystemInterfaceAdapter::AcquireCacheInvalidationReadLock() {
std::optional<std::shared_lock<os::ReadWriteLock>> lock; util::optional<std::shared_lock<os::ReadWriteLock>> lock;
if (this->deep_retry_enabled) { if (this->deep_retry_enabled) {
lock.emplace(this->invalidation_lock); lock.emplace(this->invalidation_lock);
} }

View file

@ -34,8 +34,8 @@ namespace ams::fssrv::impl {
/* ... */ /* ... */
} }
std::optional<std::shared_lock<os::ReadWriteLock>> StorageInterfaceAdapter::AcquireCacheInvalidationReadLock() { util::optional<std::shared_lock<os::ReadWriteLock>> StorageInterfaceAdapter::AcquireCacheInvalidationReadLock() {
std::optional<std::shared_lock<os::ReadWriteLock>> lock; util::optional<std::shared_lock<os::ReadWriteLock>> lock;
if (this->deep_retry_enabled) { if (this->deep_retry_enabled) {
lock.emplace(this->invalidation_lock); lock.emplace(this->invalidation_lock);
} }

View file

@ -113,7 +113,7 @@ namespace ams::fssystem {
constexpr inline s32 KeySlotCacheEntryCount = 3; constexpr inline s32 KeySlotCacheEntryCount = 3;
KeySlotCache g_key_slot_cache; KeySlotCache g_key_slot_cache;
std::optional<KeySlotCacheEntry> g_key_slot_cache_entry[KeySlotCacheEntryCount]; util::optional<KeySlotCacheEntry> g_key_slot_cache_entry[KeySlotCacheEntryCount];
spl::AccessKey &GetNcaKekAccessKey(s32 key_type) { spl::AccessKey &GetNcaKekAccessKey(s32 key_type) {
static spl::AccessKey s_nca_kek_access_key_array[KeyAreaEncryptionKeyCount] = {}; static spl::AccessKey s_nca_kek_access_key_array[KeyAreaEncryptionKeyCount] = {};

View file

@ -162,7 +162,7 @@ namespace ams::fssystem {
template class PartitionFileSystemMetaCore<impl::PartitionFileSystemFormat>; template class PartitionFileSystemMetaCore<impl::PartitionFileSystemFormat>;
template class PartitionFileSystemMetaCore<impl::Sha256PartitionFileSystemFormat>; template class PartitionFileSystemMetaCore<impl::Sha256PartitionFileSystemFormat>;
Result Sha256PartitionFileSystemMeta::Initialize(fs::IStorage *base_storage, MemoryResource *allocator, const void *hash, size_t hash_size, std::optional<u8> suffix) { Result Sha256PartitionFileSystemMeta::Initialize(fs::IStorage *base_storage, MemoryResource *allocator, const void *hash, size_t hash_size, util::optional<u8> suffix) {
/* Ensure preconditions. */ /* Ensure preconditions. */
R_UNLESS(hash_size == crypto::Sha256Generator::HashSize, fs::ResultPreconditionViolation()); R_UNLESS(hash_size == crypto::Sha256Generator::HashSize, fs::ResultPreconditionViolation());

View file

@ -59,7 +59,7 @@ namespace ams::htclow::driver {
std::scoped_lock lk(m_mutex); std::scoped_lock lk(m_mutex);
/* Clear our driver type. */ /* Clear our driver type. */
m_driver_type = std::nullopt; m_driver_type = util::nullopt;
/* Close our driver. */ /* Close our driver. */
if (m_open_driver != nullptr) { if (m_open_driver != nullptr) {

View file

@ -23,7 +23,7 @@ namespace ams::htclow::driver {
class DriverManager { class DriverManager {
private: private:
std::optional<htclow::impl::DriverType> m_driver_type{}; util::optional<htclow::impl::DriverType> m_driver_type{};
IDriver *m_debug_driver{}; IDriver *m_debug_driver{};
SocketDriver m_socket_driver; SocketDriver m_socket_driver;
UsbDriver m_usb_driver{}; UsbDriver m_usb_driver{};

View file

@ -47,7 +47,7 @@ namespace ams::htclow::mux {
u64 m_total_send_size; u64 m_total_send_size;
u64 m_cur_max_data; u64 m_cur_max_data;
u64 m_prev_max_data; u64 m_prev_max_data;
std::optional<u64> m_share; util::optional<u64> m_share;
os::Event m_state_change_event; os::Event m_state_change_event;
ChannelState m_state; ChannelState m_state;
public: public:

View file

@ -55,9 +55,9 @@ namespace ams::kvdb {
AMS_ABORT_UNLESS(this->entries != nullptr); AMS_ABORT_UNLESS(this->entries != nullptr);
} }
std::optional<size_t> FileKeyValueStore::Cache::TryGet(void *out_value, size_t max_out_size, const void *key, size_t key_size) { util::optional<size_t> FileKeyValueStore::Cache::TryGet(void *out_value, size_t max_out_size, const void *key, size_t key_size) {
if (!this->HasEntries()) { if (!this->HasEntries()) {
return std::nullopt; return util::nullopt;
} }
/* Try to find the entry. */ /* Try to find the entry. */
@ -66,7 +66,7 @@ namespace ams::kvdb {
if (entry.key_size == key_size && std::memcmp(entry.key, key, key_size) == 0) { if (entry.key_size == key_size && std::memcmp(entry.key, key, key_size) == 0) {
/* If we don't have enough space, fail to read from cache. */ /* If we don't have enough space, fail to read from cache. */
if (max_out_size < entry.value_size) { if (max_out_size < entry.value_size) {
return std::nullopt; return util::nullopt;
} }
std::memcpy(out_value, entry.value, entry.value_size); std::memcpy(out_value, entry.value, entry.value_size);
@ -74,12 +74,12 @@ namespace ams::kvdb {
} }
} }
return std::nullopt; return util::nullopt;
} }
std::optional<size_t> FileKeyValueStore::Cache::TryGetSize(const void *key, size_t key_size) { util::optional<size_t> FileKeyValueStore::Cache::TryGetSize(const void *key, size_t key_size) {
if (!this->HasEntries()) { if (!this->HasEntries()) {
return std::nullopt; return util::nullopt;
} }
/* Try to find the entry. */ /* Try to find the entry. */
@ -90,7 +90,7 @@ namespace ams::kvdb {
} }
} }
return std::nullopt; return util::nullopt;
} }
void FileKeyValueStore::Cache::Set(const void *key, size_t key_size, const void *value, size_t value_size) { void FileKeyValueStore::Cache::Set(const void *key, size_t key_size, const void *value, size_t value_size) {

View file

@ -78,13 +78,13 @@ namespace ams::ncm {
util::SNPrintf(dst, dst_size, "%s.cert", str.data); util::SNPrintf(dst, dst_size, "%s.cert", str.data);
} }
std::optional<ContentId> GetContentIdFromString(const char *str, size_t len) { util::optional<ContentId> GetContentIdFromString(const char *str, size_t len) {
if (len < ContentIdStringLength) { if (len < ContentIdStringLength) {
return std::nullopt; return util::nullopt;
} }
ContentId content_id; ContentId content_id;
return GetBytesFromString(std::addressof(content_id), sizeof(content_id), str, ContentIdStringLength) ? std::optional<ContentId>(content_id) : std::nullopt; return GetBytesFromString(std::addressof(content_id), sizeof(content_id), str, ContentIdStringLength) ? util::optional<ContentId>(content_id) : util::nullopt;
} }
} }

View file

@ -225,7 +225,7 @@ namespace ams::ncm {
out->max_content_metas = max_content_metas; out->max_content_metas = max_content_metas;
out->memory_resource = memory_resource; out->memory_resource = memory_resource;
out->content_meta_database = nullptr; out->content_meta_database = nullptr;
out->kvs = std::nullopt; out->kvs = util::nullopt;
/* Create a new mount name and copy it to out. */ /* Create a new mount name and copy it to out. */
std::strcpy(out->mount_name, impl::CreateUniqueMountName().str); std::strcpy(out->mount_name, impl::CreateUniqueMountName().str);
@ -240,7 +240,7 @@ namespace ams::ncm {
out->max_content_metas = max_content_metas; out->max_content_metas = max_content_metas;
out->memory_resource = memory_resource; out->memory_resource = memory_resource;
out->content_meta_database = nullptr; out->content_meta_database = nullptr;
out->kvs = std::nullopt; out->kvs = util::nullopt;
return ResultSuccess(); return ResultSuccess();
} }
@ -649,7 +649,7 @@ namespace ams::ncm {
/* N doesn't bother checking the result of this */ /* N doesn't bother checking the result of this */
root->content_meta_database->DisableForcibly(); root->content_meta_database->DisableForcibly();
root->content_meta_database = nullptr; root->content_meta_database = nullptr;
root->kvs = std::nullopt; root->kvs = util::nullopt;
/* Also unmount, except in the case of game cards. */ /* Also unmount, except in the case of game cards. */
if (storage_id != StorageId::GameCard) { if (storage_id != StorageId::GameCard) {

View file

@ -18,7 +18,7 @@
namespace ams::ncm { namespace ams::ncm {
Result ContentMetaDatabaseImpl::GetContentIdImpl(ContentId *out, const ContentMetaKey &key, ContentType type, std::optional<u8> id_offset) const { Result ContentMetaDatabaseImpl::GetContentIdImpl(ContentId *out, const ContentMetaKey &key, ContentType type, util::optional<u8> id_offset) const {
R_TRY(this->EnsureEnabled()); R_TRY(this->EnsureEnabled());
/* Find the meta key. */ /* Find the meta key. */
@ -78,7 +78,7 @@ namespace ams::ncm {
} }
Result ContentMetaDatabaseImpl::GetContentIdByType(sf::Out<ContentId> out_content_id, const ContentMetaKey &key, ContentType type) { Result ContentMetaDatabaseImpl::GetContentIdByType(sf::Out<ContentId> out_content_id, const ContentMetaKey &key, ContentType type) {
return this->GetContentIdImpl(out_content_id.GetPointer(), key, type, std::nullopt); return this->GetContentIdImpl(out_content_id.GetPointer(), key, type, util::nullopt);
} }
Result ContentMetaDatabaseImpl::ListContentInfo(sf::Out<s32> out_count, const sf::OutArray<ContentInfo> &out_info, const ContentMetaKey &key, s32 offset) { Result ContentMetaDatabaseImpl::ListContentInfo(sf::Out<s32> out_count, const sf::OutArray<ContentInfo> &out_info, const ContentMetaKey &key, s32 offset) {
@ -149,7 +149,7 @@ namespace ams::ncm {
Result ContentMetaDatabaseImpl::GetLatestContentMetaKey(sf::Out<ContentMetaKey> out_key, u64 id) { Result ContentMetaDatabaseImpl::GetLatestContentMetaKey(sf::Out<ContentMetaKey> out_key, u64 id) {
R_TRY(this->EnsureEnabled()); R_TRY(this->EnsureEnabled());
std::optional<ContentMetaKey> found_key = std::nullopt; util::optional<ContentMetaKey> found_key = util::nullopt;
/* Find the last key with the desired program id. */ /* Find the last key with the desired program id. */
for (auto entry = this->kvs->lower_bound(ContentMetaKey::MakeUnknownType(id, 0)); entry != this->kvs->end(); entry++) { for (auto entry = this->kvs->lower_bound(ContentMetaKey::MakeUnknownType(id, 0)); entry != this->kvs->end(); entry++) {
@ -308,15 +308,15 @@ namespace ams::ncm {
out_orphaned[i] = true; out_orphaned[i] = true;
} }
auto IsOrphanedContent = [] ALWAYS_INLINE_LAMBDA (const sf::InArray<ContentId> &list, const ncm::ContentId &id) -> std::optional<size_t> { auto IsOrphanedContent = [] ALWAYS_INLINE_LAMBDA (const sf::InArray<ContentId> &list, const ncm::ContentId &id) -> util::optional<size_t> {
/* Check if any input content ids match our found content id. */ /* Check if any input content ids match our found content id. */
for (size_t i = 0; i < list.GetSize(); i++) { for (size_t i = 0; i < list.GetSize(); i++) {
if (list[i] == id) { if (list[i] == id) {
return std::make_optional(i); return util::make_optional(i);
} }
} }
return std::nullopt; return util::nullopt;
}; };
/* Iterate over all entries. */ /* Iterate over all entries. */
@ -435,7 +435,7 @@ namespace ams::ncm {
} }
Result ContentMetaDatabaseImpl::GetContentIdByTypeAndIdOffset(sf::Out<ContentId> out_content_id, const ContentMetaKey &key, ContentType type, u8 id_offset) { Result ContentMetaDatabaseImpl::GetContentIdByTypeAndIdOffset(sf::Out<ContentId> out_content_id, const ContentMetaKey &key, ContentType type, u8 id_offset) {
return this->GetContentIdImpl(out_content_id.GetPointer(), key, type, std::make_optional(id_offset)); return this->GetContentIdImpl(out_content_id.GetPointer(), key, type, util::make_optional(id_offset));
} }
Result ContentMetaDatabaseImpl::GetCount(sf::Out<u32> out_count) { Result ContentMetaDatabaseImpl::GetCount(sf::Out<u32> out_count) {

View file

@ -25,7 +25,7 @@ namespace ams::ncm {
ContentMetaDatabaseImpl(ContentMetaKeyValueStore *kvs) : ContentMetaDatabaseImplBase(kvs) { /* ... */ } ContentMetaDatabaseImpl(ContentMetaKeyValueStore *kvs) : ContentMetaDatabaseImplBase(kvs) { /* ... */ }
private: private:
/* Helpers. */ /* Helpers. */
Result GetContentIdImpl(ContentId *out, const ContentMetaKey &key, ContentType type, std::optional<u8> id_offset) const; Result GetContentIdImpl(ContentId *out, const ContentMetaKey &key, ContentType type, util::optional<u8> id_offset) const;
public: public:
/* Actual commands. */ /* Actual commands. */
virtual Result Set(const ContentMetaKey &key, const sf::InBuffer &value) override; virtual Result Set(const ContentMetaKey &key, const sf::InBuffer &value) override;

View file

@ -116,7 +116,7 @@ namespace ams::ncm {
R_UNLESS(reader.GetExtendedDataSize() != 0, ReadMetaInfoListFromBase()); R_UNLESS(reader.GetExtendedDataSize() != 0, ReadMetaInfoListFromBase());
SystemUpdateMetaExtendedDataReader extended_data_reader(reader.GetExtendedData(), reader.GetExtendedDataSize()); SystemUpdateMetaExtendedDataReader extended_data_reader(reader.GetExtendedData(), reader.GetExtendedDataSize());
std::optional<s32> firmware_variation_index = std::nullopt; util::optional<s32> firmware_variation_index = util::nullopt;
/* NOTE: Atmosphere extension to support downgrading. */ /* NOTE: Atmosphere extension to support downgrading. */
/* If all firmware variations refer to base, don't require the current variation be present. */ /* If all firmware variations refer to base, don't require the current variation be present. */

View file

@ -208,7 +208,7 @@ namespace ams::ncm {
return this->OpenCurrentDirectory(); return this->OpenCurrentDirectory();
} }
Result ContentStorageImpl::ContentIterator::GetNext(std::optional<fs::DirectoryEntry> *out) { Result ContentStorageImpl::ContentIterator::GetNext(util::optional<fs::DirectoryEntry> *out) {
/* Iterate until we get the next entry. */ /* Iterate until we get the next entry. */
while (true) { while (true) {
/* Ensure that we have entries loaded. */ /* Ensure that we have entries loaded. */
@ -216,7 +216,7 @@ namespace ams::ncm {
/* If we failed to load any entries, there's nothing to get. */ /* If we failed to load any entries, there's nothing to get. */
if (this->entry_count <= 0) { if (this->entry_count <= 0) {
*out = std::nullopt; *out = util::nullopt;
return ResultSuccess(); return ResultSuccess();
} }
@ -353,7 +353,7 @@ namespace ams::ncm {
fs::CloseFile(this->cached_file_handle); fs::CloseFile(this->cached_file_handle);
this->cached_content_id = InvalidContentId; this->cached_content_id = InvalidContentId;
} }
this->content_iterator = std::nullopt; this->content_iterator = util::nullopt;
} }
Result ContentStorageImpl::OpenContentIdFile(ContentId content_id) { Result ContentStorageImpl::OpenContentIdFile(ContentId content_id) {
@ -586,7 +586,7 @@ namespace ams::ncm {
/* Advance to the desired offset. */ /* Advance to the desired offset. */
for (auto current_offset = 0; current_offset < offset; /* ... */) { for (auto current_offset = 0; current_offset < offset; /* ... */) {
/* Get the next directory entry. */ /* Get the next directory entry. */
std::optional<fs::DirectoryEntry> dir_entry; util::optional<fs::DirectoryEntry> dir_entry;
R_TRY(this->content_iterator->GetNext(std::addressof(dir_entry))); R_TRY(this->content_iterator->GetNext(std::addressof(dir_entry)));
/* If we run out of entries before reaching the desired offset, we're done. */ /* If we run out of entries before reaching the desired offset, we're done. */
@ -606,7 +606,7 @@ namespace ams::ncm {
s32 count = 0; s32 count = 0;
while (count < static_cast<s32>(out.GetSize())) { while (count < static_cast<s32>(out.GetSize())) {
/* Get the next directory entry. */ /* Get the next directory entry. */
std::optional<fs::DirectoryEntry> dir_entry; util::optional<fs::DirectoryEntry> dir_entry;
R_TRY(this->content_iterator->GetNext(std::addressof(dir_entry))); R_TRY(this->content_iterator->GetNext(std::addressof(dir_entry)));
/* Don't continue if the directory entry is absent. */ /* Don't continue if the directory entry is absent. */

View file

@ -42,7 +42,7 @@ namespace ams::ncm {
~ContentIterator(); ~ContentIterator();
Result Initialize(const char *root_path, size_t max_depth); Result Initialize(const char *root_path, size_t max_depth);
Result GetNext(std::optional<fs::DirectoryEntry> *out); Result GetNext(util::optional<fs::DirectoryEntry> *out);
private: private:
Result OpenCurrentDirectory(); Result OpenCurrentDirectory();
Result OpenDirectory(const char *dir); Result OpenDirectory(const char *dir);
@ -53,14 +53,14 @@ namespace ams::ncm {
ContentId cached_content_id; ContentId cached_content_id;
fs::FileHandle cached_file_handle; fs::FileHandle cached_file_handle;
RightsIdCache *rights_id_cache; RightsIdCache *rights_id_cache;
std::optional<ContentIterator> content_iterator; util::optional<ContentIterator> content_iterator;
std::optional<s32> last_content_offset; util::optional<s32> last_content_offset;
public: public:
static Result InitializeBase(const char *root_path); static Result InitializeBase(const char *root_path);
static Result CleanupBase(const char *root_path); static Result CleanupBase(const char *root_path);
static Result VerifyBase(const char *root_path); static Result VerifyBase(const char *root_path);
public: public:
ContentStorageImpl() : placeholder_accessor(), cached_content_id(InvalidContentId), cached_file_handle(), rights_id_cache(nullptr), content_iterator(std::nullopt), last_content_offset(std::nullopt) { /* ... */ } ContentStorageImpl() : placeholder_accessor(), cached_content_id(InvalidContentId), cached_file_handle(), rights_id_cache(nullptr), content_iterator(util::nullopt), last_content_offset(util::nullopt) { /* ... */ }
~ContentStorageImpl(); ~ContentStorageImpl();
Result Initialize(const char *root_path, MakeContentPathFunction content_path_func, MakePlaceHolderPathFunction placeholder_path_func, bool delay_flush, RightsIdCache *rights_id_cache); Result Initialize(const char *root_path, MakeContentPathFunction content_path_func, MakePlaceHolderPathFunction placeholder_path_func, bool delay_flush, RightsIdCache *rights_id_cache);

View file

@ -87,8 +87,8 @@ namespace ams::ncm {
R_TRY(this->CountInstallContentMetaData(std::addressof(count))); R_TRY(this->CountInstallContentMetaData(std::addressof(count)));
/* Iterate over content meta. */ /* Iterate over content meta. */
std::optional<PlaceHolderId> placeholder_id; util::optional<PlaceHolderId> placeholder_id;
std::optional<StorageId> storage_id; util::optional<StorageId> storage_id;
for (s32 i = 0; i < count; i++) { for (s32 i = 0; i < count; i++) {
/* Obtain the content meta. */ /* Obtain the content meta. */
InstallContentMeta content_meta; InstallContentMeta content_meta;
@ -716,7 +716,7 @@ namespace ams::ncm {
return ResultSuccess(); return ResultSuccess();
} }
Result InstallTaskBase::WriteContentMetaToPlaceHolder(InstallContentInfo *out_install_content_info, ContentStorage *storage, const InstallContentMetaInfo &meta_info, std::optional<bool> is_temporary) { Result InstallTaskBase::WriteContentMetaToPlaceHolder(InstallContentInfo *out_install_content_info, ContentStorage *storage, const InstallContentMetaInfo &meta_info, util::optional<bool> is_temporary) {
/* Generate a placeholder id. */ /* Generate a placeholder id. */
auto placeholder_id = storage->GeneratePlaceHolderId(); auto placeholder_id = storage->GeneratePlaceHolderId();
@ -736,14 +736,14 @@ namespace ams::ncm {
return ResultSuccess(); return ResultSuccess();
} }
Result InstallTaskBase::PrepareContentMeta(const InstallContentMetaInfo &meta_info, std::optional<ContentMetaKey> expected_key, std::optional<u32> source_version) { Result InstallTaskBase::PrepareContentMeta(const InstallContentMetaInfo &meta_info, util::optional<ContentMetaKey> expected_key, util::optional<u32> source_version) {
/* Open the BuiltInSystem content storage. */ /* Open the BuiltInSystem content storage. */
ContentStorage content_storage; ContentStorage content_storage;
R_TRY(OpenContentStorage(&content_storage, StorageId::BuiltInSystem)); R_TRY(OpenContentStorage(&content_storage, StorageId::BuiltInSystem));
/* Write content meta to a placeholder. */ /* Write content meta to a placeholder. */
InstallContentInfo content_info; InstallContentInfo content_info;
R_TRY(this->WriteContentMetaToPlaceHolder(std::addressof(content_info), std::addressof(content_storage), meta_info, std::nullopt)); R_TRY(this->WriteContentMetaToPlaceHolder(std::addressof(content_info), std::addressof(content_storage), meta_info, util::nullopt));
/* Get the path of the placeholder. */ /* Get the path of the placeholder. */
Path path; Path path;
@ -929,7 +929,7 @@ namespace ams::ncm {
/* Get and prepare install content meta info. */ /* Get and prepare install content meta info. */
InstallContentMetaInfo install_content_meta_info; InstallContentMetaInfo install_content_meta_info;
R_TRY(this->GetInstallContentMetaInfo(std::addressof(install_content_meta_info), key)); R_TRY(this->GetInstallContentMetaInfo(std::addressof(install_content_meta_info), key));
R_TRY(this->PrepareContentMeta(install_content_meta_info, key, std::nullopt)); R_TRY(this->PrepareContentMeta(install_content_meta_info, key, util::nullopt));
} }
return ResultSuccess(); return ResultSuccess();
@ -997,7 +997,7 @@ namespace ams::ncm {
return this->data->Delete(keys, num_keys); return this->data->Delete(keys, num_keys);
} }
Result InstallTaskBase::GetInstallContentMetaDataFromPath(AutoBuffer *out, const Path &path, const InstallContentInfo &content_info, std::optional<u32> source_version) { Result InstallTaskBase::GetInstallContentMetaDataFromPath(AutoBuffer *out, const Path &path, const InstallContentInfo &content_info, util::optional<u32> source_version) {
AutoBuffer meta; AutoBuffer meta;
{ {
fs::ScopedAutoAbortDisabler aad; fs::ScopedAutoAbortDisabler aad;
@ -1027,7 +1027,7 @@ namespace ams::ncm {
return ResultSuccess(); return ResultSuccess();
} }
InstallContentInfo InstallTaskBase::MakeInstallContentInfoFrom(const InstallContentMetaInfo &info, const PlaceHolderId &placeholder_id, std::optional<bool> is_tmp) { InstallContentInfo InstallTaskBase::MakeInstallContentInfoFrom(const InstallContentMetaInfo &info, const PlaceHolderId &placeholder_id, util::optional<bool> is_tmp) {
return { return {
.digest = info.digest, .digest = info.digest,
.info = ContentInfo::Make(info.content_id, info.content_size, ContentType::Meta, 0), .info = ContentInfo::Make(info.content_id, info.content_size, ContentType::Meta, 0),

View file

@ -67,7 +67,7 @@ namespace ams::ncm {
Result OnMemoryContentMetaDatabaseImpl::GetLatestContentMetaKey(sf::Out<ContentMetaKey> out_key, u64 id) { Result OnMemoryContentMetaDatabaseImpl::GetLatestContentMetaKey(sf::Out<ContentMetaKey> out_key, u64 id) {
R_TRY(this->EnsureEnabled()); R_TRY(this->EnsureEnabled());
std::optional<ContentMetaKey> found_key = std::nullopt; util::optional<ContentMetaKey> found_key = util::nullopt;
/* Find the last key with the desired program id. */ /* Find the last key with the desired program id. */
for (auto entry = this->kvs->lower_bound(ContentMetaKey::MakeUnknownType(id, 0)); entry != this->kvs->end(); entry++) { for (auto entry = this->kvs->lower_bound(ContentMetaKey::MakeUnknownType(id, 0)); entry != this->kvs->end(); entry++) {

View file

@ -50,9 +50,9 @@ namespace ams::ncm {
/* Check if this entry is content meta. */ /* Check if this entry is content meta. */
if (this->IsContentMetaContentName(entry.name)) { if (this->IsContentMetaContentName(entry.name)) {
/* Prepare content meta if id is valid. */ /* Prepare content meta if id is valid. */
std::optional<ContentId> id = GetContentIdFromString(entry.name, strnlen(entry.name, fs::EntryNameLengthMax + 1)); util::optional<ContentId> id = GetContentIdFromString(entry.name, strnlen(entry.name, fs::EntryNameLengthMax + 1));
R_UNLESS(id, ncm::ResultInvalidPackageFormat()); R_UNLESS(id, ncm::ResultInvalidPackageFormat());
R_TRY(this->PrepareContentMeta(InstallContentMetaInfo::MakeUnverifiable(*id, entry.file_size), std::nullopt, std::nullopt)); R_TRY(this->PrepareContentMeta(InstallContentMetaInfo::MakeUnverifiable(*id, entry.file_size), util::nullopt, util::nullopt));
} }
} }

View file

@ -70,7 +70,7 @@ namespace ams::ncm {
/* Get and prepare install content meta info. We aren't concerned if our key is older. */ /* Get and prepare install content meta info. We aren't concerned if our key is older. */
InstallContentMetaInfo install_content_meta_info; InstallContentMetaInfo install_content_meta_info;
R_TRY(this->GetInstallContentMetaInfo(std::addressof(install_content_meta_info), key)); R_TRY(this->GetInstallContentMetaInfo(std::addressof(install_content_meta_info), key));
return this->PrepareContentMeta(install_content_meta_info, key, std::nullopt); return this->PrepareContentMeta(install_content_meta_info, key, util::nullopt);
} }
} }

View file

@ -70,7 +70,7 @@ namespace ams::ncm {
return ResultSuccess(); return ResultSuccess();
} }
std::optional<ContentMetaKey> PackageSystemUpdateTask::GetSystemUpdateMetaKey() { util::optional<ContentMetaKey> PackageSystemUpdateTask::GetSystemUpdateMetaKey() {
StorageContentMetaKey storage_keys[0x10]; StorageContentMetaKey storage_keys[0x10];
s32 ofs = 0; s32 ofs = 0;
@ -93,7 +93,7 @@ namespace ams::ncm {
} }
} while (count > 0); } while (count > 0);
return std::nullopt; return util::nullopt;
} }
Result PackageSystemUpdateTask::GetInstallContentMetaInfo(InstallContentMetaInfo *out, const ContentMetaKey &key) { Result PackageSystemUpdateTask::GetInstallContentMetaInfo(InstallContentMetaInfo *out, const ContentMetaKey &key) {
@ -117,7 +117,7 @@ namespace ams::ncm {
R_TRY(this->GetContentInfoOfContentMeta(std::addressof(info), key)); R_TRY(this->GetContentInfoOfContentMeta(std::addressof(info), key));
/* Prepare the content meta. */ /* Prepare the content meta. */
return this->PrepareContentMeta(InstallContentMetaInfo::MakeUnverifiable(info.GetId(), info.GetSize(), key), key, std::nullopt); return this->PrepareContentMeta(InstallContentMetaInfo::MakeUnverifiable(info.GetId(), info.GetSize(), key), key, util::nullopt);
} }
Result PackageSystemUpdateTask::PrepareDependency() { Result PackageSystemUpdateTask::PrepareDependency() {

View file

@ -21,9 +21,9 @@ namespace ams::ncm {
class SubmissionPackageInstallTask::Impl { class SubmissionPackageInstallTask::Impl {
private: private:
fs::FileHandleStorage storage; fs::FileHandleStorage storage;
std::optional<impl::MountName> mount_name; util::optional<impl::MountName> mount_name;
public: public:
explicit Impl(fs::FileHandle file) : storage(file), mount_name(std::nullopt) { /* ... */ } explicit Impl(fs::FileHandle file) : storage(file), mount_name(util::nullopt) { /* ... */ }
~Impl() { ~Impl() {
if (this->mount_name) { if (this->mount_name) {

View file

@ -85,12 +85,12 @@ namespace ams::pgl::srv {
} }
} }
std::optional<os::ProcessId> GetRunningApplicationProcessId() { util::optional<os::ProcessId> GetRunningApplicationProcessId() {
os::ProcessId process_id; os::ProcessId process_id;
if (R_SUCCEEDED(pm::shell::GetApplicationProcessIdForShell(std::addressof(process_id)))) { if (R_SUCCEEDED(pm::shell::GetApplicationProcessIdForShell(std::addressof(process_id)))) {
return process_id; return process_id;
} else { } else {
return std::nullopt; return util::nullopt;
} }
} }

View file

@ -131,7 +131,7 @@ namespace ams::pgl::srv {
return ResultSuccess(); return ResultSuccess();
} }
Result GetContentPath(lr::Path *out, ncm::ContentType type, std::optional<u8> index) const { Result GetContentPath(lr::Path *out, ncm::ContentType type, util::optional<u8> index) const {
switch (this->extension_type) { switch (this->extension_type) {
case ExtensionType::Nsp: return this->GetContentPathInNsp(out, type, index); case ExtensionType::Nsp: return this->GetContentPathInNsp(out, type, index);
case ExtensionType::Nspd: return this->GetContentPathInNspd(out, type, index); case ExtensionType::Nspd: return this->GetContentPathInNspd(out, type, index);
@ -155,7 +155,7 @@ namespace ams::pgl::srv {
return this->program_index; return this->program_index;
} }
private: private:
Result GetContentPathInNsp(lr::Path *out, ncm::ContentType type, std::optional<u8> index) const { Result GetContentPathInNsp(lr::Path *out, ncm::ContentType type, util::optional<u8> index) const {
/* Create a reader. */ /* Create a reader. */
auto reader = ncm::PackagedContentMetaReader(this->content_meta_buffer.Get(), this->content_meta_buffer.GetSize()); auto reader = ncm::PackagedContentMetaReader(this->content_meta_buffer.Get(), this->content_meta_buffer.GetSize());
@ -185,7 +185,7 @@ namespace ams::pgl::srv {
return ResultSuccess(); return ResultSuccess();
} }
Result GetContentPathInNspd(lr::Path *out, ncm::ContentType type, std::optional<u8> index) const { Result GetContentPathInNspd(lr::Path *out, ncm::ContentType type, util::optional<u8> index) const {
/* Get the content name. */ /* Get the content name. */
const char *content_name = nullptr; const char *content_name = nullptr;
switch (type) { switch (type) {

View file

@ -23,7 +23,7 @@ namespace ams::powctl::impl::board::nintendo::nx {
namespace { namespace {
constinit std::optional<BatteryDevice> g_battery_device; constinit util::optional<BatteryDevice> g_battery_device;
Max17050Driver &GetMax17050Driver() { Max17050Driver &GetMax17050Driver() {
static Max17050Driver s_max17050_driver; static Max17050Driver s_max17050_driver;
@ -91,7 +91,7 @@ namespace ams::powctl::impl::board::nintendo::nx {
GetMax17050Driver().Finalize(); GetMax17050Driver().Finalize();
/* Destroy the charger device. */ /* Destroy the charger device. */
g_battery_device = std::nullopt; g_battery_device = util::nullopt;
/* Finalize gpio library. */ /* Finalize gpio library. */
gpio::Finalize(); gpio::Finalize();

View file

@ -26,7 +26,7 @@ namespace ams::powctl::impl::board::nintendo::nx {
AMS_DDSF_CASTABLE_TRAITS(ams::powctl::impl::board::nintendo::nx::BatteryDevice, ::ams::powctl::impl::IDevice); AMS_DDSF_CASTABLE_TRAITS(ams::powctl::impl::board::nintendo::nx::BatteryDevice, ::ams::powctl::impl::IDevice);
private: private:
bool use_event_handler; bool use_event_handler;
std::optional<BatteryInterruptEventHandler> event_handler; util::optional<BatteryInterruptEventHandler> event_handler;
os::SystemEventType system_event; os::SystemEventType system_event;
public: public:
BatteryDevice(bool ev); BatteryDevice(bool ev);

View file

@ -23,8 +23,8 @@ namespace ams::powctl::impl::board::nintendo::nx {
namespace { namespace {
constinit std::optional<ChargerDriver> g_charger_driver; constinit util::optional<ChargerDriver> g_charger_driver;
constinit std::optional<BatteryDriver> g_battery_driver; constinit util::optional<BatteryDriver> g_battery_driver;
void InitializeChargerDriver(bool use_event_handlers) { void InitializeChargerDriver(bool use_event_handlers) {
/* Create the charger driver. */ /* Create the charger driver. */
@ -47,7 +47,7 @@ namespace ams::powctl::impl::board::nintendo::nx {
powctl::impl::UnregisterDriver(std::addressof(*g_charger_driver)); powctl::impl::UnregisterDriver(std::addressof(*g_charger_driver));
/* Destroy the battery driver. */ /* Destroy the battery driver. */
g_charger_driver = std::nullopt; g_charger_driver = util::nullopt;
} }
void FinalizeBatteryDriver() { void FinalizeBatteryDriver() {
@ -55,7 +55,7 @@ namespace ams::powctl::impl::board::nintendo::nx {
powctl::impl::UnregisterDriver(std::addressof(*g_battery_driver)); powctl::impl::UnregisterDriver(std::addressof(*g_battery_driver));
/* Destroy the battery driver. */ /* Destroy the battery driver. */
g_battery_driver = std::nullopt; g_battery_driver = util::nullopt;
} }
} }

View file

@ -23,7 +23,7 @@ namespace ams::powctl::impl::board::nintendo::nx {
namespace { namespace {
constinit std::optional<ChargerDevice> g_charger_device; constinit util::optional<ChargerDevice> g_charger_device;
Bq24193Driver &GetBq24193Driver() { Bq24193Driver &GetBq24193Driver() {
static Bq24193Driver s_bq24193_driver; static Bq24193Driver s_bq24193_driver;
@ -80,7 +80,7 @@ namespace ams::powctl::impl::board::nintendo::nx {
gpio::CloseSession(g_charger_device->GetPadSession()); gpio::CloseSession(g_charger_device->GetPadSession());
/* Destroy the charger device. */ /* Destroy the charger device. */
g_charger_device = std::nullopt; g_charger_device = util::nullopt;
/* Finalize gpio library. */ /* Finalize gpio library. */
gpio::Finalize(); gpio::Finalize();

View file

@ -29,7 +29,7 @@ namespace ams::powctl::impl::board::nintendo::nx {
bool watchdog_timer_enabled; bool watchdog_timer_enabled;
TimeSpan watchdog_timer_timeout; TimeSpan watchdog_timer_timeout;
bool use_event_handler; bool use_event_handler;
std::optional<ChargerInterruptEventHandler> event_handler; util::optional<ChargerInterruptEventHandler> event_handler;
os::SystemEventType system_event; os::SystemEventType system_event;
public: public:
ChargerDevice(bool ev); ChargerDevice(bool ev);

View file

@ -36,7 +36,6 @@
#include <random> #include <random>
#include <atomic> #include <atomic>
#include <utility> #include <utility>
#include <optional>
#include <functional> #include <functional>
#include <tuple> #include <tuple>
#include <array> #include <array>

View file

@ -28,6 +28,7 @@
#include <vapours/util/util_exchange.hpp> #include <vapours/util/util_exchange.hpp>
#include <vapours/util/util_scope_guard.hpp> #include <vapours/util/util_scope_guard.hpp>
#include <vapours/util/util_specialization_of.hpp> #include <vapours/util/util_specialization_of.hpp>
#include <vapours/util/util_optional.hpp>
#include <vapours/util/util_bitpack.hpp> #include <vapours/util/util_bitpack.hpp>
#include <vapours/util/util_bitset.hpp> #include <vapours/util/util_bitset.hpp>
#include <vapours/util/util_bitflagset.hpp> #include <vapours/util/util_bitflagset.hpp>

View file

@ -0,0 +1,147 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <vapours/common.hpp>
#include <vapours/assert.hpp>
namespace ams::util::impl {
template<bool Copy, bool CopyAssign, bool Move, bool MoveAssign, typename Tag = void>
struct EnableCopyMove{};
template<typename Tag>
struct EnableCopyMove<false, true, true, true, Tag> {
constexpr EnableCopyMove() noexcept = default;
constexpr EnableCopyMove(const EnableCopyMove &) noexcept = delete;
constexpr EnableCopyMove(EnableCopyMove &&) noexcept = default;
constexpr EnableCopyMove &operator=(const EnableCopyMove &) noexcept = default;
constexpr EnableCopyMove &operator=(EnableCopyMove &&) noexcept = default;
};
template<typename Tag>
struct EnableCopyMove<true, false, true, true, Tag> {
constexpr EnableCopyMove() noexcept = default;
constexpr EnableCopyMove(const EnableCopyMove &) noexcept = default;
constexpr EnableCopyMove(EnableCopyMove &&) noexcept = default;
constexpr EnableCopyMove &operator=(const EnableCopyMove &) noexcept = delete;
constexpr EnableCopyMove &operator=(EnableCopyMove &&) noexcept = default;
};
template<typename Tag>
struct EnableCopyMove<false, false, true, true, Tag> {
constexpr EnableCopyMove() noexcept = default;
constexpr EnableCopyMove(const EnableCopyMove &) noexcept = delete;
constexpr EnableCopyMove(EnableCopyMove &&) noexcept = default;
constexpr EnableCopyMove &operator=(const EnableCopyMove &) noexcept = delete;
constexpr EnableCopyMove &operator=(EnableCopyMove &&) noexcept = default;
};
template<typename Tag>
struct EnableCopyMove<true, true, false, true, Tag> {
constexpr EnableCopyMove() noexcept = default;
constexpr EnableCopyMove(const EnableCopyMove &) noexcept = default;
constexpr EnableCopyMove(EnableCopyMove &&) noexcept = delete;
constexpr EnableCopyMove &operator=(const EnableCopyMove &) noexcept = default;
constexpr EnableCopyMove &operator=(EnableCopyMove &&) noexcept = default;
};
template<typename Tag>
struct EnableCopyMove<false, true, false, true, Tag> {
constexpr EnableCopyMove() noexcept = default;
constexpr EnableCopyMove(const EnableCopyMove &) noexcept = delete;
constexpr EnableCopyMove(EnableCopyMove &&) noexcept = delete;
constexpr EnableCopyMove &operator=(const EnableCopyMove &) noexcept = default;
constexpr EnableCopyMove &operator=(EnableCopyMove &&) noexcept = default;
};
template<typename Tag>
struct EnableCopyMove<true, false, false, true, Tag> {
constexpr EnableCopyMove() noexcept = default;
constexpr EnableCopyMove(const EnableCopyMove &) noexcept = default;
constexpr EnableCopyMove(EnableCopyMove &&) noexcept = delete;
constexpr EnableCopyMove &operator=(const EnableCopyMove &) noexcept = delete;
constexpr EnableCopyMove &operator=(EnableCopyMove &&) noexcept = default;
};
template<typename Tag>
struct EnableCopyMove<false, false, false, true, Tag> {
constexpr EnableCopyMove() noexcept = default;
constexpr EnableCopyMove(const EnableCopyMove &) noexcept = delete;
constexpr EnableCopyMove(EnableCopyMove &&) noexcept = delete;
constexpr EnableCopyMove &operator=(const EnableCopyMove &) noexcept = delete;
constexpr EnableCopyMove &operator=(EnableCopyMove &&) noexcept = default;
};
template<typename Tag>
struct EnableCopyMove<true, true, true, false, Tag> {
constexpr EnableCopyMove() noexcept = default;
constexpr EnableCopyMove(const EnableCopyMove &) noexcept = default;
constexpr EnableCopyMove(EnableCopyMove &&) noexcept = default;
constexpr EnableCopyMove &operator=(const EnableCopyMove &) noexcept = default;
constexpr EnableCopyMove &operator=(EnableCopyMove &&) noexcept = delete;
};
template<typename Tag>
struct EnableCopyMove<true, true, false, false, Tag> {
constexpr EnableCopyMove() noexcept = default;
constexpr EnableCopyMove(const EnableCopyMove &) noexcept = default;
constexpr EnableCopyMove(EnableCopyMove &&) noexcept = delete;
constexpr EnableCopyMove &operator=(const EnableCopyMove &) noexcept = default;
constexpr EnableCopyMove &operator=(EnableCopyMove &&) noexcept = delete;
};
template<typename Tag>
struct EnableCopyMove<false, true, false, false, Tag> {
constexpr EnableCopyMove() noexcept = default;
constexpr EnableCopyMove(const EnableCopyMove &) noexcept = delete;
constexpr EnableCopyMove(EnableCopyMove &&) noexcept = delete;
constexpr EnableCopyMove &operator=(const EnableCopyMove &) noexcept = default;
constexpr EnableCopyMove &operator=(EnableCopyMove &&) noexcept = delete;
};
template<typename Tag>
struct EnableCopyMove<true, false, false, false, Tag> {
constexpr EnableCopyMove() noexcept = default;
constexpr EnableCopyMove(const EnableCopyMove &) noexcept = default;
constexpr EnableCopyMove(EnableCopyMove &&) noexcept = delete;
constexpr EnableCopyMove &operator=(const EnableCopyMove &) noexcept = delete;
constexpr EnableCopyMove &operator=(EnableCopyMove &&) noexcept = delete;
};
template<typename Tag>
struct EnableCopyMove<false, false, false, false, Tag> {
constexpr EnableCopyMove() noexcept = default;
constexpr EnableCopyMove(const EnableCopyMove &) noexcept = delete;
constexpr EnableCopyMove(EnableCopyMove &&) noexcept = delete;
constexpr EnableCopyMove &operator=(const EnableCopyMove &) noexcept = delete;
constexpr EnableCopyMove &operator=(EnableCopyMove &&) noexcept = delete;
};
}

View file

@ -24,7 +24,7 @@ namespace ams::util {
template<class Key, class Value, size_t N> template<class Key, class Value, size_t N>
class BoundedMap { class BoundedMap {
private: private:
std::array<std::optional<Key>, N> keys; std::array<util::optional<Key>, N> keys;
std::array<TypedStorage<Value>, N> values; std::array<TypedStorage<Value>, N> values;
private: private:
ALWAYS_INLINE void FreeEntry(size_t i) { ALWAYS_INLINE void FreeEntry(size_t i) {

View file

@ -0,0 +1,27 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <vapours/common.hpp>
#include <vapours/assert.hpp>
namespace ams::util {
struct in_place_t{};
constexpr inline in_place_t in_place = {};
}

View file

@ -0,0 +1,629 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <vapours/common.hpp>
#include <vapours/assert.hpp>
#include <vapours/util/util_in_place.hpp>
#include <vapours/util/impl/util_enable_copy_move.hpp>
namespace ams::util {
namespace impl {
class NulloptHelper {
public:
template<typename T>
static consteval T CreateInstance() {
return T(T::ConstructionArgument::Token);
}
};
}
struct nullopt_t {
private:
friend class impl::NulloptHelper;
enum class ConstructionArgument {
Token,
};
public:
consteval nullopt_t(ConstructionArgument) { /* ... */ }
};
constexpr inline nullopt_t nullopt = impl::NulloptHelper::CreateInstance<nullopt_t>();
namespace impl {
template<typename T>
struct OptionalPayloadBase {
using StoredType = typename std::remove_const<T>::type;
struct EmptyType{};
template<typename U, bool = std::is_trivially_destructible<U>::value>
union StorageType {
EmptyType m_empty;
U m_value;
constexpr ALWAYS_INLINE StorageType() : m_empty() { /* ... */ }
template<typename... Args>
constexpr ALWAYS_INLINE StorageType(in_place_t, Args &&... args) : m_value(std::forward<Args>(args)...) { /* ... */ }
template<typename V, typename... Args>
constexpr ALWAYS_INLINE StorageType(std::initializer_list<V> il, Args &&... args) : m_value(il, std::forward<Args>(args)...) { /* ... */ }
};
template<typename U>
union StorageType<U, false> {
EmptyType m_empty;
U m_value;
constexpr ALWAYS_INLINE StorageType() : m_empty() { /* ... */ }
template<typename... Args>
constexpr ALWAYS_INLINE StorageType(in_place_t, Args &&... args) : m_value(std::forward<Args>(args)...) { /* ... */ }
template<typename V, typename... Args>
constexpr ALWAYS_INLINE StorageType(std::initializer_list<V> il, Args &&... args) : m_value(il, std::forward<Args>(args)...) { /* ... */ }
constexpr ALWAYS_INLINE ~StorageType() { /* ... */ }
};
StorageType<StoredType> m_payload;
bool m_engaged = false;
constexpr OptionalPayloadBase() = default;
constexpr ~OptionalPayloadBase() = default;
template<typename... Args>
constexpr OptionalPayloadBase(in_place_t tag, Args &&... args) : m_payload(tag, std::forward<Args>(args)...), m_engaged(true) { /* ... */ }
template<typename U, typename... Args>
constexpr OptionalPayloadBase(std::initializer_list<U> il, Args &&... args) : m_payload(il, std::forward<Args>(args)...), m_engaged(true) { /* ... */ }
constexpr OptionalPayloadBase(bool engaged, const OptionalPayloadBase &rhs) { if (rhs.m_engaged) { this->Construct(rhs.Get()); } }
constexpr OptionalPayloadBase(bool engaged, OptionalPayloadBase &&rhs) { if (rhs.m_engaged) { this->Construct(std::move(rhs.Get())); } }
constexpr OptionalPayloadBase(const OptionalPayloadBase &) = default;
constexpr OptionalPayloadBase(OptionalPayloadBase &&) = default;
constexpr OptionalPayloadBase &operator=(const OptionalPayloadBase &) = default;
constexpr OptionalPayloadBase &operator=(OptionalPayloadBase &&) = default;
constexpr void CopyAssign(const OptionalPayloadBase &rhs) {
if (m_engaged && rhs.m_engaged) {
this->Get() = rhs.Get();
} else if (rhs.m_engaged) {
this->Construct(rhs.Get());
} else {
this->Reset();
}
}
constexpr void MoveAssign(OptionalPayloadBase &&rhs) {
if (m_engaged && rhs.m_engaged) {
this->Get() = std::move(rhs.Get());
} else if (rhs.m_engaged) {
this->Construct(std::move(rhs.Get()));
} else {
this->Reset();
}
}
template<typename... Args>
constexpr void Construct(Args &&... args) {
std::construct_at(std::addressof(m_payload.m_value), std::forward<Args>(args)...);
m_engaged = true;
}
constexpr void Destroy() {
m_engaged = false;
std::destroy_at(std::addressof(m_payload.m_value));
}
constexpr ALWAYS_INLINE T &Get() { return m_payload.m_value; }
constexpr ALWAYS_INLINE const T &Get() const { return m_payload.m_value; }
constexpr void Reset() {
if (m_engaged) {
this->Destroy();
}
}
};
template<typename T, bool = std::is_trivially_destructible<T>::value, bool = std::is_trivially_copy_assignable<T>::value && std::is_trivially_copy_constructible<T>::value, bool = std::is_trivially_move_assignable<T>::value && std::is_trivially_move_constructible<T>::value>
struct OptionalPayload;
template<typename T>
struct OptionalPayload<T, true, true, true> : OptionalPayloadBase<T> {
using OptionalPayloadBase<T>::OptionalPayloadBase;
constexpr OptionalPayload() = default;
};
template<typename T>
struct OptionalPayload<T, true, false, true> : OptionalPayloadBase<T> {
using OptionalPayloadBase<T>::OptionalPayloadBase;
constexpr OptionalPayload() = default;
constexpr ~OptionalPayload() = default;
constexpr OptionalPayload(const OptionalPayload &) = default;
constexpr OptionalPayload(OptionalPayload &&) = default;
constexpr OptionalPayload& operator=(OptionalPayload &&) = default;
constexpr OptionalPayload &operator=(const OptionalPayload &rhs) {
this->CopyAssign(rhs);
return *this;
}
};
template<typename T>
struct OptionalPayload<T, true, true, false> : OptionalPayloadBase<T> {
using OptionalPayloadBase<T>::OptionalPayloadBase;
constexpr OptionalPayload() = default;
constexpr ~OptionalPayload() = default;
constexpr OptionalPayload(const OptionalPayload &) = default;
constexpr OptionalPayload(OptionalPayload &&) = default;
constexpr OptionalPayload& operator=(const OptionalPayload &) = default;
constexpr OptionalPayload &operator=(OptionalPayload &&rhs) {
this->MoveAssign(std::move(rhs));
return *this;
}
};
template<typename T>
struct OptionalPayload<T, true, false, false> : OptionalPayloadBase<T> {
using OptionalPayloadBase<T>::OptionalPayloadBase;
constexpr OptionalPayload() = default;
constexpr ~OptionalPayload() = default;
constexpr OptionalPayload(const OptionalPayload &) = default;
constexpr OptionalPayload(OptionalPayload &&) = default;
constexpr OptionalPayload &operator=(const OptionalPayload &rhs) {
this->CopyAssign(rhs);
return *this;
}
constexpr OptionalPayload &operator=(OptionalPayload &&rhs) {
this->MoveAssign(std::move(rhs));
return *this;
}
};
template<typename T, bool TrivialCopy, bool TrivialMove>
struct OptionalPayload<T, false, TrivialCopy, TrivialMove> : OptionalPayload<T, true, TrivialCopy, TrivialMove> {
using OptionalPayload<T, true, TrivialCopy, TrivialMove>::OptionalPayload;
constexpr OptionalPayload() = default;
constexpr OptionalPayload(const OptionalPayload &) = default;
constexpr OptionalPayload(OptionalPayload &&) = default;
constexpr OptionalPayload& operator=(const OptionalPayload &) = default;
constexpr OptionalPayload& operator=(OptionalPayload &&) = default;
constexpr ~OptionalPayload() { this->Reset(); }
};
template<typename T, typename Derived>
class OptionalBaseImpl {
protected:
using StoredType = std::remove_const<T>::type;
template<typename... Args>
constexpr void ConstructImpl(Args &&... args) { static_cast<Derived *>(this)->m_payload.Construct(std::forward<Args>(args)...); }
constexpr void DestructImpl() { static_cast<Derived *>(this)->m_payload.Destroy(); }
constexpr void ResetImpl() { static_cast<Derived *>(this)->m_payload.Reset(); }
constexpr ALWAYS_INLINE bool IsEngagedImpl() const { return static_cast<const Derived *>(this)->m_payload.m_engaged; }
constexpr ALWAYS_INLINE T &GetImpl() { return static_cast<Derived *>(this)->m_payload.Get(); }
constexpr ALWAYS_INLINE const T &GetImpl() const { return static_cast<const Derived *>(this)->m_payload.Get(); }
};
template<typename T, bool = std::is_trivially_copy_constructible<T>::value, bool = std::is_trivially_move_constructible<T>::value>
struct OptionalBase : OptionalBaseImpl<T, OptionalBase<T>> {
OptionalPayload<T> m_payload;
constexpr OptionalBase() = default;
template<typename... Args, std::enable_if_t<std::is_constructible<T, Args...>::value, bool> = false>
constexpr explicit OptionalBase(in_place_t, Args &&... args) : m_payload(in_place, std::forward<Args>(args)...) { /* ... */ }
template<typename U, typename... Args, std::enable_if_t<std::is_constructible<T, std::initializer_list<U> &, Args...>::value, bool> = false>
constexpr explicit OptionalBase(in_place_t, std::initializer_list<U> il, Args &&... args) : m_payload(in_place, il, std::forward<Args>(args)...) { /* ... */ }
constexpr OptionalBase(const OptionalBase &rhs) : m_payload(rhs.m_payload.m_engaged, rhs.m_payload) { /* ... */ }
constexpr OptionalBase(OptionalBase &&rhs) : m_payload(rhs.m_payload.m_engaged, std::move(rhs.m_payload)) { /* ... */ }
constexpr OptionalBase &operator=(const OptionalBase &) = default;
constexpr OptionalBase &operator=(OptionalBase &&) = default;
};
template<typename T>
struct OptionalBase<T, false, true> : OptionalBaseImpl<T, OptionalBase<T>> {
OptionalPayload<T> m_payload;
constexpr OptionalBase() = default;
template<typename... Args, std::enable_if_t<std::is_constructible<T, Args...>::value, bool> = false>
constexpr explicit OptionalBase(in_place_t, Args &&... args) : m_payload(in_place, std::forward<Args>(args)...) { /* ... */ }
template<typename U, typename... Args, std::enable_if_t<std::is_constructible<T, std::initializer_list<U> &, Args...>::value, bool> = false>
constexpr explicit OptionalBase(in_place_t, std::initializer_list<U> il, Args &&... args) : m_payload(in_place, il, std::forward<Args>(args)...) { /* ... */ }
constexpr OptionalBase(const OptionalBase &rhs) : m_payload(rhs.m_payload.m_engaged, rhs.m_payload) { /* ... */ }
constexpr OptionalBase(OptionalBase &&rhs) = default;
constexpr OptionalBase &operator=(const OptionalBase &) = default;
constexpr OptionalBase &operator=(OptionalBase &&) = default;
};
template<typename T>
struct OptionalBase<T, true, false> : OptionalBaseImpl<T, OptionalBase<T>> {
OptionalPayload<T> m_payload;
constexpr OptionalBase() = default;
template<typename... Args, std::enable_if_t<std::is_constructible<T, Args...>::value, bool> = false>
constexpr explicit OptionalBase(in_place_t, Args &&... args) : m_payload(in_place, std::forward<Args>(args)...) { /* ... */ }
template<typename U, typename... Args, std::enable_if_t<std::is_constructible<T, std::initializer_list<U> &, Args...>::value, bool> = false>
constexpr explicit OptionalBase(in_place_t, std::initializer_list<U> il, Args &&... args) : m_payload(in_place, il, std::forward<Args>(args)...) { /* ... */ }
constexpr OptionalBase(const OptionalBase &rhs) = default;
constexpr OptionalBase(OptionalBase &&rhs) : m_payload(rhs.m_payload.m_engaged, std::move(rhs.m_payload)) { /* ... */ }
constexpr OptionalBase &operator=(const OptionalBase &) = default;
constexpr OptionalBase &operator=(OptionalBase &&) = default;
};
template<typename T>
struct OptionalBase<T, true, true> : OptionalBaseImpl<T, OptionalBase<T>> {
OptionalPayload<T> m_payload;
constexpr OptionalBase() = default;
template<typename... Args, std::enable_if_t<std::is_constructible<T, Args...>::value, bool> = false>
constexpr explicit OptionalBase(in_place_t, Args &&... args) : m_payload(in_place, std::forward<Args>(args)...) { /* ... */ }
template<typename U, typename... Args, std::enable_if_t<std::is_constructible<T, std::initializer_list<U> &, Args...>::value, bool> = false>
constexpr explicit OptionalBase(in_place_t, std::initializer_list<U> il, Args &&... args) : m_payload(in_place, il, std::forward<Args>(args)...) { /* ... */ }
constexpr OptionalBase(const OptionalBase &rhs) = default;
constexpr OptionalBase(OptionalBase &&rhs) = default;
constexpr OptionalBase &operator=(const OptionalBase &) = default;
constexpr OptionalBase &operator=(OptionalBase &&) = default;
};
}
template<typename T>
class optional;
namespace impl {
template<typename T, typename U>
constexpr inline bool ConvertsFromOptional = std::is_constructible<T, const optional<U> &>::value ||
std::is_constructible<T, optional<U> &>::value ||
std::is_constructible<T, const optional<U> &&>::value ||
std::is_constructible<T, optional<U> &&>::value ||
std::is_convertible<const optional<U> &, T>::value ||
std::is_convertible<optional<U> &, T>::value ||
std::is_convertible<const optional<U> &&, T>::value ||
std::is_convertible<optional<U> &&, T>::value;
template<typename T, typename U>
constexpr inline bool AssignsFromOptional = std::is_assignable<T &, const optional<U> &>::value ||
std::is_assignable<T &, optional<U> &>::value ||
std::is_assignable<T &, const optional<U> &&>::value ||
std::is_assignable<T &, optional<U> &&>::value;
}
template<typename T>
class optional : private impl::OptionalBase<T>, private impl::EnableCopyMove<std::is_copy_constructible<T>::value, std::is_copy_constructible<T>::value && std::is_copy_assignable<T>::value, std::is_move_constructible<T>::value, std::is_move_constructible<T>::value && std::is_move_assignable<T>::value, optional<T>> {
static_assert(!std::is_same<std::remove_cv_t<T>, ::ams::util::nullopt_t>::value);
static_assert(!std::is_same<std::remove_cv_t<T>, ::ams::util::in_place_t>::value);
static_assert(!std::is_reference<T>::value);
private:
using Base = impl::OptionalBase<T>;
template<typename U> static constexpr inline bool IsNotSelf = !std::is_same<optional, std::remove_cvref_t<U>>::value;
template<typename U> static constexpr inline bool IsNotTag = !std::is_same<::ams::util::in_place_t, std::remove_cvref_t<U>>::value && !std::is_same<::std::in_place_t, std::remove_cvref_t<U>>::value;
template<bool... Cond>
using Requires = std::enable_if_t<(Cond && ...), bool>;
public:
using value_type = T;
public:
constexpr optional() { /* ... */ }
constexpr optional(nullopt_t) { /* ... */ }
template<typename U = T, Requires<IsNotSelf<U>, IsNotTag<U>, std::is_constructible<T, U>::value, std::is_convertible<U, T>::value> = true>
constexpr optional(U &&u) : Base(::ams::util::in_place, std::forward<U>(u)) { /* ... */ }
template<typename U = T, Requires<IsNotSelf<U>, IsNotTag<U>, std::is_constructible<T, U>::value, !std::is_convertible<U, T>::value> = false>
constexpr explicit optional(U &&u) : Base(::ams::util::in_place, std::forward<U>(u)) { /* ... */ }
template<typename U, Requires<!std::is_same<T, U>::value, std::is_constructible<T, const U &>::value, std::is_convertible<const U &, T>::value, !impl::ConvertsFromOptional<T, U>> = true>
constexpr optional(const optional<U> &u) {
if (u) {
this->emplace(*u);
}
}
template<typename U, Requires<!std::is_same<T, U>::value, std::is_constructible<T, const U &>::value, !std::is_convertible<const U &, T>::value, !impl::ConvertsFromOptional<T, U>> = false>
constexpr explicit optional(const optional<U> &u) {
if (u) {
this->emplace(*u);
}
}
template<typename U, Requires<!std::is_same<T, U>::value, std::is_constructible<T, const U &>::value, std::is_convertible<const U &, T>::value, !impl::ConvertsFromOptional<T, U>> = true>
constexpr optional(optional<U> &&u) {
if (u) {
this->emplace(std::move(*u));
}
}
template<typename U, Requires<!std::is_same<T, U>::value, std::is_constructible<T, const U &>::value, !std::is_convertible<const U &, T>::value, !impl::ConvertsFromOptional<T, U>> = false>
constexpr explicit optional(optional<U> &&u) {
if (u) {
this->emplace(std::move(*u));
}
}
template<typename... Args, Requires<std::is_constructible<T, Args...>::value> = false>
constexpr explicit optional(in_place_t, Args &&... args) : Base(::ams::util::in_place, std::forward<Args>(args)...) { /* ... */ }
template<typename U, typename... Args, Requires<std::is_constructible<T, std::initializer_list<U> &, Args...>::value> = false>
constexpr explicit optional(in_place_t, std::initializer_list<U> il, Args &&... args) : Base(::ams::util::in_place, il, std::forward<Args>(args)...) { /* ... */ }
constexpr optional &operator=(nullopt_t) { this->ResetImpl(); return *this; }
template<typename U = T>
constexpr std::enable_if_t<IsNotSelf<U> && !(std::is_scalar<T>::value && std::is_same<T, std::decay_t<U>>::value) && std::is_constructible<T, U>::value && std::is_assignable<T &, U>::value,
optional &>
operator =(U &&u) {
if (this->IsEngagedImpl()) {
this->GetImpl() = std::forward<U>(u);
} else {
this->ConstructImpl(std::forward<U>(u));
}
return *this;
}
template<typename U>
constexpr std::enable_if_t<!std::is_same<T, U>::value && std::is_constructible<T, const U &>::value && std::is_assignable<T &, const U &>::value && !impl::ConvertsFromOptional<T, U> && !impl::AssignsFromOptional<T, U>,
optional &>
operator =(const optional<U> &u) {
if (u) {
if (this->IsEngagedImpl()) {
this->GetImpl() = *u;
} else {
this->ConstructImpl(*u);
}
} else {
this->ResetImpl();
}
return *this;
}
template<typename U>
constexpr std::enable_if_t<!std::is_same<T, U>::value && std::is_constructible<T, U>::value && std::is_assignable<T &, U>::value && !impl::ConvertsFromOptional<T, U> && !impl::AssignsFromOptional<T, U>,
optional &>
operator =(optional<U> &&u) {
if (u) {
if (this->IsEngagedImpl()) {
this->GetImpl() = std::move(*u);
} else {
this->ConstructImpl(std::move(*u));
}
} else {
this->ResetImpl();
}
return *this;
}
template<typename... Args>
constexpr std::enable_if_t<std::is_constructible<T, Args...>::value, T &> emplace(Args &&... args) {
this->ResetImpl();
this->ConstructImpl(std::forward<Args>(args)...);
return this->GetImpl();
}
template<typename U, typename... Args>
constexpr std::enable_if_t<std::is_constructible<T, std::initializer_list<U> &, Args...>::value, T &> emplace(std::initializer_list<U> il, Args &&... args) {
this->ResetImpl();
this->ConstructImpl(il, std::forward<Args>(args)...);
return this->GetImpl();
}
constexpr void swap(optional &rhs) {
if (this->IsEngagedImpl() && rhs.IsEngagedImpl()) {
std::swap(this->GetImpl(), rhs.GetImpl());
} else if (this->IsEngagedImpl()) {
rhs.ConstructImpl(std::move(this->GetImpl()));
this->DestructImpl();
} else if (rhs.IsEngagedImpl()) {
this->ConstructImpl(std::move(rhs.GetImpl()));
rhs.DestructImpl();
}
}
constexpr ALWAYS_INLINE const T *operator ->() const { return std::addressof(this->GetImpl()); }
constexpr ALWAYS_INLINE T *operator ->() { return std::addressof(this->GetImpl()); }
constexpr ALWAYS_INLINE const T &operator *() const & { return this->GetImpl(); }
constexpr ALWAYS_INLINE T &operator *() & { return this->GetImpl(); }
constexpr ALWAYS_INLINE const T &&operator *() const && { return std::move(this->GetImpl()); }
constexpr ALWAYS_INLINE T &&operator *() && { return std::move(this->GetImpl()); }
constexpr ALWAYS_INLINE explicit operator bool() const { return this->IsEngagedImpl(); }
constexpr ALWAYS_INLINE bool has_value() const { return this->IsEngagedImpl(); }
constexpr ALWAYS_INLINE const T &value() const & { /* AMS_ASSERT(this->IsEngagedImpl()); */ return this->GetImpl(); }
constexpr ALWAYS_INLINE T &value() & { /* AMS_ASSERT(this->IsEngagedImpl()); */ return this->GetImpl(); }
constexpr ALWAYS_INLINE const T &&value() const && { /* AMS_ASSERT(this->IsEngagedImpl()); */ return std::move(this->GetImpl()); }
constexpr ALWAYS_INLINE T &&value() && { /* AMS_ASSERT(this->IsEngagedImpl()); */ return std::move(this->GetImpl()); }
template<typename U>
constexpr T value_or(U &&u) const & {
static_assert(std::is_copy_constructible<T>::value);
static_assert(std::is_convertible<U &&, T>::value);
return this->IsEngagedImpl() ? this->GetImpl() : static_cast<T>(std::forward<U>(u));
}
template<typename U>
constexpr T value_or(U &&u) && {
static_assert(std::is_move_constructible<T>::value);
static_assert(std::is_convertible<U &&, T>::value);
return this->IsEngagedImpl() ? std::move(this->GetImpl()) : static_cast<T>(std::forward<U>(u));
}
constexpr void reset() { this->ResetImpl(); }
};
namespace impl {
template<typename T> using optional_relop_t = std::enable_if_t<std::is_convertible<T, bool>::value, bool>;
template<typename T, typename U> using optional_eq_t = optional_relop_t<decltype(std::declval<const T &>() == std::declval<const U &>())>;
template<typename T, typename U> using optional_ne_t = optional_relop_t<decltype(std::declval<const T &>() != std::declval<const U &>())>;
template<typename T, typename U> using optional_le_t = optional_relop_t<decltype(std::declval<const T &>() <= std::declval<const U &>())>;
template<typename T, typename U> using optional_ge_t = optional_relop_t<decltype(std::declval<const T &>() >= std::declval<const U &>())>;
template<typename T, typename U> using optional_lt_t = optional_relop_t<decltype(std::declval<const T &>() < std::declval<const U &>())>;
template<typename T, typename U> using optional_gt_t = optional_relop_t<decltype(std::declval<const T &>() > std::declval<const U &>())>;
}
template<typename T, typename U>
constexpr inline impl::optional_eq_t<T, U> operator==(const optional<T> &lhs, const optional<U> &rhs) { return static_cast<bool>(lhs) == static_cast<bool>(rhs) && (!lhs || *lhs == *rhs); }
template<typename T, typename U>
constexpr inline impl::optional_ne_t<T, U> operator!=(const optional<T> &lhs, const optional<U> &rhs) { return static_cast<bool>(lhs) != static_cast<bool>(rhs) || (static_cast<bool>(lhs) && *lhs != *rhs); }
template<typename T, typename U>
constexpr inline impl::optional_lt_t<T, U> operator< (const optional<T> &lhs, const optional<U> &rhs) { return static_cast<bool>(rhs) && (!lhs || *lhs < *rhs); }
template<typename T, typename U>
constexpr inline impl::optional_gt_t<T, U> operator> (const optional<T> &lhs, const optional<U> &rhs) { return static_cast<bool>(lhs) && (!rhs || *lhs > *rhs); }
template<typename T, typename U>
constexpr inline impl::optional_le_t<T, U> operator<=(const optional<T> &lhs, const optional<U> &rhs) { return !lhs || (static_cast<bool>(rhs) && *lhs <= *rhs); }
template<typename T, typename U>
constexpr inline impl::optional_ge_t<T, U> operator>=(const optional<T> &lhs, const optional<U> &rhs) { return !rhs || (static_cast<bool>(lhs) && *lhs >= *rhs); }
template<typename T, std::three_way_comparable_with<T> U>
constexpr inline std::compare_three_way_result_t<T, U> operator <=>(const optional<T> &lhs, const optional<U> &rhs) {
return (lhs && rhs) ? *lhs <=> *rhs : static_cast<bool>(lhs) <=> static_cast<bool>(rhs);
}
template<typename T> constexpr inline bool operator==(const optional<T> &lhs, nullopt_t) { return !lhs; }
template<typename T> constexpr inline std::strong_ordering operator<=>(const optional<T> &lhs, nullopt_t) { return static_cast<bool>(lhs) <=> false; }
template<typename T, typename U>
constexpr inline impl::optional_eq_t<T, U> operator==(const optional<T> &lhs, const U &rhs) { return lhs && *lhs == rhs; }
template<typename T, typename U>
constexpr inline impl::optional_eq_t<U, T> operator==(const U &lhs, const optional<T> &rhs) { return rhs && lhs == *rhs; }
template<typename T, typename U>
constexpr inline impl::optional_ne_t<T, U> operator!=(const optional<T> &lhs, const U &rhs) { return !lhs || *lhs != rhs; }
template<typename T, typename U>
constexpr inline impl::optional_ne_t<U, T> operator!=(const U &lhs, const optional<T> &rhs) { return !rhs || lhs != *rhs; }
template<typename T, typename U>
constexpr inline impl::optional_lt_t<T, U> operator< (const optional<T> &lhs, const U &rhs) { return !lhs || *lhs < rhs; }
template<typename T, typename U>
constexpr inline impl::optional_lt_t<U, T> operator< (const U &lhs, const optional<T> &rhs) { return rhs && lhs < *rhs; }
template<typename T, typename U>
constexpr inline impl::optional_gt_t<T, U> operator> (const optional<T> &lhs, const U &rhs) { return lhs && *lhs > rhs; }
template<typename T, typename U>
constexpr inline impl::optional_gt_t<U, T> operator> (const U &lhs, const optional<T> &rhs) { return !rhs || lhs > *rhs; }
template<typename T, typename U>
constexpr inline impl::optional_le_t<T, U> operator<=(const optional<T> &lhs, const U &rhs) { return !lhs || *lhs <= rhs; }
template<typename T, typename U>
constexpr inline impl::optional_le_t<U, T> operator<=(const U &lhs, const optional<T> &rhs) { return rhs && lhs <= *rhs; }
template<typename T, typename U>
constexpr inline impl::optional_ge_t<T, U> operator>=(const optional<T> &lhs, const U &rhs) { return lhs && *lhs >= rhs; }
template<typename T, typename U>
constexpr inline impl::optional_ge_t<U, T> operator>=(const U &lhs, const optional<T> &rhs) { return !rhs || lhs >= *rhs; }
namespace impl {
template<typename T>
constexpr inline bool IsOptional = false;
template<typename T>
constexpr inline bool IsOptional<optional<T>> = true;
}
template<typename T, typename U> requires (!impl::IsOptional<U>) && std::three_way_comparable_with<T, U>
constexpr inline std::compare_three_way_result_t<T, U> operator<=>(const optional<T> &lhs, const U &rhs) {
return static_cast<bool>(lhs) ? *lhs <=> rhs : std::strong_ordering::less;
}
template<typename T>
constexpr inline std::enable_if_t<std::is_constructible<std::decay_t<T>, T>::value, optional<std::decay_t<T>>> make_optional(T && t) { return optional<std::decay_t<T>>{ std::forward<T>(t) }; }
template<typename T, typename... Args>
constexpr inline std::enable_if_t<std::is_constructible<T, Args...>::value, optional<T>> make_optional(Args &&... args) { return optional<T>{ ::ams::util::in_place, std::forward<Args>(args)... }; }
template<typename T, typename U, typename... Args>
constexpr inline std::enable_if_t<std::is_constructible<T, std::initializer_list<U> &, Args...>::value, optional<T>> make_optional(std::initializer_list<U> il, Args &&... args) { return optional<T>{ ::ams::util::in_place, il, std::forward<Args>(args)... }; }
template<typename T> optional(T) -> optional<T>;
}
namespace std {
template<typename T>
constexpr inline enable_if_t<is_move_constructible_v<T> && is_swappable_v<T>> swap(::ams::util::optional<T> &lhs, ::ams::util::optional<T> &rhs) noexcept {
lhs.swap(rhs);
}
template<typename T>
constexpr inline enable_if_t<!(is_move_constructible_v<T> && is_swappable_v<T>)> swap(::ams::util::optional<T> &lhs, ::ams::util::optional<T> &rhs) = delete;
}

View file

@ -431,7 +431,7 @@ namespace ams::mitm {
alignas(os::MemoryPageSize) CalibrationInfo g_temp_calibration_info = {}; alignas(os::MemoryPageSize) CalibrationInfo g_temp_calibration_info = {};
void SaveProdInfoBackup(std::optional<ams::fs::FileStorage> *dst, const CalibrationInfo &info) { void SaveProdInfoBackup(util::optional<ams::fs::FileStorage> *dst, const CalibrationInfo &info) {
char backup_fn[0x100]; char backup_fn[0x100];
GetBackupFileName(backup_fn, sizeof(backup_fn), info); GetBackupFileName(backup_fn, sizeof(backup_fn), info);
@ -505,9 +505,9 @@ namespace ams::mitm {
alignas(os::MemoryPageSize) CalibrationInfo g_blank_calibration_info = {}; alignas(os::MemoryPageSize) CalibrationInfo g_blank_calibration_info = {};
alignas(os::MemoryPageSize) SecureCalibrationInfoBackup g_secure_calibration_info_backup = {}; alignas(os::MemoryPageSize) SecureCalibrationInfoBackup g_secure_calibration_info_backup = {};
std::optional<ams::fs::FileStorage> g_prodinfo_backup_file; util::optional<ams::fs::FileStorage> g_prodinfo_backup_file;
std::optional<ams::fs::MemoryStorage> g_blank_prodinfo_storage; util::optional<ams::fs::MemoryStorage> g_blank_prodinfo_storage;
std::optional<ams::fs::MemoryStorage> g_fake_secure_backup_storage; util::optional<ams::fs::MemoryStorage> g_fake_secure_backup_storage;
bool g_allow_writes = false; bool g_allow_writes = false;
bool g_has_secure_backup = false; bool g_has_secure_backup = false;

View file

@ -95,7 +95,7 @@ namespace ams::mitm::sysupdater {
private: private:
Result result; Result result;
os::SystemEvent event; os::SystemEvent event;
std::optional<ThreadInfo> thread_info; util::optional<ThreadInfo> thread_info;
ncm::InstallTaskBase *task; ncm::InstallTaskBase *task;
public: public:
AsyncPrepareSdCardUpdateImpl(ncm::InstallTaskBase *task) : result(ResultSuccess()), event(os::EventClearMode_ManualClear, true), thread_info(), task(task) { /* ... */ } AsyncPrepareSdCardUpdateImpl(ncm::InstallTaskBase *task) : result(ResultSuccess()), event(os::EventClearMode_ManualClear, true), thread_info(), task(task) { /* ... */ }

View file

@ -497,7 +497,7 @@ namespace ams::mitm::sysupdater {
R_TRY(this->update_transfer_memory->Map(std::addressof(tmem_buffer), os::MemoryPermission_None)); R_TRY(this->update_transfer_memory->Map(std::addressof(tmem_buffer), os::MemoryPermission_None));
auto tmem_guard = SCOPE_GUARD { auto tmem_guard = SCOPE_GUARD {
this->update_transfer_memory->Unmap(); this->update_transfer_memory->Unmap();
this->update_transfer_memory = std::nullopt; this->update_transfer_memory = util::nullopt;
}; };
/* Now that the memory is mapped, the input handle is managed and can be released. */ /* Now that the memory is mapped, the input handle is managed and can be released. */

View file

@ -57,8 +57,8 @@ namespace ams::mitm::sysupdater {
class SystemUpdateService { class SystemUpdateService {
private: private:
SystemUpdateApplyManager apply_manager; SystemUpdateApplyManager apply_manager;
std::optional<ncm::PackageSystemDowngradeTask> update_task; util::optional<ncm::PackageSystemDowngradeTask> update_task;
std::optional<os::TransferMemory> update_transfer_memory; util::optional<os::TransferMemory> update_transfer_memory;
bool setup_update; bool setup_update;
bool requested_update; bool requested_update;
public: public:

View file

@ -42,7 +42,7 @@ namespace ams::spl::impl {
/* KeySlot management. */ /* KeySlot management. */
KeySlotCache g_keyslot_cache; KeySlotCache g_keyslot_cache;
std::optional<KeySlotCacheEntry> g_keyslot_cache_entry[MaxPhysicalAesKeySlots]; util::optional<KeySlotCacheEntry> g_keyslot_cache_entry[MaxPhysicalAesKeySlots];
inline s32 GetMaxPhysicalKeySlots() { inline s32 GetMaxPhysicalKeySlots() {
return (hos::GetVersion() >= hos::Version_6_0_0) ? MaxPhysicalAesKeySlots : MaxPhysicalAesKeySlotsDeprecated; return (hos::GetVersion() >= hos::Version_6_0_0) ? MaxPhysicalAesKeySlots : MaxPhysicalAesKeySlotsDeprecated;