strat: split out common functionality for future meso use
This commit is contained in:
22
stratosphere/libstratosphere/include/atmosphere/common.hpp
Normal file
22
stratosphere/libstratosphere/include/atmosphere/common.hpp
Normal file
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 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 "common_includes.hpp"
|
||||
#include "defines.hpp"
|
||||
#include "util.hpp"
|
||||
#include "results.hpp"
|
||||
#include "svc.hpp"
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 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
|
||||
|
||||
/* C headers. */
|
||||
#include <cstdint>
|
||||
#include <cstdarg>
|
||||
#include <cstdlib>
|
||||
#include <cstddef>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <climits>
|
||||
#include <cctype>
|
||||
|
||||
/* C++ headers. */
|
||||
#include <type_traits>
|
||||
#include <limits>
|
||||
#include <atomic>
|
||||
#include <utility>
|
||||
#include <iterator>
|
||||
#include <optional>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <tuple>
|
||||
#include <array>
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
#include <set>
|
||||
|
||||
/* Libnx. */
|
||||
#include <switch.h>
|
||||
|
||||
/* Atmosphere meta. */
|
||||
#if __has_include(<atmosphere.h>)
|
||||
#include <atmosphere.h>
|
||||
#endif
|
||||
46
stratosphere/libstratosphere/include/atmosphere/defines.hpp
Normal file
46
stratosphere/libstratosphere/include/atmosphere/defines.hpp
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 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 "common_includes.hpp"
|
||||
|
||||
/* Any broadly useful language defines should go here. */
|
||||
|
||||
#define AMS_ASSERT(expr) do { if (!(expr)) { std::abort(); } } while (0)
|
||||
|
||||
#define AMS_UNREACHABLE_DEFAULT_CASE() default: std::abort()
|
||||
|
||||
#define NON_COPYABLE(cls) \
|
||||
cls(const cls&) = delete; \
|
||||
cls& operator=(const cls&) = delete
|
||||
|
||||
#define NON_MOVEABLE(cls) \
|
||||
cls(cls&&) = delete; \
|
||||
cls& operator=(cls&&) = delete
|
||||
|
||||
#define ALIGNED(algn) __attribute__((aligned(algn)))
|
||||
#define NORETURN __attribute__((noreturn))
|
||||
#define WEAK __attribute__((weak))
|
||||
|
||||
|
||||
#define CONCATENATE_IMPL(S1, s2) s1##s2
|
||||
#define CONCATENATE(s1, s2) CONCATENATE_IMPL(s1, s2)
|
||||
|
||||
#ifdef __COUNTER__
|
||||
#define ANONYMOUS_VARIABLE(pref) CONCATENATE(pref, __COUNTER__)
|
||||
#else
|
||||
#define ANONYMOUS_VARIABLE(pref) CONCATENATE(pref, __LINE__)
|
||||
#endif
|
||||
50
stratosphere/libstratosphere/include/atmosphere/results.hpp
Normal file
50
stratosphere/libstratosphere/include/atmosphere/results.hpp
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 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 "defines.hpp"
|
||||
#include "util.hpp"
|
||||
|
||||
/* Utilities. */
|
||||
#include "results/results_common.hpp"
|
||||
|
||||
/* Official. */
|
||||
#include "results/cal_results.hpp"
|
||||
#include "results/creport_results.hpp"
|
||||
#include "results/debug_results.hpp"
|
||||
#include "results/dmnt_results.hpp"
|
||||
#include "results/err_results.hpp"
|
||||
#include "results/fatal_results.hpp"
|
||||
#include "results/fs_results.hpp"
|
||||
#include "results/hipc_results.hpp"
|
||||
#include "results/i2c_results.hpp"
|
||||
#include "results/kvdb_results.hpp"
|
||||
#include "results/loader_results.hpp"
|
||||
#include "results/lr_results.hpp"
|
||||
#include "results/os_results.hpp"
|
||||
#include "results/ncm_results.hpp"
|
||||
#include "results/pm_results.hpp"
|
||||
#include "results/ro_results.hpp"
|
||||
#include "results/settings_results.hpp"
|
||||
#include "results/sf_results.hpp"
|
||||
#include "results/sm_results.hpp"
|
||||
#include "results/spl_results.hpp"
|
||||
#include "results/svc_results.hpp"
|
||||
#include "results/updater_results.hpp"
|
||||
#include "results/vi_results.hpp"
|
||||
|
||||
/* Unofficial. */
|
||||
#include "results/exosphere_results.hpp"
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 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 "results_common.hpp"
|
||||
|
||||
namespace ams::cal {
|
||||
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(198);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(CalibrationDataCrcError, 101);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 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 "results_common.hpp"
|
||||
|
||||
namespace ams::creport {
|
||||
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(168);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(UndefinedInstruction, 0);
|
||||
R_DEFINE_ERROR_RESULT(InstructionAbort, 1);
|
||||
R_DEFINE_ERROR_RESULT(DataAbort, 2);
|
||||
R_DEFINE_ERROR_RESULT(AlignmentFault, 3);
|
||||
R_DEFINE_ERROR_RESULT(DebuggerAttached, 4);
|
||||
R_DEFINE_ERROR_RESULT(BreakPoint, 5);
|
||||
R_DEFINE_ERROR_RESULT(UserBreak, 6);
|
||||
R_DEFINE_ERROR_RESULT(DebuggerBreak, 7);
|
||||
R_DEFINE_ERROR_RESULT(UndefinedSystemCall, 8);
|
||||
R_DEFINE_ERROR_RESULT(SystemMemoryError, 9);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(IncompleteReport, 99);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 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 "results_common.hpp"
|
||||
|
||||
namespace ams::dbg {
|
||||
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(183);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(CannotDebug, 1);
|
||||
R_DEFINE_ERROR_RESULT(AlreadyAttached, 2);
|
||||
R_DEFINE_ERROR_RESULT(Cancelled, 3);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 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 "results_common.hpp"
|
||||
|
||||
namespace ams::dmnt {
|
||||
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(13);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(Unknown, 1);
|
||||
R_DEFINE_ERROR_RESULT(DebuggingDisabled, 2);
|
||||
|
||||
/* Atmosphere extension. */
|
||||
namespace cheat {
|
||||
|
||||
R_DEFINE_ABSTRACT_ERROR_RANGE(CheatError, 6500, 6599);
|
||||
R_DEFINE_ERROR_RESULT(CheatNotAttached, 6500);
|
||||
R_DEFINE_ERROR_RESULT(CheatNullBuffer, 6501);
|
||||
R_DEFINE_ERROR_RESULT(CheatInvalidBuffer, 6502);
|
||||
R_DEFINE_ERROR_RESULT(CheatUnknownId, 6503);
|
||||
R_DEFINE_ERROR_RESULT(CheatOutOfResource, 6504);
|
||||
R_DEFINE_ERROR_RESULT(CheatInvalid, 6505);
|
||||
R_DEFINE_ERROR_RESULT(CheatCannotDisable, 6506);
|
||||
|
||||
R_DEFINE_ABSTRACT_ERROR_RANGE(FrozenAddressError, 6600, 6699);
|
||||
R_DEFINE_ERROR_RESULT(FrozenAddressInvalidWidth, 6600);
|
||||
R_DEFINE_ERROR_RESULT(FrozenAddressAlreadyExists, 6601);
|
||||
R_DEFINE_ERROR_RESULT(FrozenAddressNotFound, 6602);
|
||||
R_DEFINE_ERROR_RESULT(FrozenAddressOutOfResource, 6603);
|
||||
|
||||
R_DEFINE_ABSTRACT_ERROR_RANGE(VirtualMachineError, 6700, 6799);
|
||||
R_DEFINE_ERROR_RESULT(VirtualMachineInvalidConditionDepth, 6700);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 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 "results_common.hpp"
|
||||
|
||||
namespace ams::err {
|
||||
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(162);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(ApplicationAborted, 1);
|
||||
R_DEFINE_ERROR_RESULT(SystemModuleAborted, 2);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 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 "results_common.hpp"
|
||||
|
||||
namespace ams::exosphere {
|
||||
|
||||
/* Please note: These results are all custom, and not official. */
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(444);
|
||||
|
||||
|
||||
/* Result 1-1000 reserved for Atmosphere. */
|
||||
R_DEFINE_ERROR_RESULT(NotPresent, 1);
|
||||
R_DEFINE_ERROR_RESULT(VersionMismatch, 2);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 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 "results_common.hpp"
|
||||
|
||||
namespace ams::fatal {
|
||||
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(163);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(AllocationFailed, 1);
|
||||
R_DEFINE_ERROR_RESULT(NullGraphicsBuffer, 2);
|
||||
R_DEFINE_ERROR_RESULT(AlreadyThrown, 3);
|
||||
R_DEFINE_ERROR_RESULT(TooManyEvents, 4);
|
||||
R_DEFINE_ERROR_RESULT(InRepairWithoutVolHeld, 5);
|
||||
R_DEFINE_ERROR_RESULT(InRepairWithoutTimeReviserCartridge, 6);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 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 "results_common.hpp"
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(2);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(PathNotFound, 1);
|
||||
R_DEFINE_ERROR_RESULT(PathAlreadyExists, 2);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(TargetLocked, 7);
|
||||
R_DEFINE_ERROR_RESULT(DirectoryNotEmpty, 8);
|
||||
|
||||
R_DEFINE_ERROR_RANGE (NotEnoughFreeSpace, 30, 45);
|
||||
R_DEFINE_ERROR_RANGE(NotEnoughFreeSpaceBis, 34, 38);
|
||||
R_DEFINE_ERROR_RESULT(NotEnoughFreeSpaceBisCalibration, 35);
|
||||
R_DEFINE_ERROR_RESULT(NotEnoughFreeSpaceBisSafe, 36);
|
||||
R_DEFINE_ERROR_RESULT(NotEnoughFreeSpaceBisUser, 37);
|
||||
R_DEFINE_ERROR_RESULT(NotEnoughFreeSpaceBisSystem, 38);
|
||||
R_DEFINE_ERROR_RESULT(NotEnoughFreeSpaceSdCard, 39);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(MountNameAlreadyExists, 60);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(TargetNotFound, 1002);
|
||||
|
||||
R_DEFINE_ERROR_RANGE(SdCardAccessFailed, 2000, 2499);
|
||||
R_DEFINE_ERROR_RESULT(SdCardNotPresent, 2001);
|
||||
|
||||
R_DEFINE_ERROR_RANGE(GameCardAccessFailed, 2500, 2999);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(NotImplemented, 3001);
|
||||
R_DEFINE_ERROR_RESULT(OutOfRange, 3005);
|
||||
|
||||
R_DEFINE_ERROR_RANGE(AllocationFailure, 3200, 3499);
|
||||
R_DEFINE_ERROR_RESULT(AllocationFailureInDirectorySaveDataFileSystem, 3321);
|
||||
R_DEFINE_ERROR_RESULT(AllocationFailureInSubDirectoryFileSystem, 3355);
|
||||
|
||||
R_DEFINE_ERROR_RANGE(MmcAccessFailed, 3500, 3999);
|
||||
|
||||
R_DEFINE_ERROR_RANGE(DataCorrupted, 4000, 4999);
|
||||
R_DEFINE_ERROR_RANGE(RomCorrupted, 4001, 4299);
|
||||
R_DEFINE_ERROR_RANGE(SaveDataCorrupted, 4301, 4499);
|
||||
R_DEFINE_ERROR_RANGE(NcaCorrupted, 4501, 4599);
|
||||
R_DEFINE_ERROR_RANGE(IntegrityVerificationStorageCorrupted, 4601, 4639);
|
||||
R_DEFINE_ERROR_RANGE(PartitionFileSystemCorrupted, 4641, 4659);
|
||||
R_DEFINE_ERROR_RANGE(BuiltInStorageCorrupted, 4661, 4679);
|
||||
R_DEFINE_ERROR_RANGE(HostFileSystemCorrupted, 4701, 4719);
|
||||
R_DEFINE_ERROR_RANGE(DatabaseCorrupted, 4721, 4739);
|
||||
R_DEFINE_ERROR_RANGE(AesXtsFileSystemCorrupted, 4741, 4759);
|
||||
R_DEFINE_ERROR_RANGE(SaveDataTransferDataCorrupted, 4761, 4769);
|
||||
R_DEFINE_ERROR_RANGE(SignedSystemPartitionDataCorrupted, 4771, 4779);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(GameCardLogoDataCorrupted, 4781);
|
||||
|
||||
R_DEFINE_ERROR_RANGE(Unexpected, 5000, 5999);
|
||||
|
||||
R_DEFINE_ERROR_RANGE(PreconditionViolation, 6000, 6499);
|
||||
R_DEFINE_ERROR_RANGE(InvalidArgument, 6001, 6199);
|
||||
R_DEFINE_ERROR_RANGE(InvalidPath, 6002, 6029);
|
||||
R_DEFINE_ERROR_RESULT(TooLongPath, 6003);
|
||||
R_DEFINE_ERROR_RESULT(InvalidCharacter, 6004);
|
||||
R_DEFINE_ERROR_RESULT(InvalidPathFormat, 6005);
|
||||
R_DEFINE_ERROR_RESULT(DirectoryUnobtainable, 6006);
|
||||
R_DEFINE_ERROR_RESULT(NotNormalized, 6007);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(InvalidOffset, 6061);
|
||||
R_DEFINE_ERROR_RESULT(InvalidSize, 6062);
|
||||
R_DEFINE_ERROR_RESULT(NullptrArgument, 6063);
|
||||
R_DEFINE_ERROR_RESULT(InvalidAlignment, 6064);
|
||||
R_DEFINE_ERROR_RESULT(InvalidMountName, 6065);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(ExtensionSizeTooLarge, 6066);
|
||||
R_DEFINE_ERROR_RESULT(ExtensionSizeInvalid, 6067);
|
||||
|
||||
R_DEFINE_ERROR_RANGE(InvalidEnumValue, 6080, 6099);
|
||||
R_DEFINE_ERROR_RESULT(InvalidSaveDataState, 6081);
|
||||
R_DEFINE_ERROR_RESULT(InvalidSaveDataSpaceId, 6082);
|
||||
|
||||
R_DEFINE_ERROR_RANGE(InvalidOperationForOpenMode, 6200, 6299);
|
||||
R_DEFINE_ERROR_RESULT(FileExtensionWithoutOpenModeAllowAppend, 6201);
|
||||
|
||||
R_DEFINE_ERROR_RANGE(UnsupportedOperation, 6300, 6399);
|
||||
|
||||
R_DEFINE_ERROR_RANGE(PermissionDenied, 6400, 6449);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(WriteModeFileNotClosed, 6457);
|
||||
R_DEFINE_ERROR_RESULT(AllocatorAlignmentViolation, 6461);
|
||||
R_DEFINE_ERROR_RESULT(UserNotExist, 6465);
|
||||
|
||||
R_DEFINE_ERROR_RANGE(OutOfResource, 6700, 6799);
|
||||
R_DEFINE_ERROR_RESULT(MappingTableFull, 6706);
|
||||
R_DEFINE_ERROR_RESULT(OpenCountLimit, 6709);
|
||||
|
||||
R_DEFINE_ERROR_RANGE(MappingFailed, 6800, 6899);
|
||||
R_DEFINE_ERROR_RESULT(MapFull, 6811);
|
||||
|
||||
R_DEFINE_ERROR_RANGE(BadState, 6900, 6999);
|
||||
R_DEFINE_ERROR_RESULT(NotMounted, 6905);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 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 "results_common.hpp"
|
||||
|
||||
namespace ams::sf::hipc {
|
||||
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(11);
|
||||
|
||||
R_DEFINE_ABSTRACT_ERROR_RANGE(OutOfResource, 100, 299);
|
||||
R_DEFINE_ERROR_RESULT(OutOfSessionMemory, 102);
|
||||
R_DEFINE_ERROR_RANGE (OutOfSessions, 131, 139);
|
||||
R_DEFINE_ERROR_RESULT(PointerBufferTooSmall, 141);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(OutOfDomains, 200);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(SessionClosed, 301);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(InvalidRequestSize, 402);
|
||||
R_DEFINE_ERROR_RESULT(UnknownCommandType, 403);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(InvalidCmifRequest, 420);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(TargetNotDomain, 491);
|
||||
R_DEFINE_ERROR_RESULT(DomainObjectNotFound, 492);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 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 "results_common.hpp"
|
||||
|
||||
namespace ams::i2c {
|
||||
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(101);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(NoAck, 1);
|
||||
R_DEFINE_ERROR_RESULT(BusBusy, 2);
|
||||
R_DEFINE_ERROR_RESULT(FullCommandList, 3);
|
||||
R_DEFINE_ERROR_RESULT(TimedOut, 4);
|
||||
R_DEFINE_ERROR_RESULT(UnknownDevice, 5);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 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 "results_common.hpp"
|
||||
|
||||
namespace ams::kvdb {
|
||||
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(20);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(OutOfKeyResource, 1);
|
||||
R_DEFINE_ERROR_RESULT(KeyNotFound, 2);
|
||||
R_DEFINE_ERROR_RESULT(AllocationFailed, 4);
|
||||
R_DEFINE_ERROR_RESULT(InvalidKeyValue, 5);
|
||||
R_DEFINE_ERROR_RESULT(BufferInsufficient, 6);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(InvalidFilesystemState, 8);
|
||||
R_DEFINE_ERROR_RESULT(NotCreated, 9);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 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 "results_common.hpp"
|
||||
|
||||
namespace ams::ldr {
|
||||
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(9);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(TooLongArgument, 1);
|
||||
R_DEFINE_ERROR_RESULT(TooManyArguments, 2);
|
||||
R_DEFINE_ERROR_RESULT(TooLargeMeta, 3);
|
||||
R_DEFINE_ERROR_RESULT(InvalidMeta, 4);
|
||||
R_DEFINE_ERROR_RESULT(InvalidNso, 5);
|
||||
R_DEFINE_ERROR_RESULT(InvalidPath, 6);
|
||||
R_DEFINE_ERROR_RESULT(TooManyProcesses, 7);
|
||||
R_DEFINE_ERROR_RESULT(NotPinned, 8);
|
||||
R_DEFINE_ERROR_RESULT(InvalidProgramId, 9);
|
||||
R_DEFINE_ERROR_RESULT(InvalidVersion, 10);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(InsufficientAddressSpace, 51);
|
||||
R_DEFINE_ERROR_RESULT(InvalidNro, 52);
|
||||
R_DEFINE_ERROR_RESULT(InvalidNrr, 53);
|
||||
R_DEFINE_ERROR_RESULT(InvalidSignature, 54);
|
||||
R_DEFINE_ERROR_RESULT(InsufficientNroRegistrations, 55);
|
||||
R_DEFINE_ERROR_RESULT(InsufficientNrrRegistrations, 56);
|
||||
R_DEFINE_ERROR_RESULT(NroAlreadyLoaded, 57);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(InvalidAddress, 81);
|
||||
R_DEFINE_ERROR_RESULT(InvalidSize, 82);
|
||||
R_DEFINE_ERROR_RESULT(NotLoaded, 84);
|
||||
R_DEFINE_ERROR_RESULT(NotRegistered, 85);
|
||||
R_DEFINE_ERROR_RESULT(InvalidSession, 86);
|
||||
R_DEFINE_ERROR_RESULT(InvalidProcess, 87);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(UnknownCapability, 100);
|
||||
R_DEFINE_ERROR_RESULT(InvalidCapabilityKernelFlags, 103);
|
||||
R_DEFINE_ERROR_RESULT(InvalidCapabilitySyscallMask, 104);
|
||||
R_DEFINE_ERROR_RESULT(InvalidCapabilityMapRange, 106);
|
||||
R_DEFINE_ERROR_RESULT(InvalidCapabilityMapPage, 107);
|
||||
R_DEFINE_ERROR_RESULT(InvalidCapabilityInterruptPair, 111);
|
||||
R_DEFINE_ERROR_RESULT(InvalidCapabilityApplicationType, 113);
|
||||
R_DEFINE_ERROR_RESULT(InvalidCapabilityKernelVersion, 114);
|
||||
R_DEFINE_ERROR_RESULT(InvalidCapabilityHandleTable, 115);
|
||||
R_DEFINE_ERROR_RESULT(InvalidCapabilityDebugFlags, 116);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(InternalError, 200);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 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 "results_common.hpp"
|
||||
|
||||
namespace ams::lr {
|
||||
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(8);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(ProgramNotFound, 2);
|
||||
R_DEFINE_ERROR_RESULT(DataNotFound, 3);
|
||||
R_DEFINE_ERROR_RESULT(UnknownStorageId, 4);
|
||||
R_DEFINE_ERROR_RESULT(HtmlDocumentNotFound, 6);
|
||||
R_DEFINE_ERROR_RESULT(AddOnContentNotFound, 7);
|
||||
R_DEFINE_ERROR_RESULT(ControlNotFound, 8);
|
||||
R_DEFINE_ERROR_RESULT(LegalInformationNotFound, 9);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(TooManyRegisteredPaths, 90);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 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 "results_common.hpp"
|
||||
|
||||
namespace ams::ncm {
|
||||
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(5);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(PlaceHolderAlreadyExists, 2);
|
||||
R_DEFINE_ERROR_RESULT(PlaceHolderNotFound, 3);
|
||||
R_DEFINE_ERROR_RESULT(ContentAlreadyExists, 4);
|
||||
R_DEFINE_ERROR_RESULT(ContentNotFound, 5);
|
||||
R_DEFINE_ERROR_RESULT(ContentMetaNotFound, 7);
|
||||
R_DEFINE_ERROR_RESULT(AllocationFailed, 8);
|
||||
R_DEFINE_ERROR_RESULT(UnknownStorage, 12);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(InvalidContentStorage, 100);
|
||||
R_DEFINE_ERROR_RESULT(InvalidContentMetaDatabase, 110);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(BufferInsufficient, 180);
|
||||
R_DEFINE_ERROR_RESULT(InvalidContentMetaKey, 240);
|
||||
|
||||
R_DEFINE_ERROR_RANGE(ContentStorageNotActive, 250, 258);
|
||||
R_DEFINE_ERROR_RESULT(GameCardContentStorageNotActive, 251);
|
||||
R_DEFINE_ERROR_RESULT(NandSystemContentStorageNotActive, 252);
|
||||
R_DEFINE_ERROR_RESULT(NandUserContentStorageNotActive, 253);
|
||||
R_DEFINE_ERROR_RESULT(SdCardContentStorageNotActive, 254);
|
||||
R_DEFINE_ERROR_RESULT(UnknownContentStorageNotActive, 258);
|
||||
|
||||
R_DEFINE_ERROR_RANGE(ContentMetaDatabaseNotActive, 260, 268);
|
||||
R_DEFINE_ERROR_RESULT(GameCardContentMetaDatabaseNotActive, 261);
|
||||
R_DEFINE_ERROR_RESULT(NandSystemContentMetaDatabaseNotActive, 262);
|
||||
R_DEFINE_ERROR_RESULT(NandUserContentMetaDatabaseNotActive, 263);
|
||||
R_DEFINE_ERROR_RESULT(SdCardContentMetaDatabaseNotActive, 264);
|
||||
R_DEFINE_ERROR_RESULT(UnknownContentMetaDatabaseNotActive, 268);
|
||||
|
||||
R_DEFINE_ERROR_RANGE(InvalidArgument, 8181, 8191);
|
||||
R_DEFINE_ERROR_RESULT(InvalidOffset, 8182);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 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 "results_common.hpp"
|
||||
|
||||
namespace ams::os {
|
||||
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(3);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(Busy, 4);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(OutOfMemory, 8);
|
||||
R_DEFINE_ERROR_RESULT(OutOfResource, 9);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(OutOfVirtualAddressSpace, 12);
|
||||
R_DEFINE_ERROR_RESULT(ResourceLimit, 13);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 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 "results_common.hpp"
|
||||
|
||||
namespace ams::pm {
|
||||
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(15);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(ProcessNotFound, 1);
|
||||
R_DEFINE_ERROR_RESULT(AlreadyStarted, 2);
|
||||
R_DEFINE_ERROR_RESULT(NotExited, 3);
|
||||
R_DEFINE_ERROR_RESULT(DebugHookInUse, 4);
|
||||
R_DEFINE_ERROR_RESULT(ApplicationRunning, 5);
|
||||
R_DEFINE_ERROR_RESULT(InvalidSize, 6);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,286 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 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 "../defines.hpp"
|
||||
|
||||
namespace ams {
|
||||
|
||||
namespace result::impl {
|
||||
|
||||
class ResultTraits {
|
||||
public:
|
||||
using BaseType = u32;
|
||||
static_assert(std::is_same<BaseType, ::Result>::value, "std::is_same<BaseType, ::Result>::value");
|
||||
static constexpr BaseType SuccessValue = BaseType();
|
||||
static constexpr BaseType ModuleBits = 9;
|
||||
static constexpr BaseType DescriptionBits = 13;
|
||||
static constexpr BaseType ReservedBits = 10;
|
||||
static_assert(ModuleBits + DescriptionBits + ReservedBits == sizeof(BaseType) * CHAR_BIT, "ModuleBits + DescriptionBits + ReservedBits == sizeof(BaseType) * CHAR_BIT");
|
||||
public:
|
||||
NX_CONSTEXPR BaseType MakeValue(BaseType module, BaseType description) {
|
||||
return (module) | (description << ModuleBits);
|
||||
}
|
||||
|
||||
template<BaseType module, BaseType description>
|
||||
struct MakeStaticValue : public std::integral_constant<BaseType, MakeValue(module, description)> {
|
||||
static_assert(module < (1 << ModuleBits), "Invalid Module");
|
||||
static_assert(description < (1 << DescriptionBits), "Invalid Description");
|
||||
};
|
||||
|
||||
NX_CONSTEXPR BaseType GetModuleFromValue(BaseType value) {
|
||||
return value & ~(~BaseType() << ModuleBits);
|
||||
}
|
||||
|
||||
NX_CONSTEXPR BaseType GetDescriptionFromValue(BaseType value) {
|
||||
return ((value >> ModuleBits) & ~(~BaseType() << DescriptionBits));
|
||||
}
|
||||
};
|
||||
|
||||
/* Use CRTP for Results. */
|
||||
template<typename Self>
|
||||
class ResultBase {
|
||||
public:
|
||||
using BaseType = typename ResultTraits::BaseType;
|
||||
static constexpr BaseType SuccessValue = ResultTraits::SuccessValue;
|
||||
public:
|
||||
constexpr inline BaseType GetModule() const { return ResultTraits::GetModuleFromValue(static_cast<const Self *>(this)->GetValue()); }
|
||||
constexpr inline BaseType GetDescription() const { return ResultTraits::GetDescriptionFromValue(static_cast<const Self *>(this)->GetValue()); }
|
||||
};
|
||||
|
||||
class ResultConstructor;
|
||||
|
||||
}
|
||||
|
||||
class ResultSuccess;
|
||||
|
||||
class Result final : public result::impl::ResultBase<Result> {
|
||||
friend class ResultConstructor;
|
||||
public:
|
||||
using Base = typename result::impl::ResultBase<Result>;
|
||||
private:
|
||||
typename Base::BaseType value;
|
||||
private:
|
||||
/* TODO: Maybe one-day, the result constructor. */
|
||||
public:
|
||||
Result() { /* ... */ }
|
||||
|
||||
/* TODO: It sure would be nice to make this private. */
|
||||
constexpr Result(typename Base::BaseType v) : value(v) { static_assert(std::is_same<typename Base::BaseType, ::Result>::value); }
|
||||
|
||||
constexpr inline operator ResultSuccess() const;
|
||||
NX_CONSTEXPR bool CanAccept(Result result) { return true; }
|
||||
|
||||
constexpr inline bool IsSuccess() const { return this->GetValue() == Base::SuccessValue; }
|
||||
constexpr inline bool IsFailure() const { return !this->IsSuccess(); }
|
||||
constexpr inline typename Base::BaseType GetModule() const { return Base::GetModule(); }
|
||||
constexpr inline typename Base::BaseType GetDescription() const { return Base::GetDescription(); }
|
||||
|
||||
constexpr inline typename Base::BaseType GetValue() const { return this->value; }
|
||||
};
|
||||
static_assert(sizeof(Result) == sizeof(Result::Base::BaseType), "sizeof(Result) == sizeof(Result::Base::BaseType)");
|
||||
static_assert(std::is_trivially_destructible<Result>::value, "std::is_trivially_destructible<Result>::value");
|
||||
|
||||
namespace result::impl {
|
||||
|
||||
class ResultConstructor {
|
||||
public:
|
||||
static constexpr inline Result MakeResult(ResultTraits::BaseType value) {
|
||||
return Result(value);
|
||||
}
|
||||
};
|
||||
|
||||
constexpr inline Result MakeResult(ResultTraits::BaseType value) {
|
||||
return ResultConstructor::MakeResult(value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class ResultSuccess final : public result::impl::ResultBase<ResultSuccess> {
|
||||
public:
|
||||
using Base = typename result::impl::ResultBase<ResultSuccess>;
|
||||
public:
|
||||
constexpr operator Result() const { return result::impl::MakeResult(Base::SuccessValue); }
|
||||
NX_CONSTEXPR bool CanAccept(Result result) { return result.IsSuccess(); }
|
||||
|
||||
constexpr inline bool IsSuccess() const { return true; }
|
||||
constexpr inline bool IsFailure() const { return !this->IsSuccess(); }
|
||||
constexpr inline typename Base::BaseType GetModule() const { return Base::GetModule(); }
|
||||
constexpr inline typename Base::BaseType GetDescription() const { return Base::GetDescription(); }
|
||||
|
||||
constexpr inline typename Base::BaseType GetValue() const { return Base::SuccessValue; }
|
||||
};
|
||||
|
||||
namespace result::impl {
|
||||
|
||||
NORETURN void OnResultAssertion(Result result);
|
||||
|
||||
}
|
||||
|
||||
constexpr inline Result::operator ResultSuccess() const {
|
||||
if (!ResultSuccess::CanAccept(*this)) {
|
||||
result::impl::OnResultAssertion(*this);
|
||||
}
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
namespace result::impl {
|
||||
|
||||
template<ResultTraits::BaseType _Module, ResultTraits::BaseType _Description>
|
||||
class ResultErrorBase : public ResultBase<ResultErrorBase<_Module, _Description>> {
|
||||
public:
|
||||
using Base = typename result::impl::ResultBase<ResultErrorBase<_Module, _Description>>;
|
||||
static constexpr typename Base::BaseType Module = _Module;
|
||||
static constexpr typename Base::BaseType Description = _Description;
|
||||
static constexpr typename Base::BaseType Value = ResultTraits::MakeStaticValue<Module, Description>::value;
|
||||
static_assert(Value != Base::SuccessValue, "Value != Base::SuccessValue");
|
||||
public:
|
||||
constexpr operator Result() const { return MakeResult(Value); }
|
||||
constexpr operator ResultSuccess() const { OnResultAssertion(Value); }
|
||||
|
||||
constexpr inline bool IsSuccess() const { return false; }
|
||||
constexpr inline bool IsFailure() const { return !this->IsSuccess(); }
|
||||
|
||||
constexpr inline typename Base::BaseType GetValue() const { return Value; }
|
||||
};
|
||||
|
||||
template<ResultTraits::BaseType _Module, ResultTraits::BaseType DescStart, ResultTraits::BaseType DescEnd>
|
||||
class ResultErrorRangeBase {
|
||||
public:
|
||||
static constexpr ResultTraits::BaseType Module = _Module;
|
||||
static constexpr ResultTraits::BaseType DescriptionStart = DescStart;
|
||||
static constexpr ResultTraits::BaseType DescriptionEnd = DescEnd;
|
||||
static_assert(DescriptionStart <= DescriptionEnd, "DescriptionStart <= DescriptionEnd");
|
||||
static constexpr typename ResultTraits::BaseType StartValue = ResultTraits::MakeStaticValue<Module, DescriptionStart>::value;
|
||||
static constexpr typename ResultTraits::BaseType EndValue = ResultTraits::MakeStaticValue<Module, DescriptionEnd>::value;
|
||||
public:
|
||||
NX_CONSTEXPR bool Includes(Result result) {
|
||||
return StartValue <= result.GetValue() && result.GetValue() <= EndValue;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Macros for defining new results. */
|
||||
#define R_DEFINE_NAMESPACE_RESULT_MODULE(value) namespace impl::result { static constexpr inline ::ams::result::impl::ResultTraits::BaseType ResultModuleId = value; }
|
||||
#define R_CURRENT_NAMESPACE_RESULT_MODULE impl::result::ResultModuleId
|
||||
#define R_NAMESPACE_MODULE_ID(nmspc) nmspc::R_CURRENT_NAMESPACE_RESULT_MODULE
|
||||
|
||||
#define R_MAKE_NAMESPACE_RESULT(nmspc, desc) static_cast<::ams::Result>(::ams::result::impl::ResultTraits::MakeValue(R_NAMESPACE_MODULE_ID(nmspc), desc))
|
||||
|
||||
#define R_DEFINE_ERROR_RESULT_IMPL(name, desc_start, desc_end) \
|
||||
class Result##name final : public ::ams::result::impl::ResultErrorBase<R_CURRENT_NAMESPACE_RESULT_MODULE, desc_start>, public ::ams::result::impl::ResultErrorRangeBase<R_CURRENT_NAMESPACE_RESULT_MODULE, desc_start, desc_end> {}
|
||||
|
||||
#define R_DEFINE_ABSTRACT_ERROR_RESULT_IMPL(name, desc_start, desc_end) \
|
||||
class Result##name final : public ::ams::result::impl::ResultErrorRangeBase<R_CURRENT_NAMESPACE_RESULT_MODULE, desc_start, desc_end> {}
|
||||
|
||||
|
||||
#define R_DEFINE_ERROR_RESULT(name, desc) R_DEFINE_ERROR_RESULT_IMPL(name, desc, desc)
|
||||
#define R_DEFINE_ERROR_RANGE(name, start, end) R_DEFINE_ERROR_RESULT_IMPL(name, start, end)
|
||||
|
||||
#define R_DEFINE_ABSTRACT_ERROR_RESULT(name, desc) R_DEFINE_ABSTRACT_ERROR_RESULT_IMPL(name, desc, desc)
|
||||
#define R_DEFINE_ABSTRACT_ERROR_RANGE(name, start, end) R_DEFINE_ABSTRACT_ERROR_RESULT_IMPL(name, start, end)
|
||||
|
||||
/* Remove libnx macros, replace with our own. */
|
||||
#ifndef R_SUCCEEDED
|
||||
#error "R_SUCCEEDED not defined."
|
||||
#endif
|
||||
|
||||
#undef R_SUCCEEDED
|
||||
|
||||
#ifndef R_FAILED
|
||||
#error "R_FAILED not defined"
|
||||
#endif
|
||||
|
||||
#undef R_FAILED
|
||||
|
||||
#define R_SUCCEEDED(res) (static_cast<::ams::Result>(res).IsSuccess())
|
||||
#define R_FAILED(res) (static_cast<::ams::Result>(res).IsFailure())
|
||||
|
||||
|
||||
/// Evaluates an expression that returns a result, and returns the result if it would fail.
|
||||
#define R_TRY(res_expr) \
|
||||
({ \
|
||||
const auto _tmp_r_try_rc = res_expr; \
|
||||
if (R_FAILED(_tmp_r_try_rc)) { \
|
||||
return _tmp_r_try_rc; \
|
||||
} \
|
||||
})
|
||||
|
||||
/// Evaluates an expression that returns a result, and fatals the result if it would fail.
|
||||
#define R_ASSERT(res_expr) \
|
||||
({ \
|
||||
const auto _tmp_r_assert_rc = res_expr; \
|
||||
if (R_FAILED(_tmp_r_assert_rc)) { \
|
||||
::ams::result::impl::OnResultAssertion(_tmp_r_assert_rc); \
|
||||
} \
|
||||
})
|
||||
|
||||
/// Evaluates a boolean expression, and returns a result unless that expression is true.
|
||||
#define R_UNLESS(expr, res) \
|
||||
({ \
|
||||
if (!(expr)) { \
|
||||
return static_cast<::ams::Result>(res); \
|
||||
} \
|
||||
})
|
||||
|
||||
/// Helpers for pattern-matching on a result expression, if the result would fail.
|
||||
#define R_CURRENT_RESULT _tmp_r_current_result
|
||||
|
||||
#define R_TRY_CATCH(res_expr) \
|
||||
({ \
|
||||
const auto R_CURRENT_RESULT = res_expr; \
|
||||
if (R_FAILED(R_CURRENT_RESULT)) { \
|
||||
if (false)
|
||||
|
||||
namespace ams::result::impl {
|
||||
|
||||
template<typename... Rs>
|
||||
NX_CONSTEXPR bool AnyIncludes(Result result) {
|
||||
return (Rs::Includes(result) || ...);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#define R_CATCH(...) \
|
||||
} else if (::ams::result::impl::AnyIncludes<__VA_ARGS__>(R_CURRENT_RESULT)) { \
|
||||
if (true)
|
||||
|
||||
#define R_CONVERT(catch_type, convert_type) \
|
||||
R_CATCH(catch_type) { return static_cast<::ams::Result>(convert_type); }
|
||||
|
||||
#define R_CATCH_ALL() \
|
||||
} else if (R_FAILED(R_CURRENT_RESULT)) { \
|
||||
if (true)
|
||||
|
||||
#define R_CONVERT_ALL(convert_type) \
|
||||
R_CATCH_ALL() { return static_cast<::ams::Result>(convert_type); }
|
||||
|
||||
#define R_END_TRY_CATCH \
|
||||
else if (R_FAILED(R_CURRENT_RESULT)) { \
|
||||
return R_CURRENT_RESULT; \
|
||||
} \
|
||||
} \
|
||||
})
|
||||
|
||||
#define R_END_TRY_CATCH_WITH_ASSERT \
|
||||
else { \
|
||||
R_ASSERT(R_CURRENT_RESULT); \
|
||||
} \
|
||||
} \
|
||||
})
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 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 "results_common.hpp"
|
||||
|
||||
namespace ams::ro {
|
||||
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(22);
|
||||
|
||||
R_DEFINE_ERROR_RANGE(RoError, 1, 1023);
|
||||
R_DEFINE_ERROR_RESULT(OutOfAddressSpace, 2);
|
||||
R_DEFINE_ERROR_RESULT(AlreadyLoaded, 3);
|
||||
R_DEFINE_ERROR_RESULT(InvalidNro, 4);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(InvalidNrr, 6);
|
||||
R_DEFINE_ERROR_RESULT(TooManyNro, 7);
|
||||
R_DEFINE_ERROR_RESULT(TooManyNrr, 8);
|
||||
R_DEFINE_ERROR_RESULT(NotAuthorized, 9);
|
||||
R_DEFINE_ERROR_RESULT(InvalidNrrType, 10);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(InternalError, 1023);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(InvalidAddress, 1025);
|
||||
R_DEFINE_ERROR_RESULT(InvalidSize, 1026);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(NotLoaded, 1028);
|
||||
R_DEFINE_ERROR_RESULT(NotRegistered, 1029);
|
||||
R_DEFINE_ERROR_RESULT(InvalidSession, 1030);
|
||||
R_DEFINE_ERROR_RESULT(InvalidProcess, 1031);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 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 "results_common.hpp"
|
||||
|
||||
namespace ams::settings {
|
||||
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(105);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(ItemNotFound, 11);
|
||||
|
||||
R_DEFINE_ERROR_RANGE(InternalError, 100, 149);
|
||||
R_DEFINE_ERROR_RESULT(ItemKeyAllocationFailed, 101);
|
||||
R_DEFINE_ERROR_RESULT(ItemValueAllocationFailed, 102);
|
||||
|
||||
R_DEFINE_ERROR_RANGE(InvalidArgument, 200, 399);
|
||||
R_DEFINE_ERROR_RESULT(SettingsNameNull, 201);
|
||||
R_DEFINE_ERROR_RESULT(SettingsItemKeyNull, 202);
|
||||
R_DEFINE_ERROR_RESULT(SettingsItemValueNull, 203);
|
||||
R_DEFINE_ERROR_RESULT(SettingsItemKeyBufferNull, 204);
|
||||
R_DEFINE_ERROR_RESULT(SettingsItemValueBufferNull, 205);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(SettingsNameEmpty, 221);
|
||||
R_DEFINE_ERROR_RESULT(SettingsItemKeyEmpty, 222);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(SettingsNameTooLong, 241);
|
||||
R_DEFINE_ERROR_RESULT(SettingsItemKeyTooLong, 242);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(SettingsNameInvalidFormat, 261);
|
||||
R_DEFINE_ERROR_RESULT(SettingsItemKeyInvalidFormat, 262);
|
||||
R_DEFINE_ERROR_RESULT(SettingsItemValueInvalidFormat, 263);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 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 "results_common.hpp"
|
||||
|
||||
namespace ams::sf {
|
||||
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(10);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(NotSupported, 1);
|
||||
R_DEFINE_ERROR_RESULT(PreconditionViolation, 3);
|
||||
|
||||
namespace cmif {
|
||||
|
||||
R_DEFINE_ERROR_RESULT(InvalidHeaderSize, 202);
|
||||
R_DEFINE_ERROR_RESULT(InvalidInHeader, 211);
|
||||
R_DEFINE_ERROR_RESULT(UnknownCommandId, 221);
|
||||
R_DEFINE_ERROR_RESULT(InvalidOutRawSize, 232);
|
||||
R_DEFINE_ERROR_RESULT(InvalidNumInObjects, 235);
|
||||
R_DEFINE_ERROR_RESULT(InvalidNumOutObjects, 236);
|
||||
R_DEFINE_ERROR_RESULT(InvalidInObject, 239);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(TargetNotFound, 261);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(OutOfDomainEntries, 301);
|
||||
|
||||
}
|
||||
|
||||
namespace impl {
|
||||
|
||||
R_DEFINE_ABSTRACT_ERROR_RANGE(RequestContextChanged, 800, 899);
|
||||
R_DEFINE_ABSTRACT_ERROR_RANGE(RequestInvalidated, 801, 809);
|
||||
R_DEFINE_ERROR_RESULT(RequestInvalidatedByUser, 802);
|
||||
|
||||
}
|
||||
|
||||
R_DEFINE_ABSTRACT_ERROR_RANGE(RequestDeferred, 811, 819);
|
||||
R_DEFINE_ERROR_RESULT(RequestDeferredByUser, 812);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 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 "results_common.hpp"
|
||||
|
||||
namespace ams::sm {
|
||||
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(21);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(OutOfProcesses, 1);
|
||||
R_DEFINE_ERROR_RESULT(InvalidClient, 2);
|
||||
R_DEFINE_ERROR_RESULT(OutOfSessions, 3);
|
||||
R_DEFINE_ERROR_RESULT(AlreadyRegistered, 4);
|
||||
R_DEFINE_ERROR_RESULT(OutOfServices, 5);
|
||||
R_DEFINE_ERROR_RESULT(InvalidServiceName, 6);
|
||||
R_DEFINE_ERROR_RESULT(NotRegistered, 7);
|
||||
R_DEFINE_ERROR_RESULT(NotAllowed, 8);
|
||||
R_DEFINE_ERROR_RESULT(TooLargeAccessControl, 9);
|
||||
|
||||
/* Results 1000-2000 used as extension for Atmosphere Mitm. */
|
||||
namespace mitm {
|
||||
|
||||
R_DEFINE_ERROR_RESULT(ShouldForwardToSession, 1000);
|
||||
R_DEFINE_ERROR_RESULT(ProcessNotAssociated, 1100);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 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 "results_common.hpp"
|
||||
|
||||
namespace ams::spl {
|
||||
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(26);
|
||||
|
||||
R_DEFINE_ERROR_RANGE(SecureMonitorError, 0, 99);
|
||||
R_DEFINE_ERROR_RESULT(SecureMonitorNotImplemented, 1);
|
||||
R_DEFINE_ERROR_RESULT(SecureMonitorInvalidArgument, 2);
|
||||
R_DEFINE_ERROR_RESULT(SecureMonitorBusy, 3);
|
||||
R_DEFINE_ERROR_RESULT(SecureMonitorNoAsyncOperation, 4);
|
||||
R_DEFINE_ERROR_RESULT(SecureMonitorInvalidAsyncOperation, 5);
|
||||
R_DEFINE_ERROR_RESULT(SecureMonitorNotPermitted, 6);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(InvalidSize, 100);
|
||||
R_DEFINE_ERROR_RESULT(UnknownSecureMonitorError, 101);
|
||||
R_DEFINE_ERROR_RESULT(DecryptionFailed, 102);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(OutOfKeyslots, 104);
|
||||
R_DEFINE_ERROR_RESULT(InvalidKeyslot, 105);
|
||||
R_DEFINE_ERROR_RESULT(BootReasonAlreadySet, 106);
|
||||
R_DEFINE_ERROR_RESULT(BootReasonNotSet, 107);
|
||||
R_DEFINE_ERROR_RESULT(InvalidArgument, 108);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 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 "results_common.hpp"
|
||||
|
||||
namespace ams::svc {
|
||||
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(1);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(OutOfSessions, 7);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(InvalidArgument, 14);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(NotImplemented, 33);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(ThreadTerminating, 59);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(NoEvent, 70);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(InvalidSize, 101);
|
||||
R_DEFINE_ERROR_RESULT(InvalidAddress, 102);
|
||||
R_DEFINE_ERROR_RESULT(OutOfResource, 103);
|
||||
R_DEFINE_ERROR_RESULT(OutOfMemory, 104);
|
||||
R_DEFINE_ERROR_RESULT(OutOfHandles, 105);
|
||||
R_DEFINE_ERROR_RESULT(InvalidCurrentMemoryState, 106);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(InvalidNewMemoryPermissions, 108);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(InvalidMemoryRegion, 110);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(InvalidPriority, 112);
|
||||
R_DEFINE_ERROR_RESULT(InvalidCoreId, 113);
|
||||
R_DEFINE_ERROR_RESULT(InvalidHandle, 114);
|
||||
R_DEFINE_ERROR_RESULT(InvalidPointer, 115);
|
||||
R_DEFINE_ERROR_RESULT(InvalidCombination, 116);
|
||||
R_DEFINE_ERROR_RESULT(TimedOut, 117);
|
||||
R_DEFINE_ERROR_RESULT(Cancelled, 118);
|
||||
R_DEFINE_ERROR_RESULT(OutOfRange, 119);
|
||||
R_DEFINE_ERROR_RESULT(InvalidEnumValue, 120);
|
||||
R_DEFINE_ERROR_RESULT(NotFound, 121);
|
||||
R_DEFINE_ERROR_RESULT(Busy, 122);
|
||||
R_DEFINE_ERROR_RESULT(SessionClosed, 123);
|
||||
R_DEFINE_ERROR_RESULT(NotHandled, 124);
|
||||
R_DEFINE_ERROR_RESULT(InvalidState, 125);
|
||||
R_DEFINE_ERROR_RESULT(ReservedValue, 126);
|
||||
R_DEFINE_ERROR_RESULT(NotSupported, 127);
|
||||
R_DEFINE_ERROR_RESULT(Debug, 128);
|
||||
R_DEFINE_ERROR_RESULT(ThreadNotOwned, 129);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(PortClosed, 131);
|
||||
R_DEFINE_ERROR_RESULT(LimitReached, 132);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(ReceiveListBroken, 258);
|
||||
R_DEFINE_ERROR_RESULT(OutOfAddressSpace, 259);
|
||||
R_DEFINE_ERROR_RESULT(MessageTooLarge, 260);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(ProcessTerminated, 520);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 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 "results_common.hpp"
|
||||
|
||||
namespace ams::updater {
|
||||
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(158);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(BootImagePackageNotFound, 2);
|
||||
R_DEFINE_ERROR_RESULT(InvalidBootImagePackage, 3);
|
||||
R_DEFINE_ERROR_RESULT(TooSmallWorkBuffer, 4);
|
||||
R_DEFINE_ERROR_RESULT(NotAlignedWorkBuffer, 5);
|
||||
R_DEFINE_ERROR_RESULT(NeedsRepairBootImages, 6);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 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 "results_common.hpp"
|
||||
|
||||
namespace ams::vi {
|
||||
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(114);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(OperationFailed, 1);
|
||||
R_DEFINE_ERROR_RESULT(NotSupported, 6);
|
||||
R_DEFINE_ERROR_RESULT(NotFound, 7);
|
||||
|
||||
}
|
||||
21
stratosphere/libstratosphere/include/atmosphere/svc.hpp
Normal file
21
stratosphere/libstratosphere/include/atmosphere/svc.hpp
Normal file
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 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 "defines.hpp"
|
||||
#include "results.hpp"
|
||||
|
||||
#include "svc/svc_types.hpp"
|
||||
@@ -0,0 +1,208 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 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 "../results.hpp"
|
||||
|
||||
namespace ams::svc {
|
||||
|
||||
/* Debug event types. */
|
||||
enum class DebugEventType : u32 {
|
||||
AttachProcess = 0,
|
||||
AttachThread = 1,
|
||||
ExitProcess = 2,
|
||||
ExitThread = 3,
|
||||
Exception = 4,
|
||||
};
|
||||
|
||||
struct DebugInfoAttachProcess {
|
||||
u64 title_id;
|
||||
u64 process_id;
|
||||
char name[0xC];
|
||||
u32 flags;
|
||||
u64 user_exception_context_address; /* 5.0.0+ */
|
||||
};
|
||||
|
||||
struct DebugInfoAttachThread {
|
||||
u64 thread_id;
|
||||
u64 tls_address;
|
||||
u64 entrypoint;
|
||||
};
|
||||
|
||||
enum class ExitProcessReason : u32 {
|
||||
ExitProcess = 0,
|
||||
TerminateProcess = 1,
|
||||
Exception = 2,
|
||||
};
|
||||
|
||||
struct DebugInfoExitProcess {
|
||||
ExitProcessReason reason;
|
||||
};
|
||||
|
||||
enum class ExitThreadReason : u32 {
|
||||
ExitThread = 0,
|
||||
TerminateThread = 1,
|
||||
ExitProcess = 2,
|
||||
TerminateProcess = 3,
|
||||
};
|
||||
|
||||
struct DebugInfoExitThread {
|
||||
ExitThreadReason reason;
|
||||
};
|
||||
|
||||
enum class DebugExceptionType : u32 {
|
||||
UndefinedInstruction = 0,
|
||||
InstructionAbort = 1,
|
||||
DataAbort = 2,
|
||||
AlignmentFault = 3,
|
||||
DebuggerAttached = 4,
|
||||
BreakPoint = 5,
|
||||
UserBreak = 6,
|
||||
DebuggerBreak = 7,
|
||||
UndefinedSystemCall = 8,
|
||||
SystemMemoryError = 9,
|
||||
};
|
||||
|
||||
struct DebugInfoUndefinedInstructionException {
|
||||
u32 insn;
|
||||
};
|
||||
|
||||
struct DebugInfoDataAbortException {
|
||||
u64 address;
|
||||
};
|
||||
|
||||
struct DebugInfoAligntmentFaultException {
|
||||
u64 address;
|
||||
};
|
||||
|
||||
enum class BreakPointType : u32 {
|
||||
BreakPoint = 0,
|
||||
WatchPoint = 1,
|
||||
};
|
||||
|
||||
struct DebugInfoBreakPointException {
|
||||
BreakPointType type;
|
||||
u64 address;
|
||||
};
|
||||
|
||||
struct DebugInfoUserBreakException {
|
||||
u32 break_reason; /* TODO: enum? */
|
||||
u64 address;
|
||||
u64 size;
|
||||
};
|
||||
|
||||
struct DebugInfoDebuggerBreakException {
|
||||
u64 active_thread_ids[4];
|
||||
};
|
||||
|
||||
struct DebugInfoUndefinedSystemCallException {
|
||||
u32 id;
|
||||
};
|
||||
|
||||
union DebugInfoSpecificException {
|
||||
DebugInfoUndefinedInstructionException undefined_instruction;
|
||||
DebugInfoDataAbortException data_abort;
|
||||
DebugInfoAligntmentFaultException alignment_fault;
|
||||
DebugInfoBreakPointException break_point;
|
||||
DebugInfoUserBreakException user_break;
|
||||
DebugInfoDebuggerBreakException debugger_break;
|
||||
DebugInfoUndefinedSystemCallException undefined_system_call;
|
||||
u64 raw;
|
||||
};
|
||||
|
||||
struct DebugInfoException {
|
||||
DebugExceptionType type;
|
||||
u64 address;
|
||||
DebugInfoSpecificException specific;
|
||||
};
|
||||
|
||||
union DebugInfo {
|
||||
DebugInfoAttachProcess attach_process;
|
||||
DebugInfoAttachThread attach_thread;
|
||||
DebugInfoExitProcess exit_process;
|
||||
DebugInfoExitThread exit_thread;
|
||||
DebugInfoException exception;
|
||||
};
|
||||
|
||||
struct DebugEventInfo {
|
||||
DebugEventType type;
|
||||
u32 flags;
|
||||
u64 thread_id;
|
||||
DebugInfo info;
|
||||
};
|
||||
static_assert(sizeof(DebugEventInfo) >= 0x40, "DebugEventInfo definition!");
|
||||
|
||||
/* Thread State, for svcGetDebugThreadParam. */
|
||||
enum class ThreadState : u32 {
|
||||
Waiting = 0,
|
||||
Running = 1,
|
||||
Terminated = 4,
|
||||
Initializing = 5,
|
||||
};
|
||||
|
||||
enum ThreadContextFlag : u32 {
|
||||
ThreadContextFlag_General = (1 << 0),
|
||||
ThreadContextFlag_Control = (1 << 1),
|
||||
ThreadContextFlag_Fpu = (1 << 2),
|
||||
ThreadContextFlag_FpuControl = (1 << 3),
|
||||
|
||||
ThreadContextFlag_All = (ThreadContextFlag_General | ThreadContextFlag_Control | ThreadContextFlag_Fpu | ThreadContextFlag_FpuControl),
|
||||
};
|
||||
|
||||
/* Flags for svcCreateProcess. */
|
||||
enum CreateProcessFlag : u32 {
|
||||
/* Is 64 bit? */
|
||||
CreateProcessFlag_Is64Bit = (1 << 0),
|
||||
|
||||
/* What kind of address space? */
|
||||
CreateProcessFlag_AddressSpaceShift = 1,
|
||||
CreateProcessFlag_AddressSpaceMask = (7 << CreateProcessFlag_AddressSpaceShift),
|
||||
CreateProcessFlag_AddressSpace32Bit = (0 << CreateProcessFlag_AddressSpaceShift),
|
||||
CreateProcessFlag_AddressSpace64BitDeprecated = (1 << CreateProcessFlag_AddressSpaceShift),
|
||||
CreateProcessFlag_AddressSpace32BitWithoutAlias = (2 << CreateProcessFlag_AddressSpaceShift),
|
||||
CreateProcessFlag_AddressSpace64Bit = (3 << CreateProcessFlag_AddressSpaceShift),
|
||||
|
||||
/* Should JIT debug be done on crash? */
|
||||
CreateProcessFlag_EnableDebug = (1 << 4),
|
||||
|
||||
/* Should ASLR be enabled for the process? */
|
||||
CreateProcessFlag_EnableAslr = (1 << 5),
|
||||
|
||||
/* Is the process an application? */
|
||||
CreateProcessFlag_IsApplication = (1 << 6),
|
||||
|
||||
/* 4.x deprecated: Should use secure memory? */
|
||||
CreateProcessFlag_DeprecatedUseSecureMemory = (1 << 7),
|
||||
|
||||
/* 5.x+ Pool partition type. */
|
||||
CreateProcessFlag_PoolPartitionShift = 7,
|
||||
CreateProcessFlag_PoolPartitionMask = (0xF << CreateProcessFlag_PoolPartitionShift),
|
||||
CreateProcessFlag_PoolPartitionApplication = (0 << CreateProcessFlag_PoolPartitionShift),
|
||||
CreateProcessFlag_PoolPartitionApplet = (1 << CreateProcessFlag_PoolPartitionShift),
|
||||
CreateProcessFlag_PoolPartitionSystem = (2 << CreateProcessFlag_PoolPartitionShift),
|
||||
CreateProcessFlag_PoolPartitionSystemNonSecure = (3 << CreateProcessFlag_PoolPartitionShift),
|
||||
|
||||
/* 7.x+ Should memory allocation be optimized? This requires IsApplication. */
|
||||
CreateProcessFlag_OptimizeMemoryAllocation = (1 << 11),
|
||||
};
|
||||
|
||||
/* Type for svcCreateInterruptEvent. */
|
||||
enum InterruptType : u32 {
|
||||
InterruptType_Edge = 0,
|
||||
InterruptType_Level = 1,
|
||||
};
|
||||
|
||||
}
|
||||
27
stratosphere/libstratosphere/include/atmosphere/util.hpp
Normal file
27
stratosphere/libstratosphere/include/atmosphere/util.hpp
Normal file
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 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 "defines.hpp"
|
||||
|
||||
#include "util/util_alignment.hpp"
|
||||
#include "util/util_size.hpp"
|
||||
#include "util/util_scope_guard.hpp"
|
||||
#include "util/util_typed_storage.hpp"
|
||||
#include "util/util_intrusive_list.hpp"
|
||||
#include "util/util_intrusive_red_black_tree.hpp"
|
||||
#include "util/util_compression.hpp"
|
||||
#include "util/util_ini.hpp"
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 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 "../defines.hpp"
|
||||
|
||||
namespace ams::util {
|
||||
|
||||
/* Utilities for alignment to power of two. */
|
||||
|
||||
template<typename T>
|
||||
constexpr inline T AlignUp(T value, size_t alignment) {
|
||||
using U = typename std::make_unsigned<T>::type;
|
||||
const U invmask = static_cast<U>(alignment - 1);
|
||||
return static_cast<T>((value + invmask) & ~invmask);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr inline T AlignDown(T value, size_t alignment) {
|
||||
using U = typename std::make_unsigned<T>::type;
|
||||
const U invmask = static_cast<U>(alignment - 1);
|
||||
return static_cast<T>(value & ~invmask);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr inline bool IsAligned(T value, size_t alignment) {
|
||||
using U = typename std::make_unsigned<T>::type;
|
||||
const U invmask = static_cast<U>(alignment - 1);
|
||||
return (value & invmask) == 0;
|
||||
}
|
||||
|
||||
template<>
|
||||
constexpr inline void *AlignUp<void *>(void *value, size_t alignment) {
|
||||
return reinterpret_cast<void *>(AlignUp(reinterpret_cast<uintptr_t>(value), alignment));
|
||||
}
|
||||
|
||||
template<>
|
||||
constexpr inline const void *AlignUp<const void *>(const void *value, size_t alignment) {
|
||||
return reinterpret_cast<const void *>(AlignUp(reinterpret_cast<uintptr_t>(value), alignment));
|
||||
}
|
||||
|
||||
template<>
|
||||
constexpr inline void *AlignDown<void *>(void *value, size_t alignment) {
|
||||
return reinterpret_cast<void *>(AlignDown(reinterpret_cast<uintptr_t>(value), alignment));
|
||||
}
|
||||
|
||||
template<>
|
||||
constexpr inline const void *AlignDown<const void *>(const void *value, size_t alignment) {
|
||||
return reinterpret_cast<void *>(AlignDown(reinterpret_cast<uintptr_t>(value), alignment));
|
||||
}
|
||||
|
||||
template<>
|
||||
constexpr inline bool IsAligned<void *>(void *value, size_t alignment) {
|
||||
return IsAligned(reinterpret_cast<uintptr_t>(value), alignment);
|
||||
}
|
||||
|
||||
template<>
|
||||
constexpr inline bool IsAligned<const void *>(const void *value, size_t alignment) {
|
||||
return IsAligned(reinterpret_cast<uintptr_t>(value), alignment);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 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 "../defines.hpp"
|
||||
|
||||
namespace ams::util {
|
||||
|
||||
/* Compression utilities. */
|
||||
int CompressLZ4(void *dst, size_t dst_size, const void *src, size_t src_size);
|
||||
|
||||
/* Decompression utilities. */
|
||||
int DecompressLZ4(void *dst, size_t dst_size, const void *src, size_t src_size);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 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 "../defines.hpp"
|
||||
|
||||
namespace ams::util::ini {
|
||||
|
||||
/* Ini handler type. */
|
||||
using Handler = int (*)(void *user_ctx, const char *section, const char *name, const char *value);
|
||||
|
||||
/* Utilities for dealing with INI file configuration. */
|
||||
int ParseString(const char *ini_str, void *user_ctx, Handler h);
|
||||
int ParseFile(FILE *f, void *user_ctx, Handler h);
|
||||
int ParseFile(FsFile *f, void *user_ctx, Handler h);
|
||||
int ParseFile(const char *path, void *user_ctx, Handler h);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,595 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 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 "util_parent_of_member.hpp"
|
||||
|
||||
namespace ams::util {
|
||||
|
||||
/* Forward declare implementation class for Node. */
|
||||
namespace impl {
|
||||
|
||||
class IntrusiveListImpl;
|
||||
|
||||
}
|
||||
|
||||
class IntrusiveListNode {
|
||||
NON_COPYABLE(IntrusiveListNode);
|
||||
private:
|
||||
friend class impl::IntrusiveListImpl;
|
||||
|
||||
IntrusiveListNode *prev;
|
||||
IntrusiveListNode *next;
|
||||
public:
|
||||
IntrusiveListNode() {
|
||||
this->prev = this;
|
||||
this->next = this;
|
||||
}
|
||||
|
||||
bool IsLinked() const {
|
||||
return this->next != this;
|
||||
}
|
||||
private:
|
||||
void LinkPrev(IntrusiveListNode *node) {
|
||||
/* We can't link an already linked node. */
|
||||
AMS_ASSERT(!node->IsLinked());
|
||||
this->SplicePrev(node, node);
|
||||
}
|
||||
|
||||
void SplicePrev(IntrusiveListNode *first, IntrusiveListNode *last) {
|
||||
/* Splice a range into the list. */
|
||||
auto last_prev = last->prev;
|
||||
first->prev = this->prev;
|
||||
this->prev->next = first;
|
||||
last_prev->next = this;
|
||||
this->prev = last_prev;
|
||||
}
|
||||
|
||||
void LinkNext(IntrusiveListNode *node) {
|
||||
/* We can't link an already linked node. */
|
||||
AMS_ASSERT(!node->IsLinked());
|
||||
return this->SpliceNext(node, node);
|
||||
}
|
||||
|
||||
void SpliceNext(IntrusiveListNode *first, IntrusiveListNode *last) {
|
||||
/* Splice a range into the list. */
|
||||
auto last_prev = last->prev;
|
||||
first->prev = this;
|
||||
this->next = first;
|
||||
last_prev->next = next;
|
||||
this->next->prev = last_prev;
|
||||
}
|
||||
|
||||
void Unlink() {
|
||||
this->Unlink(this->next);
|
||||
}
|
||||
|
||||
void Unlink(IntrusiveListNode *last) {
|
||||
/* Unlink a node from a next node. */
|
||||
auto last_prev = last->prev;
|
||||
this->prev->next = last;
|
||||
last->prev = this->prev;
|
||||
last_prev->next = this;
|
||||
this->prev = last_prev;
|
||||
}
|
||||
|
||||
IntrusiveListNode *GetPrev() {
|
||||
return this->prev;
|
||||
}
|
||||
|
||||
const IntrusiveListNode *GetPrev() const {
|
||||
return this->prev;
|
||||
}
|
||||
|
||||
IntrusiveListNode *GetNext() {
|
||||
return this->next;
|
||||
}
|
||||
|
||||
const IntrusiveListNode *GetNext() const {
|
||||
return this->next;
|
||||
}
|
||||
};
|
||||
|
||||
namespace impl {
|
||||
|
||||
class IntrusiveListImpl {
|
||||
NON_COPYABLE(IntrusiveListImpl);
|
||||
private:
|
||||
IntrusiveListNode root_node;
|
||||
public:
|
||||
template<bool Const>
|
||||
class Iterator;
|
||||
|
||||
using value_type = IntrusiveListNode;
|
||||
using size_type = size_t;
|
||||
using difference_type = ptrdiff_t;
|
||||
using pointer = value_type *;
|
||||
using const_pointer = const value_type *;
|
||||
using reference = value_type &;
|
||||
using const_reference = const value_type &;
|
||||
using iterator = Iterator<false>;
|
||||
using const_iterator = Iterator<true>;
|
||||
using reverse_iterator = std::reverse_iterator<iterator>;
|
||||
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
|
||||
|
||||
template<bool Const>
|
||||
class Iterator {
|
||||
public:
|
||||
using iterator_category = std::bidirectional_iterator_tag;
|
||||
using value_type = typename IntrusiveListImpl::value_type;
|
||||
using difference_type = typename IntrusiveListImpl::difference_type;
|
||||
using pointer = typename std::conditional<Const, IntrusiveListImpl::const_pointer, IntrusiveListImpl::pointer>::type;
|
||||
using reference = typename std::conditional<Const, IntrusiveListImpl::const_reference, IntrusiveListImpl::reference>::type;
|
||||
private:
|
||||
pointer node;
|
||||
public:
|
||||
explicit Iterator(pointer n) : node(n) { /* ... */ }
|
||||
|
||||
bool operator==(const Iterator &rhs) const {
|
||||
return this->node == rhs.node;
|
||||
}
|
||||
|
||||
bool operator!=(const Iterator &rhs) const {
|
||||
return !(*this == rhs);
|
||||
}
|
||||
|
||||
pointer operator->() const {
|
||||
return this->node;
|
||||
}
|
||||
|
||||
reference operator*() const {
|
||||
return *this->node;
|
||||
}
|
||||
|
||||
Iterator &operator++() {
|
||||
this->node = this->node->next;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Iterator &operator--() {
|
||||
this->node = this->node->prev;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Iterator operator++(int) {
|
||||
const Iterator it{*this};
|
||||
++(*this);
|
||||
return it;
|
||||
}
|
||||
|
||||
Iterator operator--(int) {
|
||||
const Iterator it{*this};
|
||||
--(*this);
|
||||
return it;
|
||||
}
|
||||
|
||||
operator Iterator<true>() const {
|
||||
return Iterator<true>(this->node);
|
||||
}
|
||||
|
||||
Iterator<false> GetNonConstIterator() const {
|
||||
return Iterator<false>(const_cast<IntrusiveListImpl::pointer>(this->node));
|
||||
}
|
||||
};
|
||||
public:
|
||||
IntrusiveListImpl() : root_node() { /* ... */ }
|
||||
|
||||
/* Iterator accessors. */
|
||||
iterator begin() {
|
||||
return iterator(this->root_node.GetNext());
|
||||
}
|
||||
|
||||
const_iterator begin() const {
|
||||
return const_iterator(this->root_node.GetNext());
|
||||
}
|
||||
|
||||
iterator end() {
|
||||
return iterator(&this->root_node);
|
||||
}
|
||||
|
||||
const_iterator end() const {
|
||||
return const_iterator(&this->root_node);
|
||||
}
|
||||
|
||||
iterator iterator_to(reference v) {
|
||||
/* Only allow iterator_to for values in lists. */
|
||||
AMS_ASSERT(v.IsLinked());
|
||||
return iterator(&v);
|
||||
}
|
||||
|
||||
const_iterator iterator_to(const_reference v) const {
|
||||
/* Only allow iterator_to for values in lists. */
|
||||
AMS_ASSERT(v.IsLinked());
|
||||
return const_iterator(&v);
|
||||
}
|
||||
|
||||
/* Content management. */
|
||||
bool empty() const {
|
||||
return !this->root_node.IsLinked();
|
||||
}
|
||||
|
||||
size_type size() const {
|
||||
return static_cast<size_type>(std::distance(this->begin(), this->end()));
|
||||
}
|
||||
|
||||
reference back() {
|
||||
return *this->root_node.GetPrev();
|
||||
}
|
||||
|
||||
const_reference back() const {
|
||||
return *this->root_node.GetPrev();
|
||||
}
|
||||
|
||||
reference front() {
|
||||
return *this->root_node.GetNext();
|
||||
}
|
||||
|
||||
const_reference front() const {
|
||||
return *this->root_node.GetNext();
|
||||
}
|
||||
|
||||
void push_back(reference node) {
|
||||
this->root_node.LinkPrev(&node);
|
||||
}
|
||||
|
||||
void push_front(reference node) {
|
||||
this->root_node.LinkNext(&node);
|
||||
}
|
||||
|
||||
void pop_back() {
|
||||
this->root_node.GetPrev()->Unlink();
|
||||
}
|
||||
|
||||
void pop_front() {
|
||||
this->root_node.GetNext()->Unlink();
|
||||
}
|
||||
|
||||
iterator insert(const_iterator pos, reference node) {
|
||||
pos.GetNonConstIterator()->LinkPrev(&node);
|
||||
return iterator(&node);
|
||||
}
|
||||
|
||||
void splice(const_iterator pos, IntrusiveListImpl &o) {
|
||||
splice_impl(pos, o.begin(), o.end());
|
||||
}
|
||||
|
||||
void splice(const_iterator pos, IntrusiveListImpl &o, const_iterator first) {
|
||||
const_iterator last(first);
|
||||
std::advance(last, 1);
|
||||
splice_impl(pos, first, last);
|
||||
}
|
||||
|
||||
void splice(const_iterator pos, IntrusiveListImpl &o, const_iterator first, const_iterator last) {
|
||||
splice_impl(pos, first, last);
|
||||
}
|
||||
|
||||
iterator erase(const iterator pos) {
|
||||
if (pos == this->end()) {
|
||||
return this->end();
|
||||
}
|
||||
iterator it(pos.GetNonConstIterator());
|
||||
(it++)->Unlink();
|
||||
return it;
|
||||
}
|
||||
|
||||
void clear() {
|
||||
while (!this->empty()) {
|
||||
this->pop_front();
|
||||
}
|
||||
}
|
||||
private:
|
||||
void splice_impl(const_iterator _pos, const_iterator _first, const_iterator _last) {
|
||||
if (_first == _last) {
|
||||
return;
|
||||
}
|
||||
iterator pos(_pos.GetNonConstIterator());
|
||||
iterator first(_first.GetNonConstIterator());
|
||||
iterator last(_last.GetNonConstIterator());
|
||||
first->Unlink(&*last);
|
||||
pos->SplicePrev(&*first, &*first);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
template<class T, class Traits>
|
||||
class IntrusiveList {
|
||||
NON_COPYABLE(IntrusiveList);
|
||||
private:
|
||||
impl::IntrusiveListImpl impl;
|
||||
public:
|
||||
template<bool Const>
|
||||
class Iterator;
|
||||
|
||||
using value_type = T;
|
||||
using size_type = size_t;
|
||||
using difference_type = ptrdiff_t;
|
||||
using pointer = value_type *;
|
||||
using const_pointer = const value_type *;
|
||||
using reference = value_type &;
|
||||
using const_reference = const value_type &;
|
||||
using iterator = Iterator<false>;
|
||||
using const_iterator = Iterator<true>;
|
||||
using reverse_iterator = std::reverse_iterator<iterator>;
|
||||
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
|
||||
|
||||
template<bool Const>
|
||||
class Iterator {
|
||||
public:
|
||||
friend class ams::util::IntrusiveList<T, Traits>;
|
||||
|
||||
using ImplIterator = typename std::conditional<Const, ams::util::impl::IntrusiveListImpl::const_iterator, ams::util::impl::IntrusiveListImpl::iterator>::type;
|
||||
|
||||
using iterator_category = std::bidirectional_iterator_tag;
|
||||
using value_type = typename IntrusiveList::value_type;
|
||||
using difference_type = typename IntrusiveList::difference_type;
|
||||
using pointer = typename std::conditional<Const, IntrusiveList::const_pointer, IntrusiveList::pointer>::type;
|
||||
using reference = typename std::conditional<Const, IntrusiveList::const_reference, IntrusiveList::reference>::type;
|
||||
private:
|
||||
ImplIterator iterator;
|
||||
private:
|
||||
explicit Iterator(ImplIterator it) : iterator(it) { /* ... */ }
|
||||
|
||||
ImplIterator GetImplIterator() const {
|
||||
return this->iterator;
|
||||
}
|
||||
public:
|
||||
bool operator==(const Iterator &rhs) const {
|
||||
return this->iterator == rhs.iterator;
|
||||
}
|
||||
|
||||
bool operator!=(const Iterator &rhs) const {
|
||||
return !(*this == rhs);
|
||||
}
|
||||
|
||||
pointer operator->() const {
|
||||
return &Traits::GetParent(*this->iterator);
|
||||
}
|
||||
|
||||
reference operator*() const {
|
||||
return Traits::GetParent(*this->iterator);
|
||||
}
|
||||
|
||||
Iterator &operator++() {
|
||||
++this->iterator;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Iterator &operator--() {
|
||||
--this->iterator;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Iterator operator++(int) {
|
||||
const Iterator it{*this};
|
||||
++this->iterator;
|
||||
return it;
|
||||
}
|
||||
|
||||
Iterator operator--(int) {
|
||||
const Iterator it{*this};
|
||||
--this->iterator;
|
||||
return it;
|
||||
}
|
||||
|
||||
operator Iterator<true>() const {
|
||||
return Iterator<true>(this->iterator);
|
||||
}
|
||||
};
|
||||
private:
|
||||
static constexpr IntrusiveListNode &GetNode(reference ref) {
|
||||
return Traits::GetNode(ref);
|
||||
}
|
||||
|
||||
static constexpr IntrusiveListNode const &GetNode(const_reference ref) {
|
||||
return Traits::GetNode(ref);
|
||||
}
|
||||
|
||||
static constexpr reference GetParent(IntrusiveListNode &node) {
|
||||
return Traits::GetParent(node);
|
||||
}
|
||||
|
||||
static constexpr const_reference GetParent(IntrusiveListNode const &node) {
|
||||
return Traits::GetParent(node);
|
||||
}
|
||||
public:
|
||||
IntrusiveList() : impl() { /* ... */ }
|
||||
|
||||
/* Iterator accessors. */
|
||||
iterator begin() {
|
||||
return iterator(this->impl.begin());
|
||||
}
|
||||
|
||||
const_iterator begin() const {
|
||||
return const_iterator(this->impl.begin());
|
||||
}
|
||||
|
||||
iterator end() {
|
||||
return iterator(this->impl.end());
|
||||
}
|
||||
|
||||
const_iterator end() const {
|
||||
return const_iterator(this->impl.end());
|
||||
}
|
||||
|
||||
const_iterator cbegin() const {
|
||||
return this->begin();
|
||||
}
|
||||
|
||||
const_iterator cend() const {
|
||||
return this->end();
|
||||
}
|
||||
|
||||
reverse_iterator rbegin() {
|
||||
return reverse_iterator(this->end());
|
||||
}
|
||||
|
||||
const_reverse_iterator rbegin() const {
|
||||
return const_reverse_iterator(this->end());
|
||||
}
|
||||
|
||||
reverse_iterator rend() {
|
||||
return reverse_iterator(this->begin());
|
||||
}
|
||||
|
||||
const_reverse_iterator rend() const {
|
||||
return const_reverse_iterator(this->begin());
|
||||
}
|
||||
|
||||
const_reverse_iterator crbegin() const {
|
||||
return this->rbegin();
|
||||
}
|
||||
|
||||
const_reverse_iterator crend() const {
|
||||
return this->rend();
|
||||
}
|
||||
|
||||
iterator iterator_to(reference v) {
|
||||
return iterator(this->impl.iterator_to(GetNode(v)));
|
||||
}
|
||||
|
||||
const_iterator iterator_to(const_reference v) const {
|
||||
return const_iterator(this->impl.iterator_to(GetNode(v)));
|
||||
}
|
||||
|
||||
/* Content management. */
|
||||
bool empty() const {
|
||||
return this->impl.empty();
|
||||
}
|
||||
|
||||
size_type size() const {
|
||||
return this->impl.size();
|
||||
}
|
||||
|
||||
reference back() {
|
||||
AMS_ASSERT(!this->impl.empty());
|
||||
return GetParent(this->impl.back());
|
||||
}
|
||||
|
||||
const_reference back() const {
|
||||
AMS_ASSERT(!this->impl.empty());
|
||||
return GetParent(this->impl.back());
|
||||
}
|
||||
|
||||
reference front() {
|
||||
AMS_ASSERT(!this->impl.empty());
|
||||
return GetParent(this->impl.front());
|
||||
}
|
||||
|
||||
const_reference front() const {
|
||||
AMS_ASSERT(!this->impl.empty());
|
||||
return GetParent(this->impl.front());
|
||||
}
|
||||
|
||||
void push_back(reference ref) {
|
||||
this->impl.push_back(GetNode(ref));
|
||||
}
|
||||
|
||||
void push_front(reference ref) {
|
||||
this->impl.push_back(GetNode(ref));
|
||||
}
|
||||
|
||||
void pop_back() {
|
||||
AMS_ASSERT(!this->impl.empty());
|
||||
this->impl.pop_back();
|
||||
}
|
||||
|
||||
void pop_front() {
|
||||
AMS_ASSERT(!this->impl.empty());
|
||||
this->impl.pop_front();
|
||||
}
|
||||
|
||||
iterator insert(const_iterator pos, reference ref) {
|
||||
return iterator(this->impl.insert(pos.GetImplIterator(), GetNode(ref)));
|
||||
}
|
||||
|
||||
void splice(const_iterator pos, IntrusiveList &o) {
|
||||
this->impl.splice(pos.GetImplIterator(), o.impl);
|
||||
}
|
||||
|
||||
void splice(const_iterator pos, IntrusiveList &o, const_iterator first) {
|
||||
this->impl.splice(pos.GetImplIterator(), o.impl, first.GetImplIterator());
|
||||
}
|
||||
|
||||
void splice(const_iterator pos, IntrusiveList &o, const_iterator first, const_iterator last) {
|
||||
this->impl.splice(pos.GetImplIterator(), o.impl, first.GetImplIterator(), last.GetImplIterator());
|
||||
}
|
||||
|
||||
iterator erase(const iterator pos) {
|
||||
return iterator(this->impl.erase(pos.GetImplIterator()));
|
||||
}
|
||||
|
||||
void clear() {
|
||||
this->impl.clear();
|
||||
}
|
||||
};
|
||||
|
||||
template<auto T, class Derived = util::impl::GetParentType<T>>
|
||||
class IntrusiveListMemberTraits;
|
||||
|
||||
template<class Parent, IntrusiveListNode Parent::*Member, class Derived>
|
||||
class IntrusiveListMemberTraits<Member, Derived> {
|
||||
public:
|
||||
using ListType = IntrusiveList<Derived, IntrusiveListMemberTraits>;
|
||||
private:
|
||||
friend class IntrusiveList<Derived, IntrusiveListMemberTraits>;
|
||||
|
||||
static constexpr IntrusiveListNode &GetNode(Derived &parent) {
|
||||
return parent.*Member;
|
||||
}
|
||||
|
||||
static constexpr IntrusiveListNode const &GetNode(Derived const &parent) {
|
||||
return parent.*Member;
|
||||
}
|
||||
|
||||
static constexpr Derived &GetParent(IntrusiveListNode &node) {
|
||||
return static_cast<Derived &>(util::GetParentReference<Member>(&node));
|
||||
}
|
||||
|
||||
static constexpr Derived const &GetParent(IntrusiveListNode const &node) {
|
||||
return static_cast<const Derived &>(util::GetParentReference<Member>(&node));
|
||||
}
|
||||
};
|
||||
|
||||
template<class Derived>
|
||||
class IntrusiveListBaseNode : public IntrusiveListNode{};
|
||||
|
||||
template<class Derived>
|
||||
class IntrusiveListBaseTraits {
|
||||
public:
|
||||
using ListType = IntrusiveList<Derived, IntrusiveListBaseTraits>;
|
||||
private:
|
||||
friend class IntrusiveList<Derived, IntrusiveListBaseTraits>;
|
||||
|
||||
static constexpr IntrusiveListNode &GetNode(Derived &parent) {
|
||||
return static_cast<IntrusiveListNode &>(parent);
|
||||
}
|
||||
|
||||
static constexpr IntrusiveListNode const &GetNode(Derived const &parent) {
|
||||
return static_cast<const IntrusiveListNode &>(parent);
|
||||
}
|
||||
|
||||
static constexpr Derived &GetParent(IntrusiveListNode &node) {
|
||||
return static_cast<Derived &>(node);
|
||||
}
|
||||
|
||||
static constexpr Derived const &GetParent(IntrusiveListNode const &node) {
|
||||
return static_cast<const Derived &>(node);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,297 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 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 <freebsd/sys/tree.h>
|
||||
#include "util_parent_of_member.hpp"
|
||||
|
||||
namespace ams::util {
|
||||
|
||||
struct IntrusiveRedBlackTreeNode {
|
||||
NON_COPYABLE(IntrusiveRedBlackTreeNode);
|
||||
private:
|
||||
RB_ENTRY(IntrusiveRedBlackTreeNode) entry;
|
||||
|
||||
template<class, class, class>
|
||||
friend class IntrusiveRedBlackTree;
|
||||
public:
|
||||
IntrusiveRedBlackTreeNode() { /* ... */}
|
||||
};
|
||||
|
||||
template<class T, class Traits, class Comparator>
|
||||
class IntrusiveRedBlackTree {
|
||||
NON_COPYABLE(IntrusiveRedBlackTree);
|
||||
private:
|
||||
RB_HEAD(IntrusiveRedBlackTreeRoot, IntrusiveRedBlackTreeNode);
|
||||
|
||||
IntrusiveRedBlackTreeRoot root;
|
||||
public:
|
||||
template<bool Const>
|
||||
class Iterator;
|
||||
|
||||
using value_type = T;
|
||||
using size_type = size_t;
|
||||
using difference_type = ptrdiff_t;
|
||||
using pointer = T *;
|
||||
using const_pointer = const T *;
|
||||
using reference = T &;
|
||||
using const_reference = const T &;
|
||||
using iterator = Iterator<false>;
|
||||
using const_iterator = Iterator<true>;
|
||||
|
||||
template<bool Const>
|
||||
class Iterator {
|
||||
public:
|
||||
using iterator_category = std::bidirectional_iterator_tag;
|
||||
using value_type = typename IntrusiveRedBlackTree::value_type;
|
||||
using difference_type = typename IntrusiveRedBlackTree::difference_type;
|
||||
using pointer = typename std::conditional<Const, IntrusiveRedBlackTree::const_pointer, IntrusiveRedBlackTree::pointer>::type;
|
||||
using reference = typename std::conditional<Const, IntrusiveRedBlackTree::const_reference, IntrusiveRedBlackTree::reference>::type;
|
||||
private:
|
||||
pointer node;
|
||||
public:
|
||||
explicit Iterator(pointer n) : node(n) { /* ... */ }
|
||||
|
||||
bool operator==(const Iterator &rhs) const {
|
||||
return this->node == rhs.node;
|
||||
}
|
||||
|
||||
bool operator!=(const Iterator &rhs) const {
|
||||
return !(*this == rhs);
|
||||
}
|
||||
|
||||
pointer operator->() const {
|
||||
return this->node;
|
||||
}
|
||||
|
||||
reference operator*() const {
|
||||
return *this->node;
|
||||
}
|
||||
|
||||
Iterator &operator++() {
|
||||
this->node = Traits::GetParent(GetNext(Traits::GetNode(this->node)));
|
||||
return *this;
|
||||
}
|
||||
|
||||
Iterator &operator--() {
|
||||
this->node = Traits::GetParent(GetPrev(Traits::GetNode(this->node)));
|
||||
return *this;
|
||||
}
|
||||
|
||||
Iterator operator++(int) {
|
||||
const Iterator it{*this};
|
||||
++(*this);
|
||||
return it;
|
||||
}
|
||||
|
||||
Iterator operator--(int) {
|
||||
const Iterator it{*this};
|
||||
--(*this);
|
||||
return it;
|
||||
}
|
||||
|
||||
operator Iterator<true>() const {
|
||||
return Iterator<true>(this->node);
|
||||
}
|
||||
};
|
||||
private:
|
||||
static int CompareImpl(const IntrusiveRedBlackTreeNode *lhs, const IntrusiveRedBlackTreeNode *rhs) {
|
||||
return Comparator::Compare(*Traits::GetParent(lhs), *Traits::GetParent(rhs));
|
||||
}
|
||||
|
||||
/* Generate static implementations for IntrusiveRedBlackTreeRoot. */
|
||||
RB_GENERATE_STATIC(IntrusiveRedBlackTreeRoot, IntrusiveRedBlackTreeNode, entry, CompareImpl);
|
||||
|
||||
static constexpr inline IntrusiveRedBlackTreeNode *GetNext(IntrusiveRedBlackTreeNode *node) {
|
||||
return RB_NEXT(IntrusiveRedBlackTreeRoot, nullptr, node);
|
||||
}
|
||||
|
||||
static constexpr inline IntrusiveRedBlackTreeNode const *GetNext(IntrusiveRedBlackTreeNode const *node) {
|
||||
return const_cast<const IntrusiveRedBlackTreeNode *>(GetNext(const_cast<IntrusiveRedBlackTreeNode *>(node)));
|
||||
}
|
||||
|
||||
static constexpr inline IntrusiveRedBlackTreeNode *GetPrev(IntrusiveRedBlackTreeNode *node) {
|
||||
return RB_NEXT(IntrusiveRedBlackTreeRoot, nullptr, node);
|
||||
}
|
||||
|
||||
static constexpr inline IntrusiveRedBlackTreeNode const *GetPrev(IntrusiveRedBlackTreeNode const *node) {
|
||||
return const_cast<const IntrusiveRedBlackTreeNode *>(GetPrev(const_cast<IntrusiveRedBlackTreeNode *>(node)));
|
||||
}
|
||||
|
||||
/* Define accessors using RB_* functions. */
|
||||
void InitializeImpl() {
|
||||
RB_INIT(&this->root);
|
||||
}
|
||||
|
||||
bool EmptyImpl() const {
|
||||
return RB_EMPTY(&this->root);
|
||||
}
|
||||
|
||||
IntrusiveRedBlackTreeNode *GetMinImpl() const {
|
||||
return RB_MIN(IntrusiveRedBlackTreeRoot, const_cast<IntrusiveRedBlackTreeRoot *>(&this->root));
|
||||
}
|
||||
|
||||
IntrusiveRedBlackTreeNode *GetMaxImpl() const {
|
||||
return RB_MIN(IntrusiveRedBlackTreeRoot, const_cast<IntrusiveRedBlackTreeRoot *>(&this->root));
|
||||
}
|
||||
|
||||
IntrusiveRedBlackTreeNode *InsertImpl(IntrusiveRedBlackTreeNode *node) {
|
||||
return RB_INSERT(IntrusiveRedBlackTreeRoot, &this->root, node);
|
||||
}
|
||||
|
||||
IntrusiveRedBlackTreeNode *RemoveImpl(IntrusiveRedBlackTreeNode *node) {
|
||||
return RB_REMOVE(IntrusiveRedBlackTreeRoot, &this->root, node);
|
||||
}
|
||||
|
||||
IntrusiveRedBlackTreeNode *FindImpl(IntrusiveRedBlackTreeNode const *node) const {
|
||||
return RB_FIND(IntrusiveRedBlackTreeRoot, const_cast<IntrusiveRedBlackTreeRoot *>(&this->root), const_cast<IntrusiveRedBlackTreeNode *>(node));
|
||||
}
|
||||
|
||||
IntrusiveRedBlackTreeNode *NFindImpl(IntrusiveRedBlackTreeNode const *node) const {
|
||||
return RB_NFIND(IntrusiveRedBlackTreeRoot, const_cast<IntrusiveRedBlackTreeRoot *>(&this->root), const_cast<IntrusiveRedBlackTreeNode *>(node));
|
||||
}
|
||||
|
||||
public:
|
||||
IntrusiveRedBlackTree() {
|
||||
this->InitializeImpl();
|
||||
}
|
||||
|
||||
/* Iterator accessors. */
|
||||
iterator begin() {
|
||||
return iterator(Traits::GetParent(this->GetMinImpl()));
|
||||
}
|
||||
|
||||
const_iterator begin() const {
|
||||
return const_iterator(Traits::GetParent(this->GetMinImpl()));
|
||||
}
|
||||
|
||||
iterator end() {
|
||||
return iterator(Traits::GetParent(static_cast<IntrusiveRedBlackTreeNode *>(nullptr)));
|
||||
}
|
||||
|
||||
const_iterator end() const {
|
||||
return const_iterator(Traits::GetParent(static_cast<IntrusiveRedBlackTreeNode *>(nullptr)));
|
||||
}
|
||||
|
||||
iterator iterator_to(reference ref) {
|
||||
return iterator(&ref);
|
||||
}
|
||||
|
||||
const_iterator iterator_to(const_reference ref) const {
|
||||
return const_iterator(&ref);
|
||||
}
|
||||
|
||||
/* Content management. */
|
||||
bool empty() const {
|
||||
return this->EmptyImpl();
|
||||
}
|
||||
|
||||
reference back() {
|
||||
return Traits::GetParent(this->GetMaxImpl());
|
||||
}
|
||||
|
||||
const_reference back() const {
|
||||
return Traits::GetParent(this->GetMaxImpl());
|
||||
}
|
||||
|
||||
reference front() {
|
||||
return Traits::GetParent(this->GetMinImpl());
|
||||
}
|
||||
|
||||
const_reference front() const {
|
||||
return Traits::GetParent(this->GetMinImpl());
|
||||
}
|
||||
|
||||
iterator insert(reference ref) {
|
||||
this->InsertImpl(Traits::GetNode(&ref));
|
||||
return iterator(&ref);
|
||||
}
|
||||
|
||||
iterator erase(iterator it) {
|
||||
auto cur = Traits::GetNode(&*it);
|
||||
auto next = Traits::GetParent(GetNext(cur));
|
||||
this->RemoveImpl(cur);
|
||||
return iterator(next);
|
||||
}
|
||||
|
||||
iterator find(const_reference ref) const {
|
||||
return iterator(Traits::GetParent(this->FindImpl(Traits::GetNode(&ref))));
|
||||
}
|
||||
|
||||
iterator nfind(const_reference ref) const {
|
||||
return iterator(Traits::GetParent(this->NFindImpl(Traits::GetNode(&ref))));
|
||||
}
|
||||
};
|
||||
|
||||
template<auto T, class Derived = util::impl::GetParentType<T>>
|
||||
class IntrusiveRedBlackTreeMemberTraits;
|
||||
|
||||
template<class Parent, IntrusiveRedBlackTreeNode Parent::*Member, class Derived>
|
||||
class IntrusiveRedBlackTreeMemberTraits<Member, Derived> {
|
||||
public:
|
||||
template<class Comparator>
|
||||
using ListType = IntrusiveRedBlackTree<Derived, IntrusiveRedBlackTreeMemberTraits, Comparator>;
|
||||
private:
|
||||
template<class, class, class>
|
||||
friend class IntrusiveRedBlackTree;
|
||||
|
||||
static constexpr IntrusiveRedBlackTreeNode *GetNode(Derived *parent) {
|
||||
return &(parent->*Member);
|
||||
}
|
||||
|
||||
static constexpr IntrusiveRedBlackTreeNode const *GetNode(Derived const *parent) {
|
||||
return &(parent->*Member);
|
||||
}
|
||||
|
||||
static constexpr Derived *GetParent(IntrusiveRedBlackTreeNode *node) {
|
||||
return static_cast<Derived *>(util::GetParentPointer<Member>(node));
|
||||
}
|
||||
|
||||
static constexpr Derived const *GetParent(IntrusiveRedBlackTreeNode const *node) {
|
||||
return static_cast<const Derived *>(util::GetParentPointer<Member>(node));
|
||||
}
|
||||
};
|
||||
|
||||
template<class Derived>
|
||||
class IntrusiveRedBlackTreeBaseNode : public IntrusiveRedBlackTreeNode{};
|
||||
|
||||
template<class Derived>
|
||||
class IntrusiveRedBlackTreeBaseTraits {
|
||||
public:
|
||||
template<class Comparator>
|
||||
using ListType = IntrusiveRedBlackTree<Derived, IntrusiveRedBlackTreeBaseTraits, Comparator>;
|
||||
private:
|
||||
template<class, class, class>
|
||||
friend class IntrusiveRedBlackTree;
|
||||
|
||||
static constexpr IntrusiveRedBlackTreeNode *GetNode(Derived *parent) {
|
||||
return static_cast<IntrusiveRedBlackTreeNode *>(parent);
|
||||
}
|
||||
|
||||
static constexpr IntrusiveRedBlackTreeNode const *GetNode(Derived const *parent) {
|
||||
return static_cast<const IntrusiveRedBlackTreeNode *>(parent);
|
||||
}
|
||||
|
||||
static constexpr Derived *GetParent(IntrusiveRedBlackTreeNode *node) {
|
||||
return static_cast<Derived *>(node);
|
||||
}
|
||||
|
||||
static constexpr Derived const *GetParent(IntrusiveRedBlackTreeNode const *node) {
|
||||
return static_cast<const Derived *>(node);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 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 "../defines.hpp"
|
||||
|
||||
namespace ams::util {
|
||||
|
||||
namespace impl {
|
||||
|
||||
template<typename Parent, typename Member>
|
||||
union OffsetOfImpl {
|
||||
Member Parent::* ptr;
|
||||
intptr_t offset;
|
||||
};
|
||||
|
||||
template<typename Parent, typename Member>
|
||||
constexpr inline Parent *GetParentOfMemberImpl(Member *member, Member Parent::* ptr) {
|
||||
return reinterpret_cast<Parent *>(reinterpret_cast<uintptr_t>(member) - OffsetOfImpl<Parent, Member>{ ptr }.offset);
|
||||
}
|
||||
|
||||
template<typename Parent, typename Member>
|
||||
constexpr inline Parent const *GetParentOfMemberImpl(Member const *member, Member Parent::* ptr) {
|
||||
return reinterpret_cast<Parent *>(reinterpret_cast<uintptr_t>(member) - OffsetOfImpl<Parent, Member>{ ptr }.offset);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
struct GetMemberPointerTraits;
|
||||
|
||||
template<typename P, typename M>
|
||||
struct GetMemberPointerTraits<M P::*> {
|
||||
using Parent = P;
|
||||
using Member = M;
|
||||
};
|
||||
|
||||
template<auto MemberPtr>
|
||||
using GetParentType = typename GetMemberPointerTraits<decltype(MemberPtr)>::Parent;
|
||||
|
||||
template<auto MemberPtr>
|
||||
using GetMemberType = typename GetMemberPointerTraits<decltype(MemberPtr)>::Member;
|
||||
|
||||
}
|
||||
|
||||
template<auto MemberPtr>
|
||||
constexpr inline impl::GetParentType<MemberPtr> *GetParentPointer(impl::GetMemberType<MemberPtr> *member) {
|
||||
return impl::GetParentOfMemberImpl<impl::GetParentType<MemberPtr>, impl::GetMemberType<MemberPtr>>(member, MemberPtr);
|
||||
}
|
||||
|
||||
template<auto MemberPtr>
|
||||
constexpr inline impl::GetParentType<MemberPtr> const *GetParentPointer(impl::GetMemberType<MemberPtr> const *member) {
|
||||
return impl::GetParentOfMemberImpl<impl::GetParentType<MemberPtr>, impl::GetMemberType<MemberPtr>>(member, MemberPtr);
|
||||
}
|
||||
|
||||
template<auto MemberPtr>
|
||||
constexpr inline impl::GetParentType<MemberPtr> &GetParentReference(impl::GetMemberType<MemberPtr> *member) {
|
||||
return *impl::GetParentOfMemberImpl<impl::GetParentType<MemberPtr>, impl::GetMemberType<MemberPtr>>(member, MemberPtr);
|
||||
}
|
||||
|
||||
template<auto MemberPtr>
|
||||
constexpr inline impl::GetParentType<MemberPtr> const &GetParentReference(impl::GetMemberType<MemberPtr> const *member) {
|
||||
return *impl::GetParentOfMemberImpl<impl::GetParentType<MemberPtr>, impl::GetMemberType<MemberPtr>>(member, MemberPtr);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 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/>.
|
||||
*/
|
||||
|
||||
/* Scope guard logic lovingly taken from Andrei Alexandrescu's "Systemic Error Handling in C++" */
|
||||
#pragma once
|
||||
#include "../defines.hpp"
|
||||
|
||||
namespace ams::util {
|
||||
|
||||
namespace impl {
|
||||
|
||||
template<class F>
|
||||
class ScopeGuard {
|
||||
NON_COPYABLE(ScopeGuard);
|
||||
private:
|
||||
F f;
|
||||
bool active;
|
||||
public:
|
||||
constexpr ScopeGuard(F f) : f(std::move(f)), active(true) { }
|
||||
~ScopeGuard() { if (active) { f(); } }
|
||||
void Cancel() { active = false; }
|
||||
|
||||
ScopeGuard(ScopeGuard&& rhs) : f(std::move(rhs.f)), active(rhs.active) {
|
||||
rhs.Cancel();
|
||||
}
|
||||
};
|
||||
|
||||
template<class F>
|
||||
constexpr ScopeGuard<F> MakeScopeGuard(F f) {
|
||||
return ScopeGuard<F>(std::move(f));
|
||||
}
|
||||
|
||||
enum class ScopeGuardOnExit {};
|
||||
|
||||
template <typename F>
|
||||
constexpr ScopeGuard<F> operator+(ScopeGuardOnExit, F&& f) {
|
||||
return ScopeGuard<F>(std::forward<F>(f));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#define SCOPE_GUARD ::ams::util::impl::ScopeGuardOnExit() + [&]()
|
||||
#define ON_SCOPE_EXIT auto ANONYMOUS_VARIABLE(SCOPE_EXIT_STATE_) = SCOPE_GUARD
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 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 "../defines.hpp"
|
||||
|
||||
namespace ams::util {
|
||||
|
||||
/* std::size() does not support zero-size C arrays. We're fixing that. */
|
||||
template<class C>
|
||||
constexpr auto size(const C& c) -> decltype(c.size()) {
|
||||
return std::size(c);
|
||||
}
|
||||
|
||||
template<class C>
|
||||
constexpr std::size_t size(const C& c) {
|
||||
if constexpr (sizeof(C) == 0) {
|
||||
return 0;
|
||||
} else {
|
||||
return std::size(c);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 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 "../defines.hpp"
|
||||
|
||||
namespace ams::util {
|
||||
|
||||
template<typename T, size_t Size, size_t Align>
|
||||
struct TypedStorage {
|
||||
typename std::aligned_storage<Size, Align>::type _storage;
|
||||
};
|
||||
|
||||
#define TYPED_STORAGE(T) ::ams::util::TypedStorage<T, sizeof(T), alignof(T)>
|
||||
|
||||
template<typename T>
|
||||
static constexpr inline __attribute__((always_inline)) T *GetPointer(TYPED_STORAGE(T) &ts) {
|
||||
return reinterpret_cast<T *>(&ts._storage);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static constexpr inline __attribute__((always_inline)) const T *GetPointer(const TYPED_STORAGE(T) &ts) {
|
||||
return reinterpret_cast<const T *>(&ts._storage);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static constexpr inline __attribute__((always_inline)) T &GetReference(TYPED_STORAGE(T) &ts) {
|
||||
return *GetPointer(ts);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static constexpr inline __attribute__((always_inline)) const T &GetReference(const TYPED_STORAGE(T) &ts) {
|
||||
return *GetPointer(ts);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user