ams: update to build with gcc10/c++20

This commit is contained in:
Michael Scire
2020-05-05 18:16:13 -07:00
parent 17b6bcfd37
commit 492a9e1849
87 changed files with 361 additions and 322 deletions

View File

@@ -5,7 +5,7 @@ endif
include $(DEVKITPRO)/devkitA64/base_rules
export ATMOSPHERE_DEFINES += -DATMOSPHERE_ARCH_ARM64
export ATMOSPHERE_SETTINGS += -march=armv8-a+crc+crypto -mtp=soft
export ATMOSPHERE_SETTINGS += -march=armv8-a+crc+crypto -mno-outline-atomics -mtp=soft
export ATMOSPHERE_CFLAGS +=
export ATMOSPHERE_CXXFLAGS +=
export ATMOSPHERE_ASFLAGS +=

View File

@@ -18,7 +18,7 @@ export ATMOSPHERE_DEFINES := -DATMOSPHERE
export ATMOSPHERE_SETTINGS := -fPIE -g
export ATMOSPHERE_CFLAGS := -Wall -ffunction-sections -fdata-sections -fno-strict-aliasing -fwrapv \
-fno-asynchronous-unwind-tables -fno-unwind-tables -fno-stack-protector
export ATMOSPHERE_CXXFLAGS := -fno-rtti -fno-exceptions -std=gnu++17
export ATMOSPHERE_CXXFLAGS := -fno-rtti -fno-exceptions -std=gnu++2a
export ATMOSPHERE_ASFLAGS :=

View File

@@ -122,6 +122,8 @@ $(filter-out kern_svc_tables.o, $(OFILES)) : $(GCH_FILES)
$(OFILES_SRC) : $(HFILES_BIN)
kern_libc_generic.o: CFLAGS += -fno-builtin
#---------------------------------------------------------------------------------
%_bin.h %.bin.o : %.bin
#---------------------------------------------------------------------------------

View File

@@ -72,7 +72,7 @@ namespace ams::kern::arch::arm64 {
SgirTargetListFilter_Reserved = (3 << 24),
};
};
static_assert(std::is_pod<GicDistributor>::value);
static_assert(util::is_pod<GicDistributor>::value);
static_assert(sizeof(GicDistributor) == 0x1000);
struct GicCpuInterface {
@@ -98,7 +98,7 @@ namespace ams::kern::arch::arm64 {
u32 dir;
u32 _0x1004[1023];
};
static_assert(std::is_pod<GicCpuInterface>::value);
static_assert(util::is_pod<GicCpuInterface>::value);
static_assert(sizeof(GicCpuInterface) == 0x2000);
struct KInterruptController {
@@ -164,11 +164,11 @@ namespace ams::kern::arch::arm64 {
}
void SetTarget(s32 irq, s32 core_id) const {
this->gicd->itargetsr.bytes[irq] |= GetGicMask(core_id);
this->gicd->itargetsr.bytes[irq] = this->gicd->itargetsr.bytes[irq] | GetGicMask(core_id);
}
void ClearTarget(s32 irq, s32 core_id) const {
this->gicd->itargetsr.bytes[irq] &= ~GetGicMask(core_id);
this->gicd->itargetsr.bytes[irq] = this->gicd->itargetsr.bytes[irq] & ~GetGicMask(core_id);
}
void SetPriorityLevel(s32 irq, s32 level) const {

View File

@@ -32,7 +32,7 @@ namespace ams::kern::init {
u32 init_array_offset;
u32 init_array_end_offset;
};
static_assert(std::is_pod<KernelLayout>::value);
static_assert(util::is_pod<KernelLayout>::value);
static_assert(sizeof(KernelLayout) == 0x30);
}

View File

@@ -31,8 +31,10 @@ namespace ams::kern {
s32 core_id;
void *exception_stack_top;
};
static_assert(std::is_pod<KCurrentContext>::value);
static_assert(std::is_standard_layout<KCurrentContext>::value && std::is_trivially_destructible<KCurrentContext>::value);
static_assert(sizeof(KCurrentContext) <= cpu::DataCacheLineSize);
static_assert(sizeof(std::atomic<KThread *>) == sizeof(KThread *));
static_assert(sizeof(std::atomic<KProcess *>) == sizeof(KProcess *));
namespace impl {

View File

@@ -65,7 +65,7 @@ namespace ams::kern {
Node *next;
u8 buffer[PageSize - sizeof(Node *)];
};
static_assert(std::is_pod<Node>::value);
static_assert(util::is_pod<Node>::value);
private:
Node *root;
public:

View File

@@ -22,19 +22,19 @@ namespace ams::kern {
constexpr uintptr_t Invalid = std::numeric_limits<uintptr_t>::max();
constexpr KAddressSpaceInfo AddressSpaceInfos[] = {
{ .bit_width = 32, .address = 2_MB, .size = 1_GB - 2_MB, KAddressSpaceInfo::Type_32Bit, },
{ .bit_width = 32, .address = 1_GB, .size = 4_GB - 1_GB, KAddressSpaceInfo::Type_Small64Bit, },
{ .bit_width = 32, .address = Invalid, .size = 1_GB, KAddressSpaceInfo::Type_Heap, },
{ .bit_width = 32, .address = Invalid, .size = 1_GB, KAddressSpaceInfo::Type_Alias, },
{ .bit_width = 36, .address = 128_MB, .size = 2_GB - 128_MB, KAddressSpaceInfo::Type_32Bit, },
{ .bit_width = 36, .address = 2_GB, .size = 64_GB - 2_GB, KAddressSpaceInfo::Type_Small64Bit, },
{ .bit_width = 36, .address = Invalid, .size = 6_GB, KAddressSpaceInfo::Type_Heap, },
{ .bit_width = 36, .address = Invalid, .size = 6_GB, KAddressSpaceInfo::Type_Alias, },
{ .bit_width = 39, .address = 128_MB, .size = 512_GB - 128_MB, KAddressSpaceInfo::Type_Large64Bit, },
{ .bit_width = 39, .address = Invalid, .size = 64_GB, KAddressSpaceInfo::Type_32Bit, },
{ .bit_width = 39, .address = Invalid, .size = 6_GB, KAddressSpaceInfo::Type_Heap, },
{ .bit_width = 39, .address = Invalid, .size = 64_GB, KAddressSpaceInfo::Type_Alias, },
{ .bit_width = 39, .address = Invalid, .size = 2_GB, KAddressSpaceInfo::Type_Stack, },
{ .bit_width = 32, .address = 2_MB, .size = 1_GB - 2_MB, .type = KAddressSpaceInfo::Type_32Bit, },
{ .bit_width = 32, .address = 1_GB, .size = 4_GB - 1_GB, .type = KAddressSpaceInfo::Type_Small64Bit, },
{ .bit_width = 32, .address = Invalid, .size = 1_GB, .type = KAddressSpaceInfo::Type_Heap, },
{ .bit_width = 32, .address = Invalid, .size = 1_GB, .type = KAddressSpaceInfo::Type_Alias, },
{ .bit_width = 36, .address = 128_MB, .size = 2_GB - 128_MB, .type = KAddressSpaceInfo::Type_32Bit, },
{ .bit_width = 36, .address = 2_GB, .size = 64_GB - 2_GB, .type = KAddressSpaceInfo::Type_Small64Bit, },
{ .bit_width = 36, .address = Invalid, .size = 6_GB, .type = KAddressSpaceInfo::Type_Heap, },
{ .bit_width = 36, .address = Invalid, .size = 6_GB, .type = KAddressSpaceInfo::Type_Alias, },
{ .bit_width = 39, .address = 128_MB, .size = 512_GB - 128_MB, .type = KAddressSpaceInfo::Type_Large64Bit, },
{ .bit_width = 39, .address = Invalid, .size = 64_GB, .type = KAddressSpaceInfo::Type_32Bit, },
{ .bit_width = 39, .address = Invalid, .size = 6_GB, .type = KAddressSpaceInfo::Type_Heap, },
{ .bit_width = 39, .address = Invalid, .size = 64_GB, .type = KAddressSpaceInfo::Type_Alias, },
{ .bit_width = 39, .address = Invalid, .size = 2_GB, .type = KAddressSpaceInfo::Type_Stack, },
};
constexpr bool IsAllowedIndexForAddress(size_t index) {

View File

@@ -104,7 +104,7 @@ namespace ams {
};
static_assert(sizeof(FatalErrorContext) == 0x450, "sizeof(FatalErrorContext)");
static_assert(std::is_pod<FatalErrorContext>::value, "FatalErrorContext");
static_assert(util::is_pod<FatalErrorContext>::value, "FatalErrorContext");
#ifdef ATMOSPHERE_GIT_BRANCH
NX_CONSTEXPR const char *GetGitBranch() {

View File

@@ -41,6 +41,6 @@ namespace ams::capsrv {
};
static_assert(sizeof(ScreenShotDecodeOption) == 0x20);
static_assert(sizeof(ScreenShotDecodeOption) == sizeof(::CapsScreenShotDecodeOption));
static_assert(std::is_pod<ScreenShotDecodeOption>::value);
static_assert(util::is_pod<ScreenShotDecodeOption>::value);
}

View File

@@ -49,7 +49,7 @@ namespace ams::cfg {
};
static_assert(sizeof(OverrideStatus) == 0x10, "sizeof(OverrideStatus)");
static_assert(std::is_pod<OverrideStatus>::value, "std::is_pod<OverrideStatus>::value");
static_assert(util::is_pod<OverrideStatus>::value, "util::is_pod<OverrideStatus>::value");
constexpr inline bool operator==(const OverrideStatus &lhs, const OverrideStatus &rhs) {
return std::memcmp(&lhs, &rhs, sizeof(lhs)) == 0;

View File

@@ -36,7 +36,7 @@ namespace ams::dmnt::cheat {
u8 main_nso_build_id[0x20];
};
static_assert(std::is_pod<CheatProcessMetadata>::value && sizeof(CheatProcessMetadata) == 0x70, "CheatProcessMetadata definition!");
static_assert(util::is_pod<CheatProcessMetadata>::value && sizeof(CheatProcessMetadata) == 0x70, "CheatProcessMetadata definition!");
struct CheatDefinition : sf::LargeData, sf::PrefersMapAliasTransferMode {
char readable_name[0x40];
@@ -50,8 +50,8 @@ namespace ams::dmnt::cheat {
CheatDefinition definition;
};
static_assert(std::is_pod<CheatDefinition>::value, "CheatDefinition");
static_assert(std::is_pod<CheatEntry>::value, "CheatEntry");
static_assert(util::is_pod<CheatDefinition>::value, "CheatDefinition");
static_assert(util::is_pod<CheatEntry>::value, "CheatEntry");
struct FrozenAddressValue {
u64 value;

View File

@@ -108,7 +108,7 @@ namespace ams::erpt {
};
using ReportFlagSet = util::BitFlagSet<BITSIZEOF(u32), ReportFlag>;
static_assert(std::is_pod<ReportFlagSet>::value);
static_assert(util::is_pod<ReportFlagSet>::value);
static_assert(sizeof(ReportFlagSet) == sizeof(u32));
struct ReportInfo {
@@ -149,7 +149,7 @@ namespace ams::erpt {
};
using AttachmentFlagSet = util::BitFlagSet<BITSIZEOF(u32), AttachmentFlag>;
static_assert(std::is_pod<AttachmentFlagSet>::value);
static_assert(util::is_pod<AttachmentFlagSet>::value);
static_assert(sizeof(AttachmentFlagSet) == sizeof(u32));
constexpr inline u32 AttachmentNameSizeMax = 0x20;

View File

@@ -75,44 +75,44 @@ namespace ams::fatal {
static constexpr size_t MaxStackTraceDepth = 0x20;
static constexpr const char *RegisterNameStrings[RegisterName_Count] = {
u8"X0",
u8"X1",
u8"X2",
u8"X3",
u8"X4",
u8"X5",
u8"X6",
u8"X7",
u8"X8",
u8"X9",
u8"X10",
u8"X11",
u8"X12",
u8"X13",
u8"X14",
u8"X15",
u8"X16",
u8"X17",
u8"X18",
u8"X19",
u8"X20",
u8"X21",
u8"X22",
u8"X23",
u8"X24",
u8"X25",
u8"X26",
u8"X27",
u8"X28",
u8"FP",
u8"LR",
u8"SP",
u8"PC",
u8"PState",
u8"Afsr0",
u8"Afsr1",
u8"Esr",
u8"Far",
"X0",
"X1",
"X2",
"X3",
"X4",
"X5",
"X6",
"X7",
"X8",
"X9",
"X10",
"X11",
"X12",
"X13",
"X14",
"X15",
"X16",
"X17",
"X18",
"X19",
"X20",
"X21",
"X22",
"X23",
"X24",
"X25",
"X26",
"X27",
"X28",
"FP",
"LR",
"SP",
"PC",
"PState",
"Afsr0",
"Afsr1",
"Esr",
"Far",
};
/* Registers, exception context. N left names for these fields in fatal .rodata. */
@@ -209,27 +209,27 @@ namespace ams::fatal {
static constexpr size_t MaxStackTraceDepth = 0x20;
static constexpr const char *RegisterNameStrings[RegisterName_Count] = {
u8"R0",
u8"R1",
u8"R2",
u8"R3",
u8"R4",
u8"R5",
u8"R6",
u8"R7",
u8"R8",
u8"R9",
u8"R10",
u8"FP",
u8"IP",
u8"LR",
u8"SP",
u8"PC",
u8"PState",
u8"Afsr0",
u8"Afsr1",
u8"Esr",
u8"Far",
"R0",
"R1",
"R2",
"R3",
"R4",
"R5",
"R6",
"R7",
"R8",
"R9",
"R10",
"FP",
"IP",
"LR",
"SP",
"PC",
"PState",
"Afsr0",
"Afsr1",
"Esr",
"Far",
};
/* Registers, exception context. N left names for these fields in fatal .rodata. */
@@ -311,9 +311,9 @@ namespace ams::fatal {
}
};
static_assert(std::is_pod<aarch64::CpuContext>::value && sizeof(aarch64::CpuContext) == 0x248, "aarch64::CpuContext definition!");
static_assert(std::is_pod<aarch32::CpuContext>::value && sizeof(aarch32::CpuContext) == 0xE0, "aarch32::CpuContext definition!");
static_assert(std::is_pod<CpuContext>::value && sizeof(CpuContext) == 0x250, "CpuContext definition!");
static_assert(util::is_pod<aarch64::CpuContext>::value && sizeof(aarch64::CpuContext) == 0x248, "aarch64::CpuContext definition!");
static_assert(util::is_pod<aarch32::CpuContext>::value && sizeof(aarch32::CpuContext) == 0xE0, "aarch32::CpuContext definition!");
static_assert(util::is_pod<CpuContext>::value && sizeof(CpuContext) == 0x250, "CpuContext definition!");
namespace srv {

View File

@@ -43,6 +43,6 @@ namespace ams::fs {
return this->Get();
}
};
static_assert(std::is_pod<Int64>::value);
static_assert(util::is_pod<Int64>::value);
}

View File

@@ -28,7 +28,7 @@ namespace ams::fs {
Position next_dir;
Position next_file;
};
static_assert(std::is_pod<FindPosition>::value);
static_assert(util::is_pod<FindPosition>::value);
using DirectoryInfo = RomDirectoryInfo;
using FileInfo = RomFileInfo;
@@ -56,13 +56,13 @@ namespace ams::fs {
Position dir;
Position file;
};
static_assert(std::is_pod<RomDirectoryEntry>::value);
static_assert(util::is_pod<RomDirectoryEntry>::value);
struct RomFileEntry {
Position next;
FileInfo info;
};
static_assert(std::is_pod<RomFileEntry>::value);
static_assert(util::is_pod<RomFileEntry>::value);
static constexpr inline u32 MaxKeyLength = RomPathTool::MaxPathLength;
@@ -109,7 +109,7 @@ namespace ams::fs {
return RomPathTool::IsEqualPath(reinterpret_cast<const RomPathChar *>(aux_lhs), reinterpret_cast<const RomPathChar *>(aux_rhs), aux_lhs_size / sizeof(RomPathChar));
}
};
static_assert(std::is_pod<RomEntryKey>::value);
static_assert(util::is_pod<RomEntryKey>::value);
struct EntryKey {
RomEntryKey key;
@@ -126,7 +126,7 @@ namespace ams::fs {
return hash;
}
};
static_assert(std::is_pod<EntryKey>::value);
static_assert(util::is_pod<EntryKey>::value);
using DirectoryEntryMapTable = EntryMapTable<RomEntryKey, EntryKey, RomDirectoryEntry>;
using FileEntryMapTable = EntryMapTable<RomEntryKey, EntryKey, RomFileEntry>;

View File

@@ -31,7 +31,7 @@ namespace ams::fs {
BucketIndex ind;
Position pos;
};
static_assert(std::is_pod<FindIndex>::value);
static_assert(util::is_pod<FindIndex>::value);
private:
static constexpr inline Position InvalidPosition = ~Position();
@@ -41,7 +41,7 @@ namespace ams::fs {
Position next;
u32 size;
};
static_assert(std::is_pod<Element>::value);
static_assert(util::is_pod<Element>::value);
private:
s64 bucket_count;
SubStorage bucket_storage;

View File

@@ -26,7 +26,7 @@ namespace ams::fs {
size_t length;
const RomPathChar *path;
};
static_assert(std::is_pod<RomEntryName>::value);
static_assert(util::is_pod<RomEntryName>::value);
constexpr void InitializeRomEntryName(RomEntryName *entry) {
AMS_ABORT_UNLESS(entry != nullptr);

View File

@@ -34,19 +34,19 @@ namespace ams::fs {
s64 file_entry_size;
s64 body_offset;
};
static_assert(std::is_pod<RomFileSystemInformation>::value);
static_assert(util::is_pod<RomFileSystemInformation>::value);
static_assert(sizeof(RomFileSystemInformation) == 0x50);
struct RomDirectoryInfo {
/* ... */
};
static_assert(std::is_pod<RomDirectoryInfo>::value);
static_assert(util::is_pod<RomDirectoryInfo>::value);
struct RomFileInfo {
Int64 offset;
Int64 size;
};
static_assert(std::is_pod<RomFileInfo>::value);
static_assert(util::is_pod<RomFileInfo>::value);
namespace RomStringTraits {

View File

@@ -34,7 +34,7 @@ namespace ams::fs {
return !(lhs == rhs);
}
static_assert(std::is_pod<ReadOption>::value && sizeof(ReadOption) == sizeof(u32));
static_assert(util::is_pod<ReadOption>::value && sizeof(ReadOption) == sizeof(u32));
struct WriteOption {
u32 value;
@@ -58,7 +58,7 @@ namespace ams::fs {
return !(lhs == rhs);
}
static_assert(std::is_pod<WriteOption>::value && sizeof(WriteOption) == sizeof(u32));
static_assert(util::is_pod<WriteOption>::value && sizeof(WriteOption) == sizeof(u32));
struct FileHandle {
void *handle;

View File

@@ -42,7 +42,7 @@ namespace ams::fs {
template<typename T>
std::unique_ptr<T, Deleter> MakeUnique() {
static_assert(std::is_pod<T>::value);
static_assert(util::is_pod<T>::value);
return std::unique_ptr<T, Deleter>(static_cast<T *>(::ams::fs::impl::Allocate(sizeof(T))), Deleter(sizeof(T)));
}

View File

@@ -36,7 +36,7 @@ namespace ams::fs {
}
};
static_assert(std::is_pod<QueryRangeInfo>::value);
static_assert(util::is_pod<QueryRangeInfo>::value);
static_assert(sizeof(QueryRangeInfo) == 0x40);
static_assert(sizeof(QueryRangeInfo) == sizeof(::FsRangeInfo));

View File

@@ -23,7 +23,7 @@ namespace ams::fs {
u64 data64[2];
};
static_assert(sizeof(RightsId) == 0x10);
static_assert(std::is_pod<RightsId>::value);
static_assert(util::is_pod<RightsId>::value);
inline bool operator==(const RightsId &lhs, const RightsId &rhs) {
return std::memcmp(std::addressof(lhs), std::addressof(rhs), sizeof(RightsId)) == 0;

View File

@@ -51,7 +51,7 @@ namespace ams::fs {
struct UserId {
u64 data[2];
};
static_assert(std::is_pod<UserId>::value);
static_assert(util::is_pod<UserId>::value);
constexpr inline bool operator<(const UserId &lhs, const UserId &rhs) {
if (lhs.data[0] < rhs.data[0]) {
@@ -92,7 +92,7 @@ namespace ams::fs {
bool pseudo;
u8 reserved[0x1A];
};
static_assert(std::is_pod<SaveDataCreationInfo>::value);
static_assert(util::is_pod<SaveDataCreationInfo>::value);
static_assert(sizeof(SaveDataCreationInfo) == 0x40);
struct SaveDataAttribute {
@@ -154,6 +154,6 @@ namespace ams::fs {
u8 unused[0x190];
};
static_assert(sizeof(SaveDataExtraData) == 0x200);
static_assert(std::is_pod<SaveDataExtraData>::value);
static_assert(util::is_pod<SaveDataExtraData>::value);
}

View File

@@ -43,7 +43,7 @@ namespace ams::fssrv::sf {
}
};
static_assert(std::is_pod<Path>::value && sizeof(Path) == FS_MAX_PATH);
static_assert(util::is_pod<Path>::value && sizeof(Path) == FS_MAX_PATH);
using FspPath = Path;

View File

@@ -30,7 +30,7 @@ namespace ams::fssystem {
class PageList;
struct PageEntry { PageEntry *next; };
static_assert(std::is_pod<PageEntry>::value);
static_assert(util::is_pod<PageEntry>::value);
static_assert(sizeof(PageEntry) <= BlockSizeMin);
class PageList : public ::ams::fs::impl::Newable {

View File

@@ -35,7 +35,7 @@ namespace ams::fssystem {
Position next_dir;
Position next_file;
};
static_assert(std::is_pod<FindPosition>::value);
static_assert(util::is_pod<FindPosition>::value);
using DirectoryInfo = RomDirectoryInfo;
using FileInfo = RomFileInfo;
@@ -63,13 +63,13 @@ namespace ams::fssystem {
Position dir;
Position file;
};
static_assert(std::is_pod<RomDirectoryEntry>::value);
static_assert(util::is_pod<RomDirectoryEntry>::value);
struct RomFileEntry {
Position next;
FileInfo info;
};
static_assert(std::is_pod<RomFileEntry>::value);
static_assert(util::is_pod<RomFileEntry>::value);
static constexpr inline u32 MaxKeyLength = RomPathTool::MaxPathLength;
@@ -115,7 +115,7 @@ namespace ams::fssystem {
return RomPathTool::IsEqualPath(reinterpret_cast<const RomPathChar *>(aux_lhs), reinterpret_cast<const RomPathChar *>(aux_rhs), aux_lhs_size / sizeof(RomPathChar));
}
};
static_assert(std::is_pod<RomEntryKey>::value);
static_assert(util::is_pod<RomEntryKey>::value);
struct EntryKey {
RomEntryKey key;
@@ -132,7 +132,7 @@ namespace ams::fssystem {
return hash;
}
};
static_assert(std::is_pod<EntryKey>::value);
static_assert(util::is_pod<EntryKey>::value);
using DirectoryEntryMapTable = EntryMapTable<DirectoryBucketStorage, DirectoryEntryStorage, RomEntryKey, EntryKey, RomDirectoryEntry>;
using FileEntryMapTable = EntryMapTable<FileBucketStorage, FileEntryStorage, RomEntryKey, EntryKey, RomFileEntry>;

View File

@@ -37,7 +37,7 @@ namespace ams::fssystem {
BucketIndex ind;
Position pos;
};
static_assert(std::is_pod<FindIndex>::value);
static_assert(util::is_pod<FindIndex>::value);
private:
static constexpr inline Position InvalidPosition = ~Position();
@@ -47,7 +47,7 @@ namespace ams::fssystem {
Position next;
u32 size;
};
static_assert(std::is_pod<Element>::value);
static_assert(util::is_pod<Element>::value);
private:
s64 bucket_offset;
u32 bucket_count;

View File

@@ -26,7 +26,7 @@ namespace ams::fssystem {
size_t length;
const RomPathChar *path;
};
static_assert(std::is_pod<RomEntryName>::value);
static_assert(util::is_pod<RomEntryName>::value);
constexpr void InitializeRomEntryName(RomEntryName *entry) {
entry->length = 0;

View File

@@ -34,19 +34,19 @@ namespace ams::fssystem {
s64 file_entry_size;
s64 body_offset;
};
static_assert(std::is_pod<RomFileSystemInformation>::value);
static_assert(util::is_pod<RomFileSystemInformation>::value);
static_assert(sizeof(RomFileSystemInformation) == 0x50);
struct RomDirectoryInfo {
/* ... */
};
static_assert(std::is_pod<RomDirectoryInfo>::value);
static_assert(util::is_pod<RomDirectoryInfo>::value);
struct RomFileInfo {
fs::Int64 offset;
fs::Int64 size;
};
static_assert(std::is_pod<RomFileInfo>::value);
static_assert(util::is_pod<RomFileInfo>::value);
namespace RomStringTraits {

View File

@@ -29,7 +29,7 @@ namespace ams::fssystem {
u32 name_offset;
u32 reserved;
};
static_assert(std::is_pod<PartitionEntry>::value);
static_assert(util::is_pod<PartitionEntry>::value);
#pragma pack(pop)
static constexpr const char VersionSignature[] = { 'P', 'F', 'S', '0' };
@@ -52,7 +52,7 @@ namespace ams::fssystem {
u64 hash_target_offset;
char hash[HashSize];
};
static_assert(std::is_pod<PartitionEntry>::value);
static_assert(util::is_pod<PartitionEntry>::value);
#pragma pack(pop)
static constexpr const char VersionSignature[] = { 'H', 'F', 'S', '0' };

View File

@@ -186,7 +186,7 @@ namespace ams::kvdb {
template<class Key, size_t Capacity>
class FileKeyValueCache {
static_assert(std::is_pod<Key>::value, "FileKeyValueCache Key must be pod!");
static_assert(util::is_pod<Key>::value, "FileKeyValueCache Key must be pod!");
static_assert(sizeof(Key) <= FileKeyValueStore::MaxKeySize, "FileKeyValueCache Key is too big!");
public:
using LeastRecentlyUsedList = impl::LruList<Key, Capacity>;

View File

@@ -38,7 +38,7 @@ namespace ams::kvdb {
size_t key_size;
size_t value_size;
};
static_assert(std::is_pod<Entry>::value, "FileKeyValueStore::Entry definition!");
static_assert(util::is_pod<Entry>::value, "FileKeyValueStore::Entry definition!");
class Cache {
private:
@@ -83,13 +83,13 @@ namespace ams::kvdb {
/* Niceties. */
template<typename Key>
Result Get(size_t *out_size, void *out_value, size_t max_out_size, const Key &key) {
static_assert(std::is_pod<Key>::value && sizeof(Key) <= MaxKeySize, "Invalid FileKeyValueStore Key!");
static_assert(util::is_pod<Key>::value && sizeof(Key) <= MaxKeySize, "Invalid FileKeyValueStore Key!");
return this->Get(out_size, out_value, max_out_size, &key, sizeof(Key));
}
template<typename Key, typename Value>
Result Get(Value *out_value, const Key &key) {
static_assert(std::is_pod<Value>::value && !std::is_pointer<Value>::value, "Invalid FileKeyValueStore Value!");
static_assert(util::is_pod<Value>::value && !std::is_pointer<Value>::value, "Invalid FileKeyValueStore Value!");
size_t size = 0;
R_TRY(this->Get(&size, out_value, sizeof(Value), key));
AMS_ABORT_UNLESS(size >= sizeof(Value));
@@ -103,13 +103,13 @@ namespace ams::kvdb {
template<typename Key>
Result Set(const Key &key, const void *value, size_t value_size) {
static_assert(std::is_pod<Key>::value && sizeof(Key) <= MaxKeySize, "Invalid FileKeyValueStore Key!");
static_assert(util::is_pod<Key>::value && sizeof(Key) <= MaxKeySize, "Invalid FileKeyValueStore Key!");
return this->Set(&key, sizeof(Key), value, value_size);
}
template<typename Key, typename Value>
Result Set(const Key &key, const Value &value) {
static_assert(std::is_pod<Value>::value && !std::is_pointer<Value>::value, "Invalid FileKeyValueStore Value!");
static_assert(util::is_pod<Value>::value && !std::is_pointer<Value>::value, "Invalid FileKeyValueStore Value!");
return this->Set(key, &value, sizeof(Value));
}

View File

@@ -26,7 +26,7 @@ namespace ams::kvdb {
template<class Key>
class MemoryKeyValueStore {
static_assert(std::is_pod<Key>::value, "KeyValueStore Keys must be pod!");
static_assert(util::is_pod<Key>::value, "KeyValueStore Keys must be pod!");
NON_COPYABLE(MemoryKeyValueStore);
NON_MOVEABLE(MemoryKeyValueStore);
public:
@@ -49,7 +49,7 @@ namespace ams::kvdb {
if constexpr (!std::is_same<Value, void>::value) {
AMS_ABORT_UNLESS(sizeof(Value) <= this->value_size);
/* Ensure we only get pod. */
static_assert(std::is_pod<Value>::value, "KeyValueStore Values must be pod");
static_assert(util::is_pod<Value>::value, "KeyValueStore Values must be pod");
}
return reinterpret_cast<Value *>(this->value);
}
@@ -60,7 +60,7 @@ namespace ams::kvdb {
if constexpr (!std::is_same<Value, void>::value) {
AMS_ABORT_UNLESS(sizeof(Value) <= this->value_size);
/* Ensure we only get pod. */
static_assert(std::is_pod<Value>::value, "KeyValueStore Values must be pod");
static_assert(util::is_pod<Value>::value, "KeyValueStore Values must be pod");
}
return reinterpret_cast<Value *>(this->value);
}
@@ -366,14 +366,14 @@ namespace ams::kvdb {
template<typename Value>
Result Set(const Key &key, const Value &value) {
/* Only allow setting pod. */
static_assert(std::is_pod<Value>::value, "KeyValueStore Values must be pod");
static_assert(util::is_pod<Value>::value, "KeyValueStore Values must be pod");
return this->Set(key, &value, sizeof(Value));
}
template<typename Value>
Result Set(const Key &key, const Value *value) {
/* Only allow setting pod. */
static_assert(std::is_pod<Value>::value, "KeyValueStore Values must be pod");
static_assert(util::is_pod<Value>::value, "KeyValueStore Values must be pod");
return this->Set(key, value, sizeof(Value));
}

View File

@@ -35,7 +35,7 @@ namespace ams::ldr {
u32 aci_fah_size;
u8 ac_buffer[0x3E0];
};
static_assert(std::is_pod<ProgramInfo>::value && sizeof(ProgramInfo) == 0x400, "ProgramInfo definition!");
static_assert(util::is_pod<ProgramInfo>::value && sizeof(ProgramInfo) == 0x400, "ProgramInfo definition!");
enum ProgramInfoFlag {
ProgramInfoFlag_SystemModule = (0 << 0),
@@ -71,7 +71,7 @@ namespace ams::ldr {
inline bool operator!=(const PinId &lhs, const PinId &rhs) {
return lhs.value != rhs.value;
}
static_assert(sizeof(PinId) == sizeof(u64) && std::is_pod<PinId>::value, "PinId definition!");
static_assert(sizeof(PinId) == sizeof(u64) && util::is_pod<PinId>::value, "PinId definition!");
/* Import ModuleInfo from libnx. */
using ModuleInfo = ::LoaderModuleInfo;
@@ -142,7 +142,7 @@ namespace ams::ldr {
};
};
};
static_assert(sizeof(NsoHeader) == 0x100 && std::is_pod<NsoHeader>::value, "NsoHeader definition!");
static_assert(sizeof(NsoHeader) == 0x100 && util::is_pod<NsoHeader>::value, "NsoHeader definition!");
/* NPDM types. */
struct Aci {
@@ -160,7 +160,7 @@ namespace ams::ldr {
u32 kac_size;
u8 reserved_38[0x8];
};
static_assert(sizeof(Aci) == 0x40 && std::is_pod<Aci>::value, "Aci definition!");
static_assert(sizeof(Aci) == 0x40 && util::is_pod<Aci>::value, "Aci definition!");
struct Acid {
static constexpr u32 Magic = util::FourCC<'A','C','I','D'>::Code;
@@ -199,7 +199,7 @@ namespace ams::ldr {
u32 kac_size;
u8 reserved_238[0x8];
};
static_assert(sizeof(Acid) == 0x240 && std::is_pod<Acid>::value, "Acid definition!");
static_assert(sizeof(Acid) == 0x240 && util::is_pod<Acid>::value, "Acid definition!");
struct Npdm {
static constexpr u32 Magic = util::FourCC<'M','E','T','A'>::Code;
@@ -239,6 +239,6 @@ namespace ams::ldr {
u32 acid_offset;
u32 acid_size;
};
static_assert(sizeof(Npdm) == 0x80 && std::is_pod<Npdm>::value, "Npdm definition!");
static_assert(sizeof(Npdm) == 0x80 && util::is_pod<Npdm>::value, "Npdm definition!");
}

View File

@@ -56,6 +56,6 @@ namespace ams::lr {
}
};
static_assert(std::is_pod<Path>::value && sizeof(Path) == fs::EntryNameLengthMax);
static_assert(util::is_pod<Path>::value && sizeof(Path) == fs::EntryNameLengthMax);
}

View File

@@ -65,6 +65,6 @@ namespace ams::mem::impl {
size_t alloc_size;
size_t hash;
};
static_assert(std::is_pod<HeapHash>::value);
static_assert(util::is_pod<HeapHash>::value);
}

View File

@@ -55,7 +55,7 @@ namespace ams::ncm {
}
};
static_assert(sizeof(std::is_pod<ContentInfo>::value));
static_assert(sizeof(util::is_pod<ContentInfo>::value));
static_assert(sizeof(ContentInfo) == 0x18);
}

View File

@@ -65,7 +65,7 @@ namespace ams::ncm {
u32 flags;
fs::SaveDataSpaceId space_id;
};
static_assert(std::is_pod<SystemSaveDataInfo>::value);
static_assert(util::is_pod<SystemSaveDataInfo>::value);
class ContentManagerImpl final : public IContentManager {
private:

View File

@@ -27,7 +27,7 @@ namespace ams::ncm {
return { .program_id = program_id, .storage_id = static_cast<u8>(storage_id), };
}
};
static_assert(sizeof(ProgramLocation) == 0x10 && std::is_pod<ProgramLocation>::value);
static_assert(sizeof(ProgramLocation) == 0x10 && util::is_pod<ProgramLocation>::value);
static_assert(sizeof(ProgramLocation) == sizeof(::NcmProgramLocation) && alignof(ProgramLocation) == alignof(::NcmProgramLocation), "ProgramLocation Libnx Compatibility");

View File

@@ -25,7 +25,7 @@ namespace ams::ncm {
u8 reserved[7];
};
static_assert(sizeof(RightsId) == 0x18);
static_assert(std::is_pod<RightsId>::value);
static_assert(util::is_pod<RightsId>::value);
inline bool operator==(const RightsId &lhs, const RightsId &rhs) {
return std::tie(lhs.id, lhs.key_generation) == std::tie(rhs.id, rhs.key_generation);

View File

@@ -36,7 +36,7 @@ namespace ams::os {
};
util::BitPack32 counter;
};
static_assert(std::is_pod<LockCount>::value);
static_assert(util::is_pod<LockCount>::value);
static_assert(std::is_trivial<LockCount>::value);
union {

View File

@@ -52,6 +52,6 @@ namespace ams::pgl {
};
}
};
static_assert(sizeof(ContentMetaInfo) == 0x10 && std::is_pod<ContentMetaInfo>::value);
static_assert(sizeof(ContentMetaInfo) == 0x10 && util::is_pod<ContentMetaInfo>::value);
}

View File

@@ -97,6 +97,6 @@ namespace ams::pm {
u32 event;
os::ProcessId process_id;
};
static_assert(sizeof(ProcessEventInfo) == 0x10 && std::is_pod<ProcessEventInfo>::value, "ProcessEventInfo definition!");
static_assert(sizeof(ProcessEventInfo) == 0x10 && util::is_pod<ProcessEventInfo>::value, "ProcessEventInfo definition!");
}

View File

@@ -36,7 +36,7 @@ namespace ams::reg {
}
inline void SetBits(volatile u32 *reg, u32 mask) {
*reg |= mask;
*reg = *reg | mask;
}
inline void SetBits(uintptr_t reg, u32 mask) {
@@ -44,7 +44,7 @@ namespace ams::reg {
}
inline void ClearBits(volatile u32 *reg, u32 mask) {
*reg &= ~mask;
*reg = *reg & ~mask;
}
inline void ClearBits(uintptr_t reg, u32 mask) {
@@ -52,7 +52,7 @@ namespace ams::reg {
}
inline void MaskBits(volatile u32 *reg, u32 mask) {
*reg &= mask;
*reg = *reg & mask;
}
inline void MaskBits(uintptr_t reg, u32 mask) {

View File

@@ -22,18 +22,18 @@ namespace ams::settings::factory {
u8 data[0x180];
};
static_assert(sizeof(EccP256DeviceCertificate) == 0x180);
static_assert(std::is_pod<EccP256DeviceCertificate>::value);
static_assert(util::is_pod<EccP256DeviceCertificate>::value);
struct EccB233DeviceCertificate {
u8 data[0x180];
};
static_assert(sizeof(EccB233DeviceCertificate) == 0x180);
static_assert(std::is_pod<EccB233DeviceCertificate>::value);
static_assert(util::is_pod<EccB233DeviceCertificate>::value);
struct Rsa2048DeviceCertificate {
u8 data[0x240];
};
static_assert(sizeof(Rsa2048DeviceCertificate) == 0x240);
static_assert(std::is_pod<Rsa2048DeviceCertificate>::value);
static_assert(util::is_pod<Rsa2048DeviceCertificate>::value);
}

View File

@@ -22,6 +22,6 @@ namespace ams::settings::factory {
char str[0x18];
};
static_assert(sizeof(SerialNumber) == 0x18);
static_assert(std::is_pod<SerialNumber>::value);
static_assert(util::is_pod<SerialNumber>::value);
}

View File

@@ -27,12 +27,12 @@ namespace ams::settings::fwdbg {
char value[util::AlignUp(SettingsNameLengthMax + 1, alignof(u64))];
};
static_assert(std::is_pod<SettingsName>::value && sizeof(SettingsName) > SettingsNameLengthMax);
static_assert(util::is_pod<SettingsName>::value && sizeof(SettingsName) > SettingsNameLengthMax);
struct SettingsItemKey : sf::LargeData {
char value[util::AlignUp(SettingsItemKeyLengthMax + 1, alignof(u64))];
};
static_assert(std::is_pod<SettingsItemKey>::value && sizeof(SettingsItemKey) > SettingsItemKeyLengthMax);
static_assert(util::is_pod<SettingsItemKey>::value && sizeof(SettingsItemKey) > SettingsItemKeyLengthMax);
}

View File

@@ -152,7 +152,7 @@ namespace ams::settings {
return impl::IsValidLanguageCode(lc, std::make_index_sequence<Language_Count>{});
}
static_assert(std::is_pod<LanguageCode>::value);
static_assert(util::is_pod<LanguageCode>::value);
static_assert(sizeof(LanguageCode) == sizeof(u64));
/* Not an official type, but convenient. */
@@ -193,7 +193,7 @@ namespace ams::settings {
}
};
static_assert(std::is_pod<FirmwareVersion>::value);
static_assert(util::is_pod<FirmwareVersion>::value);
static_assert(sizeof(FirmwareVersion) == sizeof(::SetSysFirmwareVersion));
constexpr inline bool operator==(const FirmwareVersion &lhs, const FirmwareVersion &rhs) {

View File

@@ -63,7 +63,7 @@ namespace ams::sf::cmif {
}
};
static_assert(std::is_pod<ServerMessageRuntimeMetadata>::value, "std::is_pod<ServerMessageRuntimeMetadata>::value");
static_assert(util::is_pod<ServerMessageRuntimeMetadata>::value, "util::is_pod<ServerMessageRuntimeMetadata>::value");
static_assert(sizeof(ServerMessageRuntimeMetadata) == sizeof(u64), "sizeof(ServerMessageRuntimeMetadata)");
class ServerMessageProcessor {

View File

@@ -61,7 +61,7 @@ namespace ams::sf::cmif {
return this->handler;
}
};
static_assert(std::is_pod<ServiceCommandMeta>::value && sizeof(ServiceCommandMeta) == 0x18, "sizeof(ServiceCommandMeta)");
static_assert(util::is_pod<ServiceCommandMeta>::value && sizeof(ServiceCommandMeta) == 0x18, "sizeof(ServiceCommandMeta)");
namespace impl {

View File

@@ -1042,7 +1042,7 @@ namespace ams::sf::impl {
};
constexpr Result GetCmifOutHeaderPointer(CmifOutHeader **out_header_ptr, cmif::PointerAndSize &out_raw_data) {
CmifOutHeader *header = reinterpret_cast<CmifOutHeader *>(out_raw_data.GetPointer());
CmifOutHeader *header = static_cast<CmifOutHeader *>(out_raw_data.GetPointer());
R_UNLESS(out_raw_data.GetSize() >= sizeof(*header), sf::cmif::ResultInvalidHeaderSize());
out_raw_data = cmif::PointerAndSize(out_raw_data.GetAddress() + sizeof(*header), out_raw_data.GetSize() - sizeof(*header));
*out_header_ptr = header;

View File

@@ -182,6 +182,9 @@ extern "C" {
/* Custom abort handler, so that std::abort will trigger these. */
void abort() {
static ams::os::Mutex abort_lock(true);
std::scoped_lock lk(abort_lock);
ams::AbortImpl();
__builtin_unreachable();
}

View File

@@ -23,6 +23,6 @@ namespace ams::capsrv::server {
};
static_assert(sizeof(DecoderWorkMemory) == SoftwareJpegDecoderWorkMemorySize);
static_assert(alignof(DecoderWorkMemory) == os::MemoryPageSize);
static_assert(std::is_pod<DecoderWorkMemory>::value);
static_assert(util::is_pod<DecoderWorkMemory>::value);
}

View File

@@ -23,7 +23,7 @@ namespace ams::fs::impl {
struct FilePathHash : public Newable {
u8 data[FilePathHashSize];
};
static_assert(std::is_pod<FilePathHash>::value);
static_assert(util::is_pod<FilePathHash>::value);
inline bool operator==(const FilePathHash &lhs, const FilePathHash &rhs) {
return std::memcmp(lhs.data, rhs.data, FilePathHashSize) == 0;

View File

@@ -21,6 +21,6 @@ namespace ams::fs {
struct MountName {
char str[MountNameLengthMax + 1];
};
static_assert(std::is_pod<MountName>::value);
static_assert(util::is_pod<MountName>::value);
}

View File

@@ -24,7 +24,7 @@ namespace ams::fssystem {
u32 name_table_size;
u32 reserved;
};
static_assert(std::is_pod<PartitionFileSystemMeta::PartitionFileSystemHeader>::value);
static_assert(util::is_pod<PartitionFileSystemMeta::PartitionFileSystemHeader>::value);
static_assert(sizeof(PartitionFileSystemMeta::PartitionFileSystemHeader) == 0x10);
template <typename Format>

View File

@@ -37,7 +37,7 @@ namespace ams::fssystem {
virtual ~RomFsFile() { /* ... */ }
public:
virtual Result ReadImpl(size_t *out, s64 offset, void *buffer, size_t size, const fs::ReadOption &option) override {
R_TRY(buffers::DoContinuouslyUntilBufferIsAllocated([=]() -> Result {
R_TRY(buffers::DoContinuouslyUntilBufferIsAllocated([=, this]() -> Result {
size_t read_size = 0;
R_TRY(this->DryRead(std::addressof(read_size), offset, size, option, fs::OpenMode_Read));
@@ -84,7 +84,7 @@ namespace ams::fssystem {
operate_size = this->GetSize() - offset;
}
R_TRY(buffers::DoContinuouslyUntilBufferIsAllocated([=]() -> Result {
R_TRY(buffers::DoContinuouslyUntilBufferIsAllocated([=, this]() -> Result {
R_TRY(this->parent->GetBaseStorage()->OperateRange(dst, dst_size, op_id, this->start + offset, operate_size, src, src_size));
return ResultSuccess();
}, AMS_CURRENT_FUNCTION_NAME));
@@ -113,7 +113,7 @@ namespace ams::fssystem {
virtual ~RomFsDirectory() override { /* ... */ }
public:
virtual Result ReadImpl(s64 *out_count, fs::DirectoryEntry *out_entries, s64 max_entries) {
R_TRY(buffers::DoContinuouslyUntilBufferIsAllocated([=]() -> Result {
R_TRY(buffers::DoContinuouslyUntilBufferIsAllocated([=, this]() -> Result {
return this->ReadImpl(out_count, std::addressof(this->current_find), out_entries, max_entries);
}, AMS_CURRENT_FUNCTION_NAME));
return ResultSuccess();
@@ -278,7 +278,7 @@ namespace ams::fssystem {
}
Result RomFsFileSystem::GetFileInfo(RomFileTable::FileInfo *out, const char *path) {
R_TRY(buffers::DoContinuouslyUntilBufferIsAllocated([=]() -> Result {
R_TRY(buffers::DoContinuouslyUntilBufferIsAllocated([=, this]() -> Result {
R_TRY_CATCH(this->rom_file_table.OpenFile(out, path)) {
R_CONVERT(fs::ResultDbmNotFound, fs::ResultPathNotFound());
} R_END_TRY_CATCH;
@@ -325,7 +325,7 @@ namespace ams::fssystem {
}
Result RomFsFileSystem::GetEntryTypeImpl(fs::DirectoryEntryType *out, const char *path) {
R_TRY(buffers::DoContinuouslyUntilBufferIsAllocated([=]() -> Result {
R_TRY(buffers::DoContinuouslyUntilBufferIsAllocated([=, this]() -> Result {
RomDirectoryInfo dir_info;
R_TRY_CATCH(this->rom_file_table.GetDirectoryInformation(std::addressof(dir_info), path)) {

View File

@@ -42,7 +42,7 @@ namespace ams::kvdb {
return header;
}
};
static_assert(sizeof(ArchiveHeader) == 0xC && std::is_pod<ArchiveHeader>::value, "ArchiveHeader definition!");
static_assert(sizeof(ArchiveHeader) == 0xC && util::is_pod<ArchiveHeader>::value, "ArchiveHeader definition!");
struct ArchiveEntryHeader {
u8 magic[sizeof(ArchiveEntryMagic)];
@@ -62,7 +62,7 @@ namespace ams::kvdb {
return header;
}
};
static_assert(sizeof(ArchiveEntryHeader) == 0xC && std::is_pod<ArchiveEntryHeader>::value, "ArchiveEntryHeader definition!");
static_assert(sizeof(ArchiveEntryHeader) == 0xC && util::is_pod<ArchiveEntryHeader>::value, "ArchiveEntryHeader definition!");
}

View File

@@ -160,7 +160,7 @@ namespace ams::mem::impl::heap {
template<typename T>
static ALWAYS_INLINE T *AlignUpPage(T *ptr) {
static_assert(std::is_pod<T>::value);
static_assert(util::is_pod<T>::value);
static_assert(util::IsAligned(PageSize, alignof(T)));
return reinterpret_cast<T *>(AlignUpPage(reinterpret_cast<uintptr_t>(ptr)));
}
@@ -171,7 +171,7 @@ namespace ams::mem::impl::heap {
template<typename T>
static ALWAYS_INLINE T *AlignDownPage(T *ptr) {
static_assert(std::is_pod<T>::value);
static_assert(util::is_pod<T>::value);
static_assert(util::IsAligned(PageSize, alignof(T)));
return reinterpret_cast<T *>(AlignDownPage(reinterpret_cast<uintptr_t>(ptr)));
}
@@ -182,7 +182,7 @@ namespace ams::mem::impl::heap {
template<typename T>
static ALWAYS_INLINE T *AlignUpPhysicalPage(T *ptr) {
static_assert(std::is_pod<T>::value);
static_assert(util::is_pod<T>::value);
static_assert(util::IsAligned(PhysicalPageSize, alignof(T)));
return reinterpret_cast<T *>(AlignUpPhysicalPage(reinterpret_cast<uintptr_t>(ptr)));
}
@@ -193,7 +193,7 @@ namespace ams::mem::impl::heap {
template<typename T>
static ALWAYS_INLINE T *AlignDownPhysicalPage(T *ptr) {
static_assert(std::is_pod<T>::value);
static_assert(util::is_pod<T>::value);
static_assert(util::IsAligned(PhysicalPageSize, alignof(T)));
return reinterpret_cast<T *>(AlignDownPhysicalPage(reinterpret_cast<uintptr_t>(ptr)));
}

View File

@@ -27,7 +27,7 @@ namespace ams::pgl::srv {
os::ProcessId process_id;
u32 flags;
};
static_assert(std::is_pod<ProcessData>::value);
static_assert(util::is_pod<ProcessData>::value);
enum ProcessDataFlag : u32 {
ProcessDataFlag_None = 0,

View File

@@ -70,7 +70,10 @@ static char* find_chars_or_comment(const char* s, const char* chars)
/* Version of strncpy that ensures dest (size bytes) is null-terminated. */
static char* strncpy0(char* dest, const char* src, size_t size)
{
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wstringop-truncation"
strncpy(dest, src, size - 1);
#pragma GCC diagnostic pop
dest[size - 1] = '\0';
return dest;
}

View File

@@ -35,9 +35,6 @@
#define CONST_FOLD(x) (__builtin_constant_p(x) ? (x) : (x))
#define WRAP_TEMPLATE_CONSTANT(...) ([] { using U = union { static constexpr auto GetValue() { return __VA_ARGS__; } }; return U{}; }())
#define UNWRAP_TEMPLATE_CONSTANT(tpnm) (tpnm::GetValue())
#define CONCATENATE_IMPL(s1, s2) s1##s2
#define CONCATENATE(s1, s2) CONCATENATE_IMPL(s1, s2)

View File

@@ -261,12 +261,11 @@ namespace ams::svc::codegen::impl {
/* TODO */
};
template<typename CodeGenerator, typename MetaCodeHolder>
static ALWAYS_INLINE void GenerateCodeForMetaCode(MetaCodeHolder) {
constexpr auto MetaCode = UNWRAP_TEMPLATE_CONSTANT(MetaCodeHolder);
template<typename CodeGenerator, auto MetaCode>
static ALWAYS_INLINE void GenerateCodeForMetaCode() {
constexpr size_t NumOperations = MetaCode.GetNumOperations();
static_assert(NumOperations <= 64);
#define SVC_CODEGEN_HANDLER(n) do { if constexpr (n < NumOperations) { constexpr auto Operation = MetaCode.GetOperation(n); GenerateCodeForOperation<CodeGenerator>(WRAP_TEMPLATE_CONSTANT(Operation)); } } while (0)
#define SVC_CODEGEN_HANDLER(n) do { if constexpr (n < NumOperations) { constexpr auto Operation = MetaCode.GetOperation(n); GenerateCodeForOperation<CodeGenerator, Operation>(); } } while (0)
SVC_CODEGEN_FOR_I_FROM_0_TO_64(SVC_CODEGEN_HANDLER)
#undef SVC_CODEGEN_HANDLER
}

View File

@@ -143,7 +143,7 @@ namespace ams::svc::codegen::impl {
template<size_t N>
class RegisterAllocator {
private:
public:
std::array<bool, N> map;
public:
constexpr explicit RegisterAllocator() : map() { /* ... */ }

View File

@@ -319,38 +319,43 @@ namespace ams::svc::codegen::impl {
template<typename... T>
struct TypeIndexFilter {
template<typename UseArrayHolder, typename HeadType, typename... TailType, size_t HeadIndex, size_t... TailIndex>
static constexpr auto GetFilteredTupleImpl(UseArrayHolder, std::tuple<HeadType, TailType...>, std::index_sequence<HeadIndex, TailIndex...>) {
constexpr auto UseArray = UNWRAP_TEMPLATE_CONSTANT(UseArrayHolder);
static_assert(sizeof...(TailType) == sizeof...(TailIndex));
static_assert(HeadIndex <= UseArray.size());
if constexpr (sizeof...(TailType) == 0) {
if constexpr (!UseArray[HeadIndex]) {
return std::tuple<HeadType>{};
} else {
return std::tuple<>{};
}
} else {
auto tail_tuple = GetFilteredTupleImpl(UseArrayHolder{}, std::tuple<TailType...>{}, std::index_sequence<TailIndex...>{});
if constexpr (!UseArray[HeadIndex]) {
return std::tuple_cat(std::tuple<HeadType>{}, tail_tuple);
} else {
return std::tuple_cat(std::tuple<>{}, tail_tuple);
}
}
}
template<auto UseArray, typename X, typename Y>
struct Helper;
template<typename UseArrayHolder>
static constexpr auto GetFilteredTuple(UseArrayHolder) {
return GetFilteredTupleImpl(UseArrayHolder{}, std::tuple<T...>{}, std::make_index_sequence<sizeof...(T)>());
}
template<auto UseArray, size_t...Index>
struct Helper<UseArray, std::tuple<>, std::index_sequence<Index...>> {
using Type = std::tuple<>;
};
template<auto UseArray, typename HeadType, typename... TailType, size_t HeadIndex, size_t... TailIndex>
struct Helper<UseArray, std::tuple<HeadType, TailType...>, std::index_sequence<HeadIndex, TailIndex...>> {
using LastHeadType = std::tuple<HeadType>;
using LastNullType = std::tuple<>;
using LastType = typename std::conditional<!UseArray[HeadIndex], LastHeadType, LastNullType>::type;
using NextTailType = std::tuple<TailType...>;
using NextTailSequence = std::index_sequence<TailIndex...>;
using NextType = typename std::conditional<!UseArray[HeadIndex],
decltype(std::tuple_cat(std::declval<LastHeadType>(), std::declval<typename Helper<UseArray, NextTailType, NextTailSequence>::Type>())),
decltype(std::tuple_cat(std::declval<LastNullType>(), std::declval<typename Helper<UseArray, NextTailType, NextTailSequence>::Type>()))
>::type;
using Type = typename std::conditional<sizeof...(TailType) == 0, LastType, NextType>::type;
};
template<auto UseArray>
using FilteredTupleType = typename Helper<UseArray, std::tuple<T...>, decltype(std::make_index_sequence<sizeof...(T)>())>::Type;
};
template<typename AllocatorHolder, typename FirstOperation, typename...OtherOperations>
static constexpr auto GetModifiedOperations(AllocatorHolder, std::tuple<FirstOperation, OtherOperations...> ops) {
template<auto Allocator, typename FirstOperation, typename...OtherOperations>
static constexpr auto GetModifiedOperations(std::tuple<FirstOperation, OtherOperations...> ops) {
constexpr size_t ModifyRegister = [] {
auto allocator = UNWRAP_TEMPLATE_CONSTANT(AllocatorHolder);
auto allocator = Allocator;
return allocator.AllocateFirstFree();
}();
@@ -359,13 +364,13 @@ namespace ams::svc::codegen::impl {
return std::tuple<ModifiedFirstOperation, OtherOperations..., NewMoveOperation>{};
}
template<typename Conversion, typename AllocatorHolder, typename FirstOperation, typename... OtherOperations>
static constexpr auto GenerateBeforeOperations(MetaCodeGenerator &mcg, AllocatorHolder, std::tuple<FirstOperation, OtherOperations...> ops) -> RegisterAllocator<UNWRAP_TEMPLATE_CONSTANT(AllocatorHolder).GetRegisterCount()> {
template<typename Conversion, auto Allocator, typename FirstOperation, typename... OtherOperations>
static constexpr auto GenerateBeforeOperations(MetaCodeGenerator &mcg, std::tuple<FirstOperation, OtherOperations...> ops) -> RegisterAllocator<Allocator.GetRegisterCount()> {
constexpr size_t NumOperations = 1 + sizeof...(OtherOperations);
using OperationsTuple = decltype(ops);
using FilterHelper = TypeIndexFilter<FirstOperation, OtherOperations...>;
constexpr auto ProcessOperation = []<typename Operation>(MetaCodeGenerator &pr_mcg, auto &allocator, Operation) {
constexpr auto ProcessOperation = []<typename Operation>(MetaCodeGenerator &pr_mcg, auto &allocator) {
if (Conversion::template CanGenerateCode<Operation, CodeGenerationKind::SvcInvocationToKernelProcedure>(allocator)) {
Conversion::template GenerateCode<Operation, CodeGenerationKind::SvcInvocationToKernelProcedure>(pr_mcg, allocator);
return true;
@@ -373,12 +378,12 @@ namespace ams::svc::codegen::impl {
return false;
};
constexpr auto ProcessResults = [ProcessOperation]<typename... Operations>(std::tuple<Operations...>) {
auto allocator = UNWRAP_TEMPLATE_CONSTANT(AllocatorHolder);
constexpr auto ProcessResults = []<auto AllocatorVal, auto ProcessOp, typename... Operations>(std::tuple<Operations...>) {
auto allocator = AllocatorVal;
MetaCodeGenerator pr_mcg;
auto use_array = std::array<bool, NumOperations>{ ProcessOperation(pr_mcg, allocator, Operations{})... };
auto use_array = std::array<bool, NumOperations>{ ProcessOp.template operator()<Operations>(pr_mcg, allocator)... };
return std::make_tuple(use_array, allocator, pr_mcg);
}(OperationsTuple{});
}.template operator()<Allocator, ProcessOperation>(OperationsTuple{});
constexpr auto CanGenerate = std::get<0>(ProcessResults);
constexpr auto AfterAllocator = std::get<1>(ProcessResults);
@@ -388,15 +393,15 @@ namespace ams::svc::codegen::impl {
mcg.AddOperationDirectly(GeneratedCode.GetOperation(i));
}
constexpr auto FilteredOperations = FilterHelper::template GetFilteredTuple(WRAP_TEMPLATE_CONSTANT(CanGenerate));
static_assert(std::tuple_size<decltype(FilteredOperations)>::value <= NumOperations);
if constexpr (std::tuple_size<decltype(FilteredOperations)>::value > 0) {
if constexpr (std::tuple_size<decltype(FilteredOperations)>::value != NumOperations) {
return GenerateBeforeOperations<Conversion>(mcg, WRAP_TEMPLATE_CONSTANT(AfterAllocator), FilteredOperations);
using FilteredOperations = typename FilterHelper::FilteredTupleType<CanGenerate>;
static_assert(std::tuple_size<FilteredOperations>::value <= NumOperations);
if constexpr (std::tuple_size<FilteredOperations>::value > 0) {
if constexpr (std::tuple_size<FilteredOperations>::value != NumOperations) {
return GenerateBeforeOperations<Conversion, AfterAllocator>(mcg, FilteredOperations{});
} else {
/* No progress was made, so we need to make a change. */
constexpr auto ModifiedOperations = GetModifiedOperations(WRAP_TEMPLATE_CONSTANT(AfterAllocator), FilteredOperations);
return GenerateBeforeOperations<Conversion>(mcg, WRAP_TEMPLATE_CONSTANT(AfterAllocator), ModifiedOperations);
constexpr auto ModifiedOperations = GetModifiedOperations<AfterAllocator>(FilteredOperations{});
return GenerateBeforeOperations<Conversion, AfterAllocator>(mcg, ModifiedOperations);
}
} else {
return AfterAllocator;
@@ -433,7 +438,7 @@ namespace ams::svc::codegen::impl {
/* Generate code for before operations. */
if constexpr (Conversion::NumBeforeOperations > 0) {
allocator = GenerateBeforeOperations<Conversion>(mcg, WRAP_TEMPLATE_CONSTANT(InitialAllocator), typename Conversion::BeforeOperations{});
allocator = GenerateBeforeOperations<Conversion, InitialAllocator>(mcg, typename Conversion::BeforeOperations{});
} else {
allocator = InitialAllocator;
}
@@ -527,8 +532,8 @@ namespace ams::svc::codegen::impl {
static ALWAYS_INLINE void WrapSvcFunction() {
/* Generate appropriate assembly. */
GenerateCodeForMetaCode<CodeGenerator>(WRAP_TEMPLATE_CONSTANT(BeforeMetaCode));
ON_SCOPE_EXIT { GenerateCodeForMetaCode<CodeGenerator>(WRAP_TEMPLATE_CONSTANT(AfterMetaCode)); };
GenerateCodeForMetaCode<CodeGenerator, BeforeMetaCode>();
ON_SCOPE_EXIT { GenerateCodeForMetaCode<CodeGenerator, AfterMetaCode>(); };
return reinterpret_cast<void (*)()>(Function)();
}

View File

@@ -24,7 +24,7 @@ namespace ams::svc::codegen::impl {
static constexpr size_t MaxParameters = 8;
private:
static constexpr size_t InvalidIndex = std::numeric_limits<size_t>::max();
private:
public:
/* ABI parameters. */
Abi abi;
@@ -102,7 +102,7 @@ namespace ams::svc::codegen::impl {
};
class ProcedureLayout {
private:
public:
Abi abi;
ParameterLayout input;
ParameterLayout output;
@@ -205,7 +205,7 @@ namespace ams::svc::codegen::impl {
};
class SvcInvocationLayout {
private:
public:
Abi abi;
ParameterLayout input;
ParameterLayout output;

View File

@@ -304,9 +304,8 @@ namespace ams::svc::codegen::impl {
static constexpr auto DetermineConversionOperations() {
[[maybe_unused]] constexpr auto Procedure = LayoutForKernel;
[[maybe_unused]] constexpr ParameterLayout Svc = Input ? LayoutForSvc.GetInputLayout() : LayoutForSvc.GetOutputLayout();
[[maybe_unused]] constexpr std::array<size_t, Svc.GetNumParameters()> ParameterMap = []<typename SvcHolder>(SvcHolder){
[[maybe_unused]] constexpr std::array<size_t, Svc.GetNumParameters()> ParameterMap = []<auto CapturedSvc>(){
/* We want to iterate over the parameters in sorted order. */
constexpr ParameterLayout CapturedSvc = UNWRAP_TEMPLATE_CONSTANT(SvcHolder);
std::array<size_t, CapturedSvc.GetNumParameters()> map{};
const size_t num_parameters = CapturedSvc.GetNumParameters();
for (size_t i = 0; i < num_parameters; i++) {
@@ -322,7 +321,7 @@ namespace ams::svc::codegen::impl {
}
}
return map;
}(WRAP_TEMPLATE_CONSTANT(Svc));
}.template operator()<Svc>();
if constexpr (ParameterIndex >= Svc.GetNumParameters()) {
/* Base case: we're done. */
@@ -378,15 +377,13 @@ namespace ams::svc::codegen::impl {
constexpr size_t PassedSize = ProcedureParam.GetTypeSize();
/* TODO: C++20 templated lambdas. For now, use GCC extension syntax. */
constexpr auto SvcIndexSequence = []<typename SvcParamWrapper, size_t... Is>(SvcParamWrapper, std::index_sequence<Is...>) {
constexpr Parameter CapturedSvcParam = UNWRAP_TEMPLATE_CONSTANT(SvcParamWrapper);
constexpr auto SvcIndexSequence = []<auto CapturedSvcParam, size_t... Is>(std::index_sequence<Is...>) {
return std::index_sequence<CapturedSvcParam.GetLocation(Is).GetIndex()...>{};
}(WRAP_TEMPLATE_CONSTANT(SvcParam), std::make_index_sequence<SvcParam.GetNumLocations()>());
}.template operator()<SvcParam>(std::make_index_sequence<SvcParam.GetNumLocations()>());
constexpr auto OperationValue = []<typename ProcedureLocWrapper, size_t... Is>(ProcedureLocWrapper, std::index_sequence<Is...>) {
constexpr Location CapturedProcedureLoc = UNWRAP_TEMPLATE_CONSTANT(ProcedureLocWrapper);
constexpr auto OperationValue = []<auto CapturedProcedureLoc, size_t... Is>(std::index_sequence<Is...>) {
return LayoutConversionBase::OperationScatter<RegisterSize, PassedSize, StackIndex * KernelAbiType::RegisterSize, CapturedProcedureLoc.GetIndex(), Is...>{};
}(WRAP_TEMPLATE_CONSTANT(ProcedureLoc), SvcIndexSequence);
}.template operator()<ProcedureLoc>(SvcIndexSequence);
constexpr auto cur_op = std::make_tuple(OperationValue);

View File

@@ -79,7 +79,7 @@ namespace ams::svc::codegen::impl {
return op;
}
private:
public:
size_t num_operations;
std::array<Operation, MaxOperations> operations;
public:
@@ -98,15 +98,13 @@ namespace ams::svc::codegen::impl {
}
};
template<typename _OperationHolder>
template<auto Operation>
static constexpr auto GetOperationParameterSequence() {
constexpr auto _Operation = UNWRAP_TEMPLATE_CONSTANT(_OperationHolder);
constexpr size_t NumParameters = _Operation.num_parameters;
constexpr size_t NumParameters = Operation.num_parameters;
return []<typename OperationHolder, size_t... Is>(OperationHolder, std::index_sequence<Is...>) {
constexpr auto Operation = UNWRAP_TEMPLATE_CONSTANT(OperationHolder);
return []<size_t... Is>(std::index_sequence<Is...>) {
return std::index_sequence<Operation.parameters[Is]...>{};
}(_OperationHolder{}, std::make_index_sequence<NumParameters>());
}(std::make_index_sequence<NumParameters>());
}
template<typename CodeGenerator, MetaCode::OperationKind Kind, size_t... Parameters>
@@ -130,10 +128,9 @@ namespace ams::svc::codegen::impl {
#undef META_CODE_OPERATION_KIND_GENERATE_CODE
}
template<typename CodeGenerator, typename OperationHolder>
static ALWAYS_INLINE void GenerateCodeForOperation(OperationHolder) {
constexpr auto Operation = UNWRAP_TEMPLATE_CONSTANT(OperationHolder);
GenerateCodeForOperationImpl<CodeGenerator, Operation.kind>(GetOperationParameterSequence<OperationHolder>());
template<typename CodeGenerator, auto Operation>
static ALWAYS_INLINE void GenerateCodeForOperation() {
GenerateCodeForOperationImpl<CodeGenerator, Operation.kind>(GetOperationParameterSequence<Operation>());
}
class MetaCodeGenerator {

View File

@@ -27,7 +27,7 @@ namespace ams::svc::codegen::impl {
class Location {
private:
static constexpr size_t InvalidIndex = std::numeric_limits<size_t>::max();
private:
public:
Storage storage;
size_t index;
public:
@@ -75,7 +75,7 @@ namespace ams::svc::codegen::impl {
static constexpr size_t MaxLocations = 8;
static constexpr size_t IdentifierLengthMax = 0x40;
class Identifier {
private:
public:
char name[IdentifierLengthMax];
size_t index;
public:
@@ -99,7 +99,7 @@ namespace ams::svc::codegen::impl {
return !(*this == rhs);
}
};
private:
public:
Identifier identifier;
ArgumentType type;
size_t type_size;

View File

@@ -58,11 +58,11 @@ namespace ams::svc::ipc {
private:
util::BitPack32 header[2];
public:
constexpr ALWAYS_INLINE MessageHeader() : header({util::BitPack32{0}, util::BitPack32{0}}) {
constexpr ALWAYS_INLINE MessageHeader() : header{util::BitPack32{0}, util::BitPack32{0}} {
this->header[0].Set<Tag>(NullTag);
}
constexpr ALWAYS_INLINE MessageHeader(u16 tag, bool special, s32 ptr, s32 send, s32 recv, s32 exch, s32 raw, s32 recv_list) : header({util::BitPack32{0}, util::BitPack32{0}}) {
constexpr ALWAYS_INLINE MessageHeader(u16 tag, bool special, s32 ptr, s32 send, s32 recv, s32 exch, s32 raw, s32 recv_list) : header{util::BitPack32{0}, util::BitPack32{0}} {
this->header[0].Set<Tag>(tag);
this->header[0].Set<PointerCount>(ptr);
this->header[0].Set<SendCount>(send);
@@ -74,11 +74,11 @@ namespace ams::svc::ipc {
this->header[1].Set<HasSpecialHeader>(special);
}
ALWAYS_INLINE explicit MessageHeader(const MessageBuffer &buf) : header({util::BitPack32{0}, util::BitPack32{0}}) {
ALWAYS_INLINE explicit MessageHeader(const MessageBuffer &buf) : header{util::BitPack32{0}, util::BitPack32{0}} {
buf.Get(0, this->header, util::size(this->header));
}
ALWAYS_INLINE explicit MessageHeader(const u32 *msg) : header({util::BitPack32{msg[0]}, util::BitPack32{msg[1]}}) { /* ... */ }
ALWAYS_INLINE explicit MessageHeader(const u32 *msg) : header{util::BitPack32{msg[0]}, util::BitPack32{msg[1]}} { /* ... */ }
constexpr ALWAYS_INLINE u16 GetTag() const {
return this->header[0].Get<Tag>();
@@ -219,9 +219,9 @@ namespace ams::svc::ipc {
private:
util::BitPack32 data[3];
public:
constexpr ALWAYS_INLINE MapAliasDescriptor() : data({util::BitPack32{0}, util::BitPack32{0}, util::BitPack32{0}}) { /* ... */ }
constexpr ALWAYS_INLINE MapAliasDescriptor() : data{util::BitPack32{0}, util::BitPack32{0}, util::BitPack32{0}} { /* ... */ }
ALWAYS_INLINE MapAliasDescriptor(const void *buffer, size_t _size, Attribute attr = Attribute_Ipc) : data({util::BitPack32{0}, util::BitPack32{0}, util::BitPack32{0}}) {
ALWAYS_INLINE MapAliasDescriptor(const void *buffer, size_t _size, Attribute attr = Attribute_Ipc) : data{util::BitPack32{0}, util::BitPack32{0}, util::BitPack32{0}} {
const u64 address = reinterpret_cast<u64>(buffer);
const u64 size = static_cast<u64>(_size);
this->data[0] = { static_cast<u32>(size) };
@@ -233,7 +233,7 @@ namespace ams::svc::ipc {
this->data[2].Set<AddressHigh>(GetAddressHigh(address));
}
ALWAYS_INLINE MapAliasDescriptor(const MessageBuffer &buf, s32 index) : data({util::BitPack32{0}, util::BitPack32{0}, util::BitPack32{0}}) {
ALWAYS_INLINE MapAliasDescriptor(const MessageBuffer &buf, s32 index) : data{util::BitPack32{0}, util::BitPack32{0}, util::BitPack32{0}} {
buf.Get(index, this->data, util::size(this->data));
}
@@ -283,9 +283,9 @@ namespace ams::svc::ipc {
private:
util::BitPack32 data[2];
public:
constexpr ALWAYS_INLINE PointerDescriptor() : data({util::BitPack32{0}, util::BitPack32{0}}) { /* ... */ }
constexpr ALWAYS_INLINE PointerDescriptor() : data{util::BitPack32{0}, util::BitPack32{0}} { /* ... */ }
ALWAYS_INLINE PointerDescriptor(const void *buffer, size_t size, s32 index) : data({util::BitPack32{0}, util::BitPack32{0}}) {
ALWAYS_INLINE PointerDescriptor(const void *buffer, size_t size, s32 index) : data{util::BitPack32{0}, util::BitPack32{0}} {
const u64 address = reinterpret_cast<u64>(buffer);
this->data[0].Set<Index>(index);
@@ -296,7 +296,7 @@ namespace ams::svc::ipc {
this->data[1] = { static_cast<u32>(address) };
}
ALWAYS_INLINE PointerDescriptor(const MessageBuffer &buf, s32 index) : data({util::BitPack32{0}, util::BitPack32{0}}) {
ALWAYS_INLINE PointerDescriptor(const MessageBuffer &buf, s32 index) : data{util::BitPack32{0}, util::BitPack32{0}} {
buf.Get(index, this->data, util::size(this->data));
}
@@ -338,9 +338,9 @@ namespace ams::svc::ipc {
private:
util::BitPack32 data[2];
public:
constexpr ALWAYS_INLINE ReceiveListEntry() : data({util::BitPack32{0}, util::BitPack32{0}}) { /* ... */ }
constexpr ALWAYS_INLINE ReceiveListEntry() : data{util::BitPack32{0}, util::BitPack32{0}} { /* ... */ }
ALWAYS_INLINE ReceiveListEntry(const void *buffer, size_t size) : data({util::BitPack32{0}, util::BitPack32{0}}) {
ALWAYS_INLINE ReceiveListEntry(const void *buffer, size_t size) : data{util::BitPack32{0}, util::BitPack32{0}} {
const u64 address = reinterpret_cast<u64>(buffer);
this->data[0] = { static_cast<u32>(address) };
@@ -349,7 +349,7 @@ namespace ams::svc::ipc {
this->data[1].Set<Size>(size);
}
ALWAYS_INLINE ReceiveListEntry(u32 a, u32 b) : data({util::BitPack32{a}, util::BitPack32{b}}) { /* ... */ }
ALWAYS_INLINE ReceiveListEntry(u32 a, u32 b) : data{util::BitPack32{a}, util::BitPack32{b}} { /* ... */ }
constexpr ALWAYS_INLINE uintptr_t GetAddress() {
const u64 address = (static_cast<u64>(this->data[1].Get<AddressHigh>()) << AddressLow::Count) | this->data[0].Get<AddressLow>();

View File

@@ -18,6 +18,7 @@
#include <vapours/common.hpp>
#include <vapours/assert.hpp>
#include <vapours/util/util_type_traits.hpp>
#include <vapours/util/util_alignment.hpp>
#include <vapours/util/util_size.hpp>
#include <vapours/util/util_endian.hpp>

View File

@@ -50,7 +50,7 @@ namespace ams::util {
static constexpr size_t Next = Index + Count;
using BitPackType = BitPack<IntegralStorageType>;
static_assert(std::is_pod<BitPackType>::value);
static_assert(util::is_pod<BitPackType>::value);
static_assert(Mask<Index, Count> != 0);
static_assert(std::is_integral<T>::value || std::is_enum<T>::value);
@@ -84,10 +84,10 @@ namespace ams::util {
using BitPack32 = impl::BitPack<u32>;
using BitPack64 = impl::BitPack<u64>;
static_assert(std::is_pod<BitPack8>::value);
static_assert(std::is_pod<BitPack16>::value);
static_assert(std::is_pod<BitPack32>::value);
static_assert(std::is_pod<BitPack64>::value);
static_assert(util::is_pod<BitPack8>::value);
static_assert(util::is_pod<BitPack16>::value);
static_assert(util::is_pod<BitPack32>::value);
static_assert(util::is_pod<BitPack64>::value);
static_assert(std::is_trivially_destructible<BitPack8 >::value);
static_assert(std::is_trivially_destructible<BitPack16>::value);
static_assert(std::is_trivially_destructible<BitPack32>::value);

View File

@@ -0,0 +1,26 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <vapours/common.hpp>
#include <vapours/assert.hpp>
namespace ams::util {
template<typename T>
using is_pod = std::bool_constant<std::is_standard_layout<T>::value && std::is_trivial<T>::value>;
}