Merge branch 'master' into npdmfixup

This commit is contained in:
SciresM
2018-10-31 18:02:07 +09:00
committed by GitHub
235 changed files with 6301 additions and 9851 deletions

View File

@@ -1,4 +1,4 @@
KIPS := loader pm sm boot fs_mitm creport
KIPS := loader pm sm boot fs_mitm set_mitm creport
#TODO: boot2 ?

View File

@@ -21,7 +21,7 @@ TARGET := $(notdir $(CURDIR))
BUILD := build
SOURCES := source
DATA := data
INCLUDES := include
INCLUDES := include ../../common/include
EXEFS_SRC := exefs_src
DEFINES := -DDISABLE_IPC

View File

@@ -83,6 +83,8 @@ void __appInit(void) {
fatalSimple(0xCAFE << 4 | 2);
fsdevMountSdmc();
CheckAtmosphereVersion();
}
void __appExit(void) {

View File

@@ -21,7 +21,7 @@ TARGET := $(notdir $(CURDIR))
BUILD := build
SOURCES := source
DATA := data
INCLUDES := include
INCLUDES := include ../../common/include
EXEFS_SRC := exefs_src
DEFINES := -DDISABLE_IPC

View File

@@ -21,7 +21,7 @@ TARGET := $(notdir $(CURDIR))
BUILD := build
SOURCES := source
DATA := data
INCLUDES := include
INCLUDES := include ../../common/include
EXEFS_SRC := exefs_src
DEFINES := -DDISABLE_IPC

View File

@@ -13,63 +13,64 @@
{
"type": "syscalls",
"value": {
"svcSetHeapSize": "0x01",
"svcSetMemoryPermission": "0x02",
"svcSetMemoryAttribute": "0x03",
"svcMapMemory": "0x04",
"svcUnmapMemory": "0x05",
"svcQueryMemory": "0x06",
"svcExitProcess": "0x07",
"svcCreateThread": "0x08",
"svcStartThread": "0x09",
"svcExitThread": "0x0a",
"svcSleepThread": "0x0b",
"svcGetThreadPriority": "0x0c",
"svcSetThreadPriority": "0x0d",
"svcGetThreadCoreMask": "0x0e",
"svcSetThreadCoreMask": "0x0f",
"svcGetCurrentProcessorNumber": "0x10",
"svcSignalEvent": "0x11",
"svcClearEvent": "0x12",
"svcMapSharedMemory": "0x13",
"svcUnmapSharedMemory": "0x14",
"svcCreateTransferMemory": "0x15",
"svcCloseHandle": "0x16",
"svcResetSignal": "0x17",
"svcWaitSynchronization": "0x18",
"svcCancelSynchronization": "0x19",
"svcArbitrateLock": "0x1a",
"svcArbitrateUnlock": "0x1b",
"svcWaitProcessWideKeyAtomic": "0x1c",
"svcSignalProcessWideKey": "0x1d",
"svcGetSystemTick": "0x1e",
"svcConnectToNamedPort": "0x1f",
"svcSendSyncRequestLight": "0x20",
"svcSendSyncRequest": "0x21",
"svcSendSyncRequestWithUserBuffer": "0x22",
"svcSendAsyncRequestWithUserBuffer": "0x23",
"svcGetProcessId": "0x24",
"svcGetThreadId": "0x25",
"svcBreak": "0x26",
"svcOutputDebugString": "0x27",
"svcReturnFromException": "0x28",
"svcGetInfo": "0x29",
"svcWaitForAddress": "0x34",
"svcSignalToAddress": "0x35",
"svcCreateSession": "0x40",
"svcAcceptSession": "0x41",
"svcReplyAndReceiveLight": "0x42",
"svcReplyAndReceive": "0x43",
"svcReplyAndReceiveWithUserBuffer": "0x44",
"svcCreateEvent": "0x45",
"svcCreateInterruptEvent": "0x53",
"svcQueryIoMapping": "0x55",
"svcCreateDeviceAddressSpace": "0x56",
"svcAttachDeviceAddressSpace": "0x57",
"svcDetachDeviceAddressSpace": "0x58",
"svcMapDeviceAddressSpaceAligned": "0x5a",
"svcUnmapDeviceAddressSpace": "0x5c",
"svcGetSystemInfo": "0x6f"
"svcSetHeapSize": "0x01",
"svcSetMemoryPermission": "0x02",
"svcSetMemoryAttribute": "0x03",
"svcMapMemory": "0x04",
"svcUnmapMemory": "0x05",
"svcQueryMemory": "0x06",
"svcExitProcess": "0x07",
"svcCreateThread": "0x08",
"svcStartThread": "0x09",
"svcExitThread": "0x0a",
"svcSleepThread": "0x0b",
"svcGetThreadPriority": "0x0c",
"svcSetThreadPriority": "0x0d",
"svcGetThreadCoreMask": "0x0e",
"svcSetThreadCoreMask": "0x0f",
"svcGetCurrentProcessorNumber": "0x10",
"svcSignalEvent": "0x11",
"svcClearEvent": "0x12",
"svcMapSharedMemory": "0x13",
"svcUnmapSharedMemory": "0x14",
"svcCreateTransferMemory": "0x15",
"svcCloseHandle": "0x16",
"svcResetSignal": "0x17",
"svcWaitSynchronization": "0x18",
"svcCancelSynchronization": "0x19",
"svcArbitrateLock": "0x1a",
"svcArbitrateUnlock": "0x1b",
"svcWaitProcessWideKeyAtomic": "0x1c",
"svcSignalProcessWideKey": "0x1d",
"svcGetSystemTick": "0x1e",
"svcConnectToNamedPort": "0x1f",
"svcSendSyncRequestLight": "0x20",
"svcSendSyncRequest": "0x21",
"svcSendSyncRequestWithUserBuffer": "0x22",
"svcSendAsyncRequestWithUserBuffer": "0x23",
"svcGetProcessId": "0x24",
"svcGetThreadId": "0x25",
"svcBreak": "0x26",
"svcOutputDebugString": "0x27",
"svcReturnFromException": "0x28",
"svcGetInfo": "0x29",
"svcWaitForAddress": "0x34",
"svcSignalToAddress": "0x35",
"svcCreateSession": "0x40",
"svcAcceptSession": "0x41",
"svcReplyAndReceiveLight": "0x42",
"svcReplyAndReceive": "0x43",
"svcReplyAndReceiveWithUserBuffer": "0x44",
"svcCreateEvent": "0x45",
"svcCreateInterruptEvent": "0x53",
"svcReadWriteRegister": "0x4E",
"svcQueryIoMapping": "0x55",
"svcCreateDeviceAddressSpace": "0x56",
"svcAttachDeviceAddressSpace": "0x57",
"svcDetachDeviceAddressSpace": "0x58",
"svcMapDeviceAddressSpaceAligned": "0x5a",
"svcUnmapDeviceAddressSpace": "0x5c",
"svcGetSystemInfo": "0x6f"
}
}
]

View File

@@ -24,7 +24,5 @@ void Reboot() {
}
void Log(const void *data, int size) {
(void)(data);
(void)(size);
/* ... */
}

View File

@@ -21,21 +21,19 @@
#include "debug.hpp"
enum class FsIStorageCmd {
Read = 0,
Write = 1,
Flush = 2,
SetSize = 3,
GetSize = 4,
OperateRange = 5,
enum FsIStorageCmd : u32 {
FsIStorageCmd_Read = 0,
FsIStorageCmd_Write = 1,
FsIStorageCmd_Flush = 2,
FsIStorageCmd_SetSize = 3,
FsIStorageCmd_GetSize = 4,
FsIStorageCmd_OperateRange = 5,
};
class IStorage {
public:
virtual ~IStorage();
virtual IStorage *Clone() = 0;
virtual Result Read(void *buffer, size_t size, u64 offset) = 0;
virtual Result Write(void *buffer, size_t size, u64 offset) = 0;
virtual Result Flush() = 0;
@@ -51,88 +49,59 @@ class IStorageInterface : public IServiceObject {
IStorageInterface(IStorage *s) : base_storage(s) {
/* ... */
};
IStorageInterface *clone() override {
return new IStorageInterface(this->base_storage->Clone());
}
~IStorageInterface() {
delete base_storage;
};
Result dispatch(IpcParsedCommand &r, IpcCommand &out_c, u64 cmd_id, u8 *pointer_buffer, size_t pointer_buffer_size) final {
Result rc = 0xF601;
switch ((FsIStorageCmd)cmd_id) {
case FsIStorageCmd::Read:
rc = WrapIpcCommandImpl<&IStorageInterface::read>(this, r, out_c, pointer_buffer, pointer_buffer_size);
break;
case FsIStorageCmd::Write:
rc = WrapIpcCommandImpl<&IStorageInterface::write>(this, r, out_c, pointer_buffer, pointer_buffer_size);
break;
case FsIStorageCmd::Flush:
rc = WrapIpcCommandImpl<&IStorageInterface::flush>(this, r, out_c, pointer_buffer, pointer_buffer_size);
break;
case FsIStorageCmd::SetSize:
rc = WrapIpcCommandImpl<&IStorageInterface::set_size>(this, r, out_c, pointer_buffer, pointer_buffer_size);
break;
case FsIStorageCmd::GetSize:
rc = WrapIpcCommandImpl<&IStorageInterface::get_size>(this, r, out_c, pointer_buffer, pointer_buffer_size);
break;
case FsIStorageCmd::OperateRange:
if (kernelAbove400()) {
rc = WrapIpcCommandImpl<&IStorageInterface::operate_range>(this, r, out_c, pointer_buffer, pointer_buffer_size);
}
break;
default:
break;
}
return rc;
};
Result handle_deferred() final {
/* TODO: Panic, we can never defer. */
return 0;
};
private:
/* Actual command API. */
virtual std::tuple<Result> read(OutBuffer<u8, BufferType_Type1> buffer, u64 offset, u64 size) final {
return {this->base_storage->Read(buffer.buffer, std::min(buffer.num_elements, size), offset)};
virtual Result Read(OutBuffer<u8, BufferType_Type1> buffer, u64 offset, u64 size) final {
return this->base_storage->Read(buffer.buffer, std::min(buffer.num_elements, size), offset);
};
virtual std::tuple<Result> write(InBuffer<u8, BufferType_Type1> buffer, u64 offset, u64 size) final {
return {this->base_storage->Write(buffer.buffer, std::min(buffer.num_elements, size), offset)};
virtual Result Write(InBuffer<u8, BufferType_Type1> buffer, u64 offset, u64 size) final {
return this->base_storage->Write(buffer.buffer, std::min(buffer.num_elements, size), offset);
};
virtual std::tuple<Result> flush() final {
return {this->base_storage->Flush()};
virtual Result Flush() final {
return this->base_storage->Flush();
};
virtual std::tuple<Result> set_size(u64 size) final {
return {this->base_storage->SetSize(size)};
virtual Result SetSize(u64 size) final {
return this->base_storage->SetSize(size);
};
virtual std::tuple<Result, u64> get_size() final {
u64 out_size = 0;
Result rc = this->base_storage->GetSize(&out_size);
return {rc, out_size};
virtual Result GetSize(Out<u64> size) final {
return this->base_storage->GetSize(size.GetPointer());
};
virtual std::tuple<Result, FsRangeInfo> operate_range(u32 operation_type, u64 offset, u64 size) final {
FsRangeInfo out_range_info = {0};
Result rc = this->base_storage->OperateRange(operation_type, offset, size, &out_range_info);
return {rc, out_range_info};
virtual Result OperateRange(Out<FsRangeInfo> range_info, u32 operation_type, u64 offset, u64 size) final {
return this->base_storage->OperateRange(operation_type, offset, size, range_info.GetPointer());
};
public:
DEFINE_SERVICE_DISPATCH_TABLE {
/* 1.0.0- */
MakeServiceCommandMeta<FsIStorageCmd_Read, &IStorageInterface::Read>(),
MakeServiceCommandMeta<FsIStorageCmd_Write, &IStorageInterface::Write>(),
MakeServiceCommandMeta<FsIStorageCmd_Flush, &IStorageInterface::Flush>(),
MakeServiceCommandMeta<FsIStorageCmd_SetSize, &IStorageInterface::SetSize>(),
MakeServiceCommandMeta<FsIStorageCmd_GetSize, &IStorageInterface::GetSize>(),
/* 4.0.0- */
MakeServiceCommandMeta<FsIStorageCmd_OperateRange, &IStorageInterface::OperateRange, FirmwareVersion_400>(),
};
};
class IROStorage : public IStorage {
public:
virtual Result Read(void *buffer, size_t size, u64 offset) = 0;
Result Write(void *buffer, size_t size, u64 offset) final {
virtual Result Write(void *buffer, size_t size, u64 offset) final {
(void)(buffer);
(void)(offset);
(void)(size);
return 0x313802;
};
Result Flush() final {
virtual Result Flush() final {
return 0x0;
};
Result SetSize(u64 size) final {
virtual Result SetSize(u64 size) final {
(void)(size);
return 0x313802;
};

View File

@@ -17,47 +17,6 @@
#include <switch.h>
#include "fs_shim.h"
/* Necessary evil. */
Result ipcCopyFromDomain(Handle session, u32 object_id, Service *out) {
u32* buf = (u32*)armGetTls();
IpcCommand c;
ipcInitialize(&c);
struct {
u64 magic;
u64 cmd_id;
u32 object_id;
} *raw;
raw = ipcPrepareHeader(&c, sizeof(*raw));
buf[0] = IpcCommandType_Control;
raw->magic = SFCI_MAGIC;
raw->cmd_id = 1;
raw->object_id = object_id;
Result rc = ipcDispatch(session);
if (R_SUCCEEDED(rc)) {
IpcParsedCommand r;
ipcParse(&r);
struct ipcCopyFromDomainResponse {
u64 magic;
u64 result;
} *raw = (struct ipcCopyFromDomainResponse*)r.Raw;
rc = raw->result;
if (R_SUCCEEDED(rc)) {
serviceCreate(out, r.Handles[0]);
}
}
return rc;
}
/* Missing fsp-srv commands. */
Result fsOpenDataStorageByCurrentProcessFwd(Service* s, FsStorage* out) {
IpcCommand c;
@@ -68,7 +27,7 @@ Result fsOpenDataStorageByCurrentProcessFwd(Service* s, FsStorage* out) {
u64 cmd_id;
} *raw;
raw = ipcPrepareHeader(&c, sizeof(*raw));
raw = serviceIpcPrepareHeader(s, &c, sizeof(*raw));
raw->magic = SFCI_MAGIC;
raw->cmd_id = 200;
@@ -77,60 +36,25 @@ Result fsOpenDataStorageByCurrentProcessFwd(Service* s, FsStorage* out) {
if (R_SUCCEEDED(rc)) {
IpcParsedCommand r;
ipcParse(&r);
struct {
u64 magic;
u64 result;
} *resp = r.Raw;
} *resp;
serviceIpcParse(s, &r, sizeof(*resp));
resp = r.Raw;
rc = resp->result;
if (R_SUCCEEDED(rc)) {
serviceCreate(&out->s, r.Handles[0]);
serviceCreateSubservice(&out->s, s, &r, 0);
}
}
return rc;
}
Result fsOpenDataStorageByCurrentProcessFromDomainFwd(Service* s, u32 *out_object_id) {
IpcCommand c;
ipcInitialize(&c);
struct {
u64 magic;
u64 cmd_id;
} *raw;
raw = ipcPrepareHeaderForDomain(&c, sizeof(*raw), s->object_id);
raw->magic = SFCI_MAGIC;
raw->cmd_id = 200;
Result rc = serviceIpcDispatch(s);
if (R_SUCCEEDED(rc)) {
IpcParsedCommand r;
ipcParseForDomain(&r);
struct {
u64 magic;
u64 result;
u32 object_id;
} *resp = r.Raw;
rc = resp->result;
if (R_SUCCEEDED(rc)) {
*out_object_id = resp->object_id;
}
}
return rc;
}
Result fsOpenDataStorageByDataId(Service* s, FsStorageId storage_id, u64 data_id, FsStorage* out) {
Result fsOpenDataStorageByDataIdFwd(Service* s, FsStorageId storage_id, u64 data_id, FsStorage* out) {
IpcCommand c;
ipcInitialize(&c);
@@ -141,7 +65,7 @@ Result fsOpenDataStorageByDataId(Service* s, FsStorageId storage_id, u64 data_id
u64 data_id;
} *raw;
raw = ipcPrepareHeader(&c, sizeof(*raw));
raw = serviceIpcPrepareHeader(s, &c, sizeof(*raw));
raw->magic = SFCI_MAGIC;
raw->cmd_id = 202;
@@ -152,58 +76,18 @@ Result fsOpenDataStorageByDataId(Service* s, FsStorageId storage_id, u64 data_id
if (R_SUCCEEDED(rc)) {
IpcParsedCommand r;
ipcParse(&r);
struct {
u64 magic;
u64 result;
} *resp = r.Raw;
} *resp;
serviceIpcParse(s, &r, sizeof(*resp));
resp = r.Raw;
rc = resp->result;
if (R_SUCCEEDED(rc)) {
serviceCreate(&out->s, r.Handles[0]);
}
}
return rc;
}
Result fsOpenDataStorageByDataIdFromDomain(Service* s, FsStorageId storage_id, u64 data_id, u32 *out_object_id) {
IpcCommand c;
ipcInitialize(&c);
struct {
u64 magic;
u64 cmd_id;
FsStorageId storage_id;
u64 data_id;
} *raw;
raw = ipcPrepareHeaderForDomain(&c, sizeof(*raw), s->object_id);
raw->magic = SFCI_MAGIC;
raw->cmd_id = 202;
raw->storage_id = storage_id;
raw->data_id = data_id;
Result rc = serviceIpcDispatch(s);
if (R_SUCCEEDED(rc)) {
IpcParsedCommand r;
ipcParseForDomain(&r);
struct {
u64 magic;
u64 result;
u32 object_id;
} *resp = r.Raw;
rc = resp->result;
if (R_SUCCEEDED(rc)) {
*out_object_id = resp->object_id;
serviceCreateSubservice(&out->s, s, &r, 0);
}
}
@@ -223,7 +107,7 @@ Result fsFileOperateRange(FsFile* f, u32 op_id, u64 off, u64 len, FsRangeInfo *o
u64 len;
} *raw;
raw = ipcPrepareHeader(&c, sizeof(*raw));
raw = serviceIpcPrepareHeader(&f->s, &c, sizeof(*raw));
raw->magic = SFCI_MAGIC;
raw->cmd_id = 5;
@@ -235,13 +119,14 @@ Result fsFileOperateRange(FsFile* f, u32 op_id, u64 off, u64 len, FsRangeInfo *o
if (R_SUCCEEDED(rc)) {
IpcParsedCommand r;
ipcParse(&r);
struct {
u64 magic;
u64 result;
FsRangeInfo range_info;
} *resp = r.Raw;
} *resp;
serviceIpcParse(&f->s, &r, sizeof(*resp));
resp = r.Raw;
rc = resp->result;
if (R_SUCCEEDED(rc) && out) *out = resp->range_info;
@@ -263,7 +148,7 @@ Result fsStorageOperateRange(FsStorage* s, u32 op_id, u64 off, u64 len, FsRangeI
u64 len;
} *raw;
raw = ipcPrepareHeader(&c, sizeof(*raw));
raw = serviceIpcPrepareHeader(&s->s, &c, sizeof(*raw));
raw->magic = SFCI_MAGIC;
raw->cmd_id = 5;
@@ -275,13 +160,14 @@ Result fsStorageOperateRange(FsStorage* s, u32 op_id, u64 off, u64 len, FsRangeI
if (R_SUCCEEDED(rc)) {
IpcParsedCommand r;
ipcParse(&r);
struct {
u64 magic;
u64 result;
FsRangeInfo range_info;
} *resp = r.Raw;
} *resp;
serviceIpcParse(&s->s, &r, sizeof(*resp));
resp = r.Raw;
rc = resp->result;
if (R_SUCCEEDED(rc) && out) *out = resp->range_info;

View File

@@ -16,14 +16,9 @@ typedef struct {
u32 flags[0x40/sizeof(u32)];
} FsRangeInfo;
/* Necessary evils. */
Result ipcCopyFromDomain(Handle session, u32 object_id, Service *out);
/* Missing fsp-srv commands. */
Result fsOpenDataStorageByCurrentProcessFwd(Service* s, FsStorage* out);
Result fsOpenDataStorageByCurrentProcessFromDomainFwd(Service* s, u32 *out_object_id);
Result fsOpenDataStorageByDataId(Service* s, FsStorageId storage_id, u64 data_id, FsStorage* out);
Result fsOpenDataStorageByDataIdFromDomain(Service* s, FsStorageId storage_id, u64 data_id, u32 *out_object_id);
Result fsOpenDataStorageByDataIdFwd(Service* s, FsStorageId storage_id, u64 data_id, FsStorage* out);
/* Missing FS File commands. */
Result fsFileOperateRange(FsFile* f, u32 op_id, u64 off, u64 len, FsRangeInfo *out);

View File

@@ -124,12 +124,14 @@ Result LayeredRomFS::Read(void *buffer, size_t size, u64 offset) {
fatalSimple(0xF601);
}
read_so_far += cur_read_size;
offset += cur_read_size;
} else {
/* Handle padding explicitly. */
cur_source_ind++;
/* Zero out the padding we skip, here. */
memset((void *)((uintptr_t)buffer + read_so_far), 0, ((*this->p_source_infos)[cur_source_ind]).virtual_offset - (cur_source->virtual_offset + cur_source->size));
read_so_far += ((*this->p_source_infos)[cur_source_ind]).virtual_offset - (cur_source->virtual_offset + cur_source->size);
memset((void *)((uintptr_t)buffer + read_so_far), 0, ((*this->p_source_infos)[cur_source_ind]).virtual_offset - offset);
read_so_far += ((*this->p_source_infos)[cur_source_ind]).virtual_offset - offset;
offset = ((*this->p_source_infos)[cur_source_ind]).virtual_offset;
}
}

View File

@@ -32,16 +32,12 @@ class LayeredRomFS : public IROStorage {
/* Information about the merged RomFS. */
u64 title_id;
std::shared_ptr<std::vector<RomFSSourceInfo>> p_source_infos;
LayeredRomFS *Clone() override {
return new LayeredRomFS(*this);
};
public:
LayeredRomFS(std::shared_ptr<RomInterfaceStorage> s_r, std::shared_ptr<RomFileStorage> f_r, u64 tid);
virtual ~LayeredRomFS() = default;
Result Read(void *buffer, size_t size, u64 offset) override;
Result GetSize(u64 *out_size) override;
Result OperateRange(u32 operation_type, u64 offset, u64 size, FsRangeInfo *out_range_info) override;
virtual Result Read(void *buffer, size_t size, u64 offset) override;
virtual Result GetSize(u64 *out_size) override;
virtual Result OperateRange(u32 operation_type, u64 offset, u64 size, FsRangeInfo *out_range_info) override;
};

View File

@@ -22,13 +22,7 @@
#include <switch.h>
#include <stratosphere.hpp>
#include "sm_mitm.h"
#include "mitm_server.hpp"
#include "fsmitm_service.hpp"
#include "fsmitm_worker.hpp"
#include "mitm_query_service.hpp"
#include "fsmitm_utils.hpp"
@@ -67,58 +61,32 @@ void __appInit(void) {
fatalSimple(MAKERESULT(Module_Libnx, LibnxError_InitFail_SM));
}
rc = smMitMInitialize();
if (R_FAILED(rc)) {
fatalSimple(MAKERESULT(Module_Libnx, LibnxError_InitFail_SM));
}
rc = fsInitialize();
if (R_FAILED(rc)) {
fatalSimple(MAKERESULT(Module_Libnx, LibnxError_InitFail_FS));
}
rc = splInitialize();
if (R_FAILED(rc)) {
fatalSimple(0xCAFE << 4 | 3);
}
/* Check for exosphere API compatibility. */
u64 exosphere_cfg;
if (R_SUCCEEDED(splGetConfig((SplConfigItem)65000, &exosphere_cfg))) {
/* MitM requires Atmosphere API 0.1. */
u16 api_version = (exosphere_cfg >> 16) & 0xFFFF;
if (api_version < 0x0001) {
fatalSimple(0xCAFE << 4 | 0xFE);
}
} else {
fatalSimple(0xCAFE << 4 | 0xFF);
}
//splExit();
CheckAtmosphereVersion();
}
void __appExit(void) {
/* Cleanup services. */
fsExit();
smMitMExit();
smExit();
}
struct FsMitmManagerOptions {
static const size_t PointerBufferSize = 0x800;
static const size_t MaxDomains = 0x10;
static const size_t MaxDomainObjects = 0x4000;
};
using FsMitmManager = WaitableManager<FsMitmManagerOptions>;
int main(int argc, char **argv)
{
Thread worker_thread = {0};
Thread sd_initializer_thread = {0};
Thread hid_initializer_thread = {0};
consoleDebugInit(debugDevice_SVC);
consoleDebugInit(debugDevice_SVC);
if (R_FAILED(threadCreate(&worker_thread, &FsMitMWorker::Main, NULL, 0x20000, 45, 0))) {
/* TODO: Panic. */
}
if (R_FAILED(threadStart(&worker_thread))) {
/* TODO: Panic. */
}
if (R_FAILED(threadCreate(&sd_initializer_thread, &Utils::InitializeSdThreadFunc, NULL, 0x4000, 0x15, 0))) {
/* TODO: Panic. */
}
@@ -126,18 +94,23 @@ int main(int argc, char **argv)
/* TODO: Panic. */
}
if (R_FAILED(threadCreate(&hid_initializer_thread, &Utils::InitializeHidThreadFunc, NULL, 0x4000, 0x15, 0))) {
/* TODO: Panic. */
}
if (R_FAILED(threadStart(&hid_initializer_thread))) {
/* TODO: Panic. */
}
/* TODO: What's a good timeout value to use here? */
auto server_manager = std::make_unique<MultiThreadedWaitableManager>(1, U64_MAX, 0x20000);
//auto server_manager = std::make_unique<WaitableManager>(U64_MAX);
auto server_manager = new FsMitmManager(5);
/* Create fsp-srv mitm. */
ISession<MitMQueryService<FsMitMService>> *fs_query_srv = NULL;
MitMServer<FsMitMService> *fs_srv = new MitMServer<FsMitMService>(&fs_query_srv, "fsp-srv", 61);
server_manager->add_waitable(fs_srv);
server_manager->add_waitable(fs_query_srv);
AddMitmServerToManager<FsMitmService>(server_manager, "fsp-srv", 61);
/* Loop forever, servicing our services. */
server_manager->process();
server_manager->Process();
delete server_manager;
return 0;
}

View File

@@ -400,7 +400,7 @@ void RomFSBuildContext::Build(std::vector<RomFSSourceInfo> *out_infos) {
header->file_table_ofs = header->file_hash_table_ofs + header->file_hash_table_size;
/* For debugging, uncomment this to get a log of the generated metadata tables. */
/*
{
FsFileSystem sd_fs;
if (R_SUCCEEDED(fsMountSdcard(&sd_fs))) {
@@ -415,7 +415,7 @@ void RomFSBuildContext::Build(std::vector<RomFSSourceInfo> *out_infos) {
fsFsClose(&sd_fs);
}
}
*/
out_infos->emplace_back(header->dir_hash_table_ofs, this->dir_hash_table_size + this->dir_table_size + this->file_hash_table_size + this->file_table_size, metadata, RomFSDataSource::Memory);
}

View File

@@ -35,10 +35,6 @@ class RomFileStorage : public IROStorage {
fsFileClose(base_file);
delete base_file;
};
RomFileStorage *Clone() override {
return new RomFileStorage(this->base_file);
};
public:
Result Read(void *buffer, size_t size, u64 offset) override {
size_t out_sz = 0;
@@ -72,10 +68,6 @@ class RomInterfaceStorage : public IROStorage {
fsStorageClose(base_storage);
delete base_storage;
};
RomInterfaceStorage *Clone() override {
return new RomInterfaceStorage(this->base_storage);
};
public:
Result Read(void *buffer, size_t size, u64 offset) override {
return fsStorageRead(this->base_storage, offset, buffer, size);

View File

@@ -18,149 +18,115 @@
#include "fsmitm_service.hpp"
#include "fs_shim.h"
#include "fsmitm_worker.hpp"
#include "fsmitm_utils.hpp"
#include "fsmitm_romstorage.hpp"
#include "fsmitm_layeredrom.hpp"
#include "mitm_query_service.hpp"
#include "debug.hpp"
Result FsMitMService::dispatch(IpcParsedCommand &r, IpcCommand &out_c, u64 cmd_id, u8 *pointer_buffer, size_t pointer_buffer_size) {
Result rc = 0xF601;
if (this->has_initialized) {
switch (static_cast<FspSrvCmd>(cmd_id)) {
case FspSrvCmd::OpenDataStorageByCurrentProcess:
rc = WrapIpcCommandImpl<&FsMitMService::open_data_storage_by_current_process>(this, r, out_c, pointer_buffer, pointer_buffer_size);
void FsMitmService::PostProcess(IMitmServiceObject *obj, IpcResponseContext *ctx) {
auto this_ptr = static_cast<FsMitmService *>(obj);
switch ((FspSrvCmd)ctx->cmd_id) {
case FspSrvCmd_SetCurrentProcess:
if (R_SUCCEEDED(ctx->rc)) {
this_ptr->has_initialized = true;
this_ptr->process_id = ctx->request.Pid;
this_ptr->title_id = this_ptr->process_id;
if (R_FAILED(MitmQueryUtils::GetAssociatedTidForPid(this_ptr->process_id, &this_ptr->title_id))) {
/* Log here, if desired. */
}
break;
case FspSrvCmd::OpenDataStorageByDataId:
rc = WrapIpcCommandImpl<&FsMitMService::open_data_storage_by_data_id>(this, r, out_c, pointer_buffer, pointer_buffer_size);
break;
default:
break;
}
} else {
if (static_cast<FspSrvCmd>(cmd_id) == FspSrvCmd::SetCurrentProcess) {
if (r.HasPid) {
this->init_pid = r.Pid;
}
}
}
return rc;
}
void FsMitMService::postprocess(IpcParsedCommand &r, IpcCommand &out_c, u64 cmd_id, u8 *pointer_buffer, size_t pointer_buffer_size) {
struct {
u64 magic;
u64 result;
} *resp = (decltype(resp))r.Raw;
u64 *tls = (u64 *)armGetTls();
std::array<u64, 0x100/sizeof(u64)> backup_tls;
std::copy(tls, tls + backup_tls.size(), backup_tls.begin());
Result rc = (Result)resp->result;
switch (static_cast<FspSrvCmd>(cmd_id)) {
case FspSrvCmd::SetCurrentProcess:
if (R_SUCCEEDED(rc)) {
this->has_initialized = true;
}
this->process_id = this->init_pid;
this->title_id = this->process_id;
if (R_FAILED(MitMQueryUtils::get_associated_tid_for_pid(this->process_id, &this->title_id))) {
/* Log here, if desired. */
}
std::copy(backup_tls.begin(), backup_tls.end(), tls);
break;
default:
break;
}
resp->result = rc;
}
Result FsMitMService::handle_deferred() {
/* This service is never deferrable. */
return 0;
}
/* Add redirection for RomFS to the SD card. */
std::tuple<Result, OutSession<IStorageInterface>> FsMitMService::open_data_storage_by_current_process() {
IPCSession<IStorageInterface> *out_session = NULL;
std::shared_ptr<IStorageInterface> out_storage = nullptr;
Result FsMitmService::OpenDataStorageByCurrentProcess(Out<std::shared_ptr<IStorageInterface>> out_storage) {
std::shared_ptr<IStorageInterface> storage = nullptr;
u32 out_domain_id = 0;
Result rc;
Result rc = 0;
ON_SCOPE_EXIT {
if (R_SUCCEEDED(rc)) {
out_storage.SetValue(std::move(storage));
if (out_storage.IsDomain()) {
out_storage.ChangeObjectId(out_domain_id);
}
}
};
if (this->romfs_storage != nullptr) {
if (this->get_owner() != NULL) {
rc = fsOpenDataStorageByCurrentProcessFromDomainFwd(this->forward_service, &out_domain_id);
if (out_storage.IsDomain()) {
FsStorage s = {0};
rc = fsOpenDataStorageByCurrentProcessFwd(this->forward_service.get(), &s);
if (R_SUCCEEDED(rc)) {
out_domain_id = s.s.object_id;
}
} else {
rc = 0;
}
if (R_SUCCEEDED(rc)) {
out_storage = this->romfs_storage;
out_session = new IPCSession<IStorageInterface>(out_storage);
storage = this->romfs_storage;
}
} else {
FsStorage data_storage;
FsFile data_file;
rc = fsOpenDataStorageByCurrentProcessFwd(this->forward_service.get(), &data_storage);
if (this->get_owner() == NULL) {
rc = fsOpenDataStorageByCurrentProcessFwd(this->forward_service, &data_storage);
} else {
rc = fsOpenDataStorageByCurrentProcessFromDomainFwd(this->forward_service, &out_domain_id);
if (R_SUCCEEDED(rc)) {
rc = ipcCopyFromDomain(this->forward_service->handle, out_domain_id, &data_storage.s);
}
}
Log(armGetTls(), 0x100);
if (R_SUCCEEDED(rc)) {
/* TODO: Is there a sensible path that ends in ".romfs" we can use?" */
if (R_SUCCEEDED(Utils::OpenSdFileForAtmosphere(this->title_id, "romfs.bin", FS_OPEN_READ, &data_file))) {
out_storage = std::make_shared<IStorageInterface>(new LayeredRomFS(std::make_shared<RomInterfaceStorage>(data_storage), std::make_shared<RomFileStorage>(data_file), this->title_id));
storage = std::make_shared<IStorageInterface>(new LayeredRomFS(std::make_shared<RomInterfaceStorage>(data_storage), std::make_shared<RomFileStorage>(data_file), this->title_id));
} else {
out_storage = std::make_shared<IStorageInterface>(new LayeredRomFS(std::make_shared<RomInterfaceStorage>(data_storage), nullptr, this->title_id));
storage = std::make_shared<IStorageInterface>(new LayeredRomFS(std::make_shared<RomInterfaceStorage>(data_storage), nullptr, this->title_id));
}
this->romfs_storage = out_storage;
out_session = new IPCSession<IStorageInterface>(out_storage);
if (this->get_owner() == NULL) {
FsMitMWorker::AddWaitable(out_session);
this->romfs_storage = storage;
if (out_storage.IsDomain()) {
out_domain_id = data_storage.s.object_id;
}
}
}
OutSession out_s = OutSession(out_session);
out_s.domain_id = out_domain_id;
return {rc, out_s};
return rc;
}
/* Add redirection for System Data Archives to the SD card. */
std::tuple<Result, OutSession<IStorageInterface>> FsMitMService::open_data_storage_by_data_id(u64 sid, u64 data_id) {
Result FsMitmService::OpenDataStorageByDataId(Out<std::shared_ptr<IStorageInterface>> out_storage, u64 data_id, u8 sid) {
FsStorageId storage_id = (FsStorageId)sid;
IPCSession<IStorageInterface> *out_session = NULL;
FsStorage data_storage;
FsFile data_file;
std::shared_ptr<IStorageInterface> storage = nullptr;
u32 out_domain_id = 0;
Result rc;
if (this->get_owner() == NULL) {
rc = fsOpenDataStorageByDataId(this->forward_service, storage_id, data_id, &data_storage);
} else {
rc = fsOpenDataStorageByDataIdFromDomain(this->forward_service, storage_id, data_id, &out_domain_id);
Result rc = 0;
ON_SCOPE_EXIT {
if (R_SUCCEEDED(rc)) {
rc = ipcCopyFromDomain(this->forward_service->handle, out_domain_id, &data_storage.s);
out_storage.SetValue(std::move(storage));
if (out_storage.IsDomain()) {
out_storage.ChangeObjectId(out_domain_id);
}
}
}
};
rc = fsOpenDataStorageByDataIdFwd(this->forward_service.get(), storage_id, data_id, &data_storage);
if (R_SUCCEEDED(rc)) {
/* TODO: Is there a sensible path that ends in ".romfs" we can use?" */
if (R_SUCCEEDED(Utils::OpenSdFileForAtmosphere(data_id, "romfs.bin", FS_OPEN_READ, &data_file))) {
out_session = new IPCSession<IStorageInterface>(std::make_shared<IStorageInterface>(new LayeredRomFS(std::make_shared<RomInterfaceStorage>(data_storage), std::make_shared<RomFileStorage>(data_file), data_id)));
storage = std::make_shared<IStorageInterface>(new LayeredRomFS(std::make_shared<RomInterfaceStorage>(data_storage), std::make_shared<RomFileStorage>(data_file), data_id));
} else {
out_session = new IPCSession<IStorageInterface>(std::make_shared<IStorageInterface>(new LayeredRomFS(std::make_shared<RomInterfaceStorage>(data_storage), nullptr, data_id)));
storage = std::make_shared<IStorageInterface>(new LayeredRomFS(std::make_shared<RomInterfaceStorage>(data_storage), nullptr, data_id));
}
if (this->get_owner() == NULL) {
FsMitMWorker::AddWaitable(out_session);
if (out_storage.IsDomain()) {
out_domain_id = data_storage.s.object_id;
}
}
OutSession out_s = OutSession(out_session);
out_s.domain_id = out_domain_id;
return {rc, out_s};
return rc;
}

View File

@@ -16,49 +16,41 @@
#pragma once
#include <switch.h>
#include <stratosphere/iserviceobject.hpp>
#include "imitmserviceobject.hpp"
#include <stratosphere.hpp>
#include "fs_istorage.hpp"
#include "fsmitm_utils.hpp"
enum class FspSrvCmd {
SetCurrentProcess = 1,
OpenDataStorageByCurrentProcess = 200,
OpenDataStorageByDataId = 202,
enum FspSrvCmd : u32 {
FspSrvCmd_SetCurrentProcess = 1,
FspSrvCmd_OpenDataStorageByCurrentProcess = 200,
FspSrvCmd_OpenDataStorageByDataId = 202,
};
class FsMitMService : public IMitMServiceObject {
class FsMitmService : public IMitmServiceObject {
private:
bool has_initialized = false;
u64 init_pid = 0;
std::shared_ptr<IStorageInterface> romfs_storage;
public:
FsMitMService(Service *s) : IMitMServiceObject(s) {
FsMitmService(std::shared_ptr<Service> s) : IMitmServiceObject(s) {
/* ... */
}
static bool should_mitm(u64 pid, u64 tid) {
return tid >= 0x0100000000010000ULL || Utils::HasSdMitMFlag(tid);
static bool ShouldMitm(u64 pid, u64 tid) {
if (Utils::HasSdDisableMitMFlag(tid)) {
return false;
}
return (tid >= 0x0100000000010000ULL || Utils::HasSdMitMFlag(tid)) && Utils::HasOverrideButton(tid);
}
FsMitMService *clone() override {
auto new_srv = new FsMitMService((Service *)&this->forward_service);
this->clone_to(new_srv);
return new_srv;
}
void clone_to(void *o) override {
FsMitMService *other = (FsMitMService *)o;
other->has_initialized = has_initialized;
other->init_pid = init_pid;
}
virtual Result dispatch(IpcParsedCommand &r, IpcCommand &out_c, u64 cmd_id, u8 *pointer_buffer, size_t pointer_buffer_size);
virtual void postprocess(IpcParsedCommand &r, IpcCommand &out_c, u64 cmd_id, u8 *pointer_buffer, size_t pointer_buffer_size);
virtual Result handle_deferred();
static void PostProcess(IMitmServiceObject *obj, IpcResponseContext *ctx);
protected:
/* Overridden commands. */
std::tuple<Result, OutSession<IStorageInterface>> open_data_storage_by_current_process();
std::tuple<Result, OutSession<IStorageInterface>> open_data_storage_by_data_id(u64 storage_id, u64 data_id);
Result OpenDataStorageByCurrentProcess(Out<std::shared_ptr<IStorageInterface>> out);
Result OpenDataStorageByDataId(Out<std::shared_ptr<IStorageInterface>> out, u64 data_id, u8 storage_id);
public:
DEFINE_SERVICE_DISPATCH_TABLE {
MakeServiceCommandMeta<FspSrvCmd_OpenDataStorageByCurrentProcess, &FsMitmService::OpenDataStorageByCurrentProcess>(),
MakeServiceCommandMeta<FspSrvCmd_OpenDataStorageByDataId, &FsMitmService::OpenDataStorageByDataId>(),
};
};

View File

@@ -18,14 +18,23 @@
#include <stratosphere.hpp>
#include <atomic>
#include <algorithm>
#include <strings.h>
#include "sm_mitm.h"
#include "debug.hpp"
#include "fsmitm_utils.hpp"
#include "ini.h"
static FsFileSystem g_sd_filesystem = {0};
static std::vector<u64> g_mitm_flagged_tids;
static std::vector<u64> g_disable_mitm_flagged_tids;
static std::atomic_bool g_has_initialized = false;
static std::atomic_bool g_has_hid_session = false;
static u64 g_override_key_combination = KEY_R;
static bool g_override_by_default = true;
/* Static buffer for loader.ini contents at runtime. */
static char g_config_ini_data[0x800];
static bool IsHexadecimal(const char *str) {
while (*str) {
@@ -72,20 +81,45 @@ void Utils::InitializeSdThreadFunc(void *args) {
g_mitm_flagged_tids.push_back(title_id);
fsFileClose(&f);
}
memset(title_path, 0, sizeof(title_path));
strcpy(title_path, "/atmosphere/titles/");
strcat(title_path, dir_entry.name);
strcat(title_path, "/fsmitm_disable.flag");
if (R_SUCCEEDED(fsFsOpenFile(&g_sd_filesystem, title_path, FS_OPEN_READ, &f))) {
g_disable_mitm_flagged_tids.push_back(title_id);
fsFileClose(&f);
}
}
}
fsDirClose(&titles_dir);
}
Utils::RefreshConfiguration();
g_has_initialized = true;
svcExitThread();
}
void Utils::InitializeHidThreadFunc(void *args) {
while (R_FAILED(hidInitialize())) {
svcSleepThread(1000ULL);
}
g_has_hid_session = true;
svcExitThread();
}
bool Utils::IsSdInitialized() {
return g_has_initialized;
}
bool Utils::IsHidInitialized() {
return g_has_hid_session;
}
Result Utils::OpenSdFile(const char *fn, int flags, FsFile *out) {
if (!IsSdInitialized()) {
return 0xFA202;
@@ -189,3 +223,115 @@ bool Utils::HasSdMitMFlag(u64 tid) {
}
return false;
}
bool Utils::HasSdDisableMitMFlag(u64 tid) {
if (IsSdInitialized()) {
return std::find(g_disable_mitm_flagged_tids.begin(), g_disable_mitm_flagged_tids.end(), tid) != g_disable_mitm_flagged_tids.end();
}
return false;
}
Result Utils::GetKeysDown(u64 *keys) {
if (!Utils::IsHidInitialized()) {
return MAKERESULT(Module_Libnx, LibnxError_InitFail_HID);
}
hidScanInput();
*keys = hidKeysDown(CONTROLLER_P1_AUTO);
return 0x0;
}
bool Utils::HasOverrideButton(u64 tid) {
if (tid < 0x0100000000010000ULL || !IsSdInitialized()) {
/* Disable button override disable for non-applications. */
return true;
}
/* Unconditionally refresh loader.ini contents. */
RefreshConfiguration();
u64 kDown = 0;
bool keys_triggered = (R_SUCCEEDED(GetKeysDown(&kDown)) && ((kDown & g_override_key_combination) != 0));
return IsSdInitialized() && (g_override_by_default ^ keys_triggered);
}
static int FsMitMIniHandler(void *user, const char *section, const char *name, const char *value) {
/* Taken and modified, with love, from Rajkosto's implementation. */
if (strcasecmp(section, "config") == 0) {
if (strcasecmp(name, "override_key") == 0) {
if (value[0] == '!') {
g_override_by_default = true;
value++;
} else {
g_override_by_default = false;
}
if (strcasecmp(value, "A") == 0) {
g_override_key_combination = KEY_A;
} else if (strcasecmp(value, "B") == 0) {
g_override_key_combination = KEY_B;
} else if (strcasecmp(value, "X") == 0) {
g_override_key_combination = KEY_X;
} else if (strcasecmp(value, "Y") == 0) {
g_override_key_combination = KEY_Y;
} else if (strcasecmp(value, "LS") == 0) {
g_override_key_combination = KEY_LSTICK;
} else if (strcasecmp(value, "RS") == 0) {
g_override_key_combination = KEY_RSTICK;
} else if (strcasecmp(value, "L") == 0) {
g_override_key_combination = KEY_L;
} else if (strcasecmp(value, "R") == 0) {
g_override_key_combination = KEY_R;
} else if (strcasecmp(value, "ZL") == 0) {
g_override_key_combination = KEY_ZL;
} else if (strcasecmp(value, "ZR") == 0) {
g_override_key_combination = KEY_ZR;
} else if (strcasecmp(value, "PLUS") == 0) {
g_override_key_combination = KEY_PLUS;
} else if (strcasecmp(value, "MINUS") == 0) {
g_override_key_combination = KEY_MINUS;
} else if (strcasecmp(value, "DLEFT") == 0) {
g_override_key_combination = KEY_DLEFT;
} else if (strcasecmp(value, "DUP") == 0) {
g_override_key_combination = KEY_DUP;
} else if (strcasecmp(value, "DRIGHT") == 0) {
g_override_key_combination = KEY_DRIGHT;
} else if (strcasecmp(value, "DDOWN") == 0) {
g_override_key_combination = KEY_DDOWN;
} else if (strcasecmp(value, "SL") == 0) {
g_override_key_combination = KEY_SL;
} else if (strcasecmp(value, "SR") == 0) {
g_override_key_combination = KEY_SR;
} else {
g_override_key_combination = 0;
}
}
} else {
return 0;
}
return 1;
}
void Utils::RefreshConfiguration() {
FsFile config_file;
if (R_FAILED(fsFsOpenFile(&g_sd_filesystem, "/atmosphere/loader.ini", FS_OPEN_READ, &config_file))) {
return;
}
u64 size;
if (R_FAILED(fsFileGetSize(&config_file, &size))) {
return;
}
size = std::min(size, (decltype(size))0x7FF);
/* Read in string. */
std::fill(g_config_ini_data, g_config_ini_data + 0x800, 0);
size_t r_s;
fsFileRead(&config_file, 0, g_config_ini_data, size, &r_s);
fsFileClose(&config_file);
ini_parse_string(g_config_ini_data, FsMitMIniHandler, NULL);
}

View File

@@ -37,4 +37,13 @@ class Utils {
/* SD card Initialization + MitM detection. */
static void InitializeSdThreadFunc(void *args);
static bool HasSdMitMFlag(u64 tid);
static bool HasSdDisableMitMFlag(u64 tid);
static bool IsHidInitialized();
static void InitializeHidThreadFunc(void *args);
static Result GetKeysDown(u64 *keys);
static bool HasOverrideButton(u64 tid);
private:
static void RefreshConfiguration();
};

View File

@@ -1,53 +0,0 @@
/*
* Copyright (c) 2018 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/>.
*/
#include <mutex>
#include <switch.h>
#include <stratosphere.hpp>
#include "fsmitm_worker.hpp"
static SystemEvent *g_new_waitable_event = NULL;
static HosMutex g_new_waitable_mutex;
static HosSemaphore g_sema_new_waitable_finish;
static std::unique_ptr<WaitableManager> g_worker_waiter;
Result FsMitMWorker::AddWaitableCallback(void *arg, Handle *handles, size_t num_handles, u64 timeout) {
(void)arg;
svcClearEvent(handles[0]);
g_sema_new_waitable_finish.Signal();
return 0;
}
void FsMitMWorker::AddWaitable(IWaitable *waitable) {
g_worker_waiter->add_waitable(waitable);
std::scoped_lock lk{g_new_waitable_mutex};
g_new_waitable_event->signal_event();
g_sema_new_waitable_finish.Wait();
}
void FsMitMWorker::Main(void *arg) {
/* Initialize waitable event. */
g_new_waitable_event = new SystemEvent(NULL, &FsMitMWorker::AddWaitableCallback);
/* Make a new waitable manager. */
g_worker_waiter = std::make_unique<WaitableManager>(U64_MAX);
g_worker_waiter->add_waitable(g_new_waitable_event);
/* Service processes. */
g_worker_waiter->process();
}

View File

@@ -0,0 +1,269 @@
/* inih -- simple .INI file parser
inih is released under the New BSD license (see LICENSE.txt). Go to the project
home page for more info:
https://github.com/benhoyt/inih
*/
#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS)
#define _CRT_SECURE_NO_WARNINGS
#endif
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include "ini.h"
#if !INI_USE_STACK
#include <stdlib.h>
#endif
#define MAX_SECTION 50
#define MAX_NAME 50
/* Used by ini_parse_string() to keep track of string parsing state. */
typedef struct {
const char* ptr;
size_t num_left;
} ini_parse_string_ctx;
/* Strip whitespace chars off end of given string, in place. Return s. */
static char* rstrip(char* s)
{
char* p = s + strlen(s);
while (p > s && isspace((unsigned char)(*--p)))
*p = '\0';
return s;
}
/* Return pointer to first non-whitespace char in given string. */
static char* lskip(const char* s)
{
while (*s && isspace((unsigned char)(*s)))
s++;
return (char*)s;
}
/* Return pointer to first char (of chars) or inline comment in given string,
or pointer to null at end of string if neither found. Inline comment must
be prefixed by a whitespace character to register as a comment. */
static char* find_chars_or_comment(const char* s, const char* chars)
{
#if INI_ALLOW_INLINE_COMMENTS
int was_space = 0;
while (*s && (!chars || !strchr(chars, *s)) &&
!(was_space && strchr(INI_INLINE_COMMENT_PREFIXES, *s))) {
was_space = isspace((unsigned char)(*s));
s++;
}
#else
while (*s && (!chars || !strchr(chars, *s))) {
s++;
}
#endif
return (char*)s;
}
/* Version of strncpy that ensures dest (size bytes) is null-terminated. */
static char* strncpy0(char* dest, const char* src, size_t size)
{
strncpy(dest, src, size - 1);
dest[size - 1] = '\0';
return dest;
}
/* See documentation in header file. */
int ini_parse_stream(ini_reader reader, void* stream, ini_handler handler,
void* user)
{
/* Uses a fair bit of stack (use heap instead if you need to) */
#if INI_USE_STACK
char line[INI_MAX_LINE];
int max_line = INI_MAX_LINE;
#else
char* line;
int max_line = INI_INITIAL_ALLOC;
#endif
#if INI_ALLOW_REALLOC
char* new_line;
int offset;
#endif
char section[MAX_SECTION] = "";
char prev_name[MAX_NAME] = "";
char* start;
char* end;
char* name;
char* value;
int lineno = 0;
int error = 0;
#if !INI_USE_STACK
line = (char*)malloc(INI_INITIAL_ALLOC);
if (!line) {
return -2;
}
#endif
#if INI_HANDLER_LINENO
#define HANDLER(u, s, n, v) handler(u, s, n, v, lineno)
#else
#define HANDLER(u, s, n, v) handler(u, s, n, v)
#endif
/* Scan through stream line by line */
while (reader(line, max_line, stream) != NULL) {
#if INI_ALLOW_REALLOC
offset = strlen(line);
while (offset == max_line - 1 && line[offset - 1] != '\n') {
max_line *= 2;
if (max_line > INI_MAX_LINE)
max_line = INI_MAX_LINE;
new_line = realloc(line, max_line);
if (!new_line) {
free(line);
return -2;
}
line = new_line;
if (reader(line + offset, max_line - offset, stream) == NULL)
break;
if (max_line >= INI_MAX_LINE)
break;
offset += strlen(line + offset);
}
#endif
lineno++;
start = line;
#if INI_ALLOW_BOM
if (lineno == 1 && (unsigned char)start[0] == 0xEF &&
(unsigned char)start[1] == 0xBB &&
(unsigned char)start[2] == 0xBF) {
start += 3;
}
#endif
start = lskip(rstrip(start));
if (strchr(INI_START_COMMENT_PREFIXES, *start)) {
/* Start-of-line comment */
}
#if INI_ALLOW_MULTILINE
else if (*prev_name && *start && start > line) {
/* Non-blank line with leading whitespace, treat as continuation
of previous name's value (as per Python configparser). */
if (!HANDLER(user, section, prev_name, start) && !error)
error = lineno;
}
#endif
else if (*start == '[') {
/* A "[section]" line */
end = find_chars_or_comment(start + 1, "]");
if (*end == ']') {
*end = '\0';
strncpy0(section, start + 1, sizeof(section));
*prev_name = '\0';
}
else if (!error) {
/* No ']' found on section line */
error = lineno;
}
}
else if (*start) {
/* Not a comment, must be a name[=:]value pair */
end = find_chars_or_comment(start, "=:");
if (*end == '=' || *end == ':') {
*end = '\0';
name = rstrip(start);
value = end + 1;
#if INI_ALLOW_INLINE_COMMENTS
end = find_chars_or_comment(value, NULL);
if (*end)
*end = '\0';
#endif
value = lskip(value);
rstrip(value);
/* Valid name[=:]value pair found, call handler */
strncpy0(prev_name, name, sizeof(prev_name));
if (!HANDLER(user, section, name, value) && !error)
error = lineno;
}
else if (!error) {
/* No '=' or ':' found on name[=:]value line */
error = lineno;
}
}
#if INI_STOP_ON_FIRST_ERROR
if (error)
break;
#endif
}
#if !INI_USE_STACK
free(line);
#endif
return error;
}
/* See documentation in header file. */
int ini_parse_file(FILE* file, ini_handler handler, void* user)
{
return ini_parse_stream((ini_reader)fgets, file, handler, user);
}
/* See documentation in header file. */
int ini_parse(const char* filename, ini_handler handler, void* user)
{
FILE* file;
int error;
file = fopen(filename, "r");
if (!file)
return -1;
error = ini_parse_file(file, handler, user);
fclose(file);
return error;
}
/* An ini_reader function to read the next line from a string buffer. This
is the fgets() equivalent used by ini_parse_string(). */
static char* ini_reader_string(char* str, int num, void* stream) {
ini_parse_string_ctx* ctx = (ini_parse_string_ctx*)stream;
const char* ctx_ptr = ctx->ptr;
size_t ctx_num_left = ctx->num_left;
char* strp = str;
char c;
if (ctx_num_left == 0 || num < 2)
return NULL;
while (num > 1 && ctx_num_left != 0) {
c = *ctx_ptr++;
ctx_num_left--;
*strp++ = c;
if (c == '\n')
break;
num--;
}
*strp = '\0';
ctx->ptr = ctx_ptr;
ctx->num_left = ctx_num_left;
return str;
}
/* See documentation in header file. */
int ini_parse_string(const char* string, ini_handler handler, void* user) {
ini_parse_string_ctx ctx;
ctx.ptr = string;
ctx.num_left = strlen(string);
return ini_parse_stream((ini_reader)ini_reader_string, &ctx, handler,
user);
}

View File

@@ -0,0 +1,130 @@
/* inih -- simple .INI file parser
inih is released under the New BSD license (see LICENSE.txt). Go to the project
home page for more info:
https://github.com/benhoyt/inih
*/
#ifndef __INI_H__
#define __INI_H__
/* Make this header file easier to include in C++ code */
#ifdef __cplusplus
extern "C" {
#endif
#include <stdio.h>
/* Nonzero if ini_handler callback should accept lineno parameter. */
#ifndef INI_HANDLER_LINENO
#define INI_HANDLER_LINENO 0
#endif
/* Typedef for prototype of handler function. */
#if INI_HANDLER_LINENO
typedef int (*ini_handler)(void* user, const char* section,
const char* name, const char* value,
int lineno);
#else
typedef int (*ini_handler)(void* user, const char* section,
const char* name, const char* value);
#endif
/* Typedef for prototype of fgets-style reader function. */
typedef char* (*ini_reader)(char* str, int num, void* stream);
/* Parse given INI-style file. May have [section]s, name=value pairs
(whitespace stripped), and comments starting with ';' (semicolon). Section
is "" if name=value pair parsed before any section heading. name:value
pairs are also supported as a concession to Python's configparser.
For each name=value pair parsed, call handler function with given user
pointer as well as section, name, and value (data only valid for duration
of handler call). Handler should return nonzero on success, zero on error.
Returns 0 on success, line number of first error on parse error (doesn't
stop on first error), -1 on file open error, or -2 on memory allocation
error (only when INI_USE_STACK is zero).
*/
int ini_parse(const char* filename, ini_handler handler, void* user);
/* Same as ini_parse(), but takes a FILE* instead of filename. This doesn't
close the file when it's finished -- the caller must do that. */
int ini_parse_file(FILE* file, ini_handler handler, void* user);
/* Same as ini_parse(), but takes an ini_reader function pointer instead of
filename. Used for implementing custom or string-based I/O (see also
ini_parse_string). */
int ini_parse_stream(ini_reader reader, void* stream, ini_handler handler,
void* user);
/* Same as ini_parse(), but takes a zero-terminated string with the INI data
instead of a file. Useful for parsing INI data from a network socket or
already in memory. */
int ini_parse_string(const char* string, ini_handler handler, void* user);
/* Nonzero to allow multi-line value parsing, in the style of Python's
configparser. If allowed, ini_parse() will call the handler with the same
name for each subsequent line parsed. */
#ifndef INI_ALLOW_MULTILINE
#define INI_ALLOW_MULTILINE 1
#endif
/* Nonzero to allow a UTF-8 BOM sequence (0xEF 0xBB 0xBF) at the start of
the file. See http://code.google.com/p/inih/issues/detail?id=21 */
#ifndef INI_ALLOW_BOM
#define INI_ALLOW_BOM 1
#endif
/* Chars that begin a start-of-line comment. Per Python configparser, allow
both ; and # comments at the start of a line by default. */
#ifndef INI_START_COMMENT_PREFIXES
#define INI_START_COMMENT_PREFIXES ";#"
#endif
/* Nonzero to allow inline comments (with valid inline comment characters
specified by INI_INLINE_COMMENT_PREFIXES). Set to 0 to turn off and match
Python 3.2+ configparser behaviour. */
#ifndef INI_ALLOW_INLINE_COMMENTS
#define INI_ALLOW_INLINE_COMMENTS 1
#endif
#ifndef INI_INLINE_COMMENT_PREFIXES
#define INI_INLINE_COMMENT_PREFIXES ";"
#endif
/* Nonzero to use stack for line buffer, zero to use heap (malloc/free). */
#ifndef INI_USE_STACK
#define INI_USE_STACK 1
#endif
/* Maximum line length for any line in INI file (stack or heap). Note that
this must be 3 more than the longest line (due to '\r', '\n', and '\0'). */
#ifndef INI_MAX_LINE
#define INI_MAX_LINE 200
#endif
/* Nonzero to allow heap line buffer to grow via realloc(), zero for a
fixed-size buffer of INI_MAX_LINE bytes. Only applies if INI_USE_STACK is
zero. */
#ifndef INI_ALLOW_REALLOC
#define INI_ALLOW_REALLOC 0
#endif
/* Initial size in bytes for heap line buffer. Only applies if INI_USE_STACK
is zero. */
#ifndef INI_INITIAL_ALLOC
#define INI_INITIAL_ALLOC 200
#endif
/* Stop parsing on first error (default is to keep parsing). */
#ifndef INI_STOP_ON_FIRST_ERROR
#define INI_STOP_ON_FIRST_ERROR 0
#endif
#ifdef __cplusplus
}
#endif
#endif /* __INI_H__ */

View File

@@ -1,75 +0,0 @@
/*
* Copyright (c) 2018 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 <switch.h>
#include <stratosphere/iserviceobject.hpp>
#include "debug.hpp"
enum MitMQueryServiceCommand {
MQS_Cmd_ShouldMitm = 65000,
MQS_Cmd_AssociatePidTid = 65001
};
namespace MitMQueryUtils {
Result get_associated_tid_for_pid(u64 pid, u64 *tid);
void associate_pid_to_tid(u64 pid, u64 tid);
}
template <typename T>
class MitMQueryService : public IServiceObject {
public:
MitMQueryService<T> *clone() override {
return new MitMQueryService<T>();
}
Result dispatch(IpcParsedCommand &r, IpcCommand &out_c, u64 cmd_id, u8 *pointer_buffer, size_t pointer_buffer_size) override {
Log(armGetTls(), 0x100);
switch (cmd_id) {
case MQS_Cmd_ShouldMitm:
return WrapIpcCommandImpl<&MitMQueryService::should_mitm>(this, r, out_c, pointer_buffer, pointer_buffer_size);
case MQS_Cmd_AssociatePidTid:
return WrapIpcCommandImpl<&MitMQueryService::associate_pid_tid>(this, r, out_c, pointer_buffer, pointer_buffer_size);
default:
return 0xF601;
}
if (cmd_id == 65000) {
} else {
return 0xF601;
}
}
Result handle_deferred() override {
/* This service is never deferrable. */
return 0;
}
protected:
std::tuple<Result, u64> should_mitm(u64 pid) {
u64 should_mitm = 0;
u64 tid = 0;
if (R_SUCCEEDED(MitMQueryUtils::get_associated_tid_for_pid(pid, &tid))) {
should_mitm = T::should_mitm(pid, tid);
}
return {0, should_mitm};
}
std::tuple<Result> associate_pid_tid(u64 pid, u64 tid) {
MitMQueryUtils::associate_pid_to_tid(pid, tid);
return {0x0};
}
};

View File

@@ -1,69 +0,0 @@
/*
* Copyright (c) 2018 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 <switch.h>
#include <stratosphere.hpp>
#include "mitm_query_service.hpp"
#include "sm_mitm.h"
#include "mitm_session.hpp"
#include "debug.hpp"
template <typename T>
class MitMSession;
template <typename T>
class MitMServer final : public IServer<T> {
static_assert(std::is_base_of<IServiceObject, T>::value, "Service Objects must derive from IServiceObject");
private:
char mitm_name[9];
public:
MitMServer(ISession<MitMQueryService<T>> **out_query_session, const char *service_name, unsigned int max_s, bool s_d = false) : IServer<T>(service_name, max_s, s_d) {
Handle tmp_hnd;
Handle out_query_h;
Result rc;
if (R_SUCCEEDED((rc = smGetServiceOriginal(&tmp_hnd, smEncodeName(service_name))))) {
svcCloseHandle(tmp_hnd);
} else {
fatalSimple(rc);
}
strncpy(mitm_name, service_name, 8);
mitm_name[8] = '\x00';
if (R_FAILED((rc = smMitMInstall(&this->port_handle, &out_query_h, mitm_name)))) {
fatalSimple(rc);
}
*out_query_session = new ServiceSession<MitMQueryService<T>>(NULL, out_query_h, 0);
}
virtual ~MitMServer() {
if (this->port_handle) {
if (R_FAILED(smMitMUninstall(this->mitm_name))) {
/* TODO: Panic. */
}
/* svcCloseHandle(port_handle); was called by ~IServer. */
}
}
ISession<T> *get_new_session(Handle session_h) override {
return new MitMSession<T>(this, session_h, 0, mitm_name);
}
};

View File

@@ -1,244 +0,0 @@
/*
* Copyright (c) 2018 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 <switch.h>
#include <stratosphere.hpp>
#include "imitmserviceobject.hpp"
#include "mitm_query_service.hpp"
#include "mitm_server.hpp"
#include "fsmitm_worker.hpp"
#include "debug.hpp"
template <typename T>
class MitMServer;
template <typename T>
class MitMSession final : public ISession<T> {
static_assert(std::is_base_of<IMitMServiceObject, T>::value, "MitM Service Objects must derive from IMitMServiceObject");
/* This will be for the actual session. */
Service forward_service;
IpcParsedCommand cur_out_r;
u32 mitm_domain_id = 0;
bool got_first_message;
public:
MitMSession<T>(MitMServer<T> *s, Handle s_h, Handle c_h, const char *srv) : ISession<T>(s, s_h, c_h, NULL, 0), got_first_message(false) {
this->server = s;
this->server_handle = s_h;
this->client_handle = c_h;
if (R_FAILED(smMitMGetService(&forward_service, srv))) {
/* TODO: Panic. */
}
size_t pointer_buffer_size = 0;
if (R_FAILED(ipcQueryPointerBufferSize(forward_service.handle, &pointer_buffer_size))) {
/* TODO: Panic. */
}
this->service_object = std::make_shared<T>(&forward_service);
this->pointer_buffer.resize(pointer_buffer_size);
}
MitMSession<T>(MitMServer<T> *s, Handle s_h, Handle c_h, Handle f_h) : ISession<T>(s, s_h, c_h, NULL, 0), got_first_message(true) {
this->server = s;
this->server_handle = s_h;
this->client_handle = c_h;
serviceCreate(&this->forward_service, f_h);
size_t pointer_buffer_size = 0;
if (R_FAILED(ipcQueryPointerBufferSize(forward_service.handle, &pointer_buffer_size))) {
/* TODO: Panic. */
}
this->service_object = std::make_shared<T>(&forward_service);
this->pointer_buffer.resize(pointer_buffer_size);
}
virtual ~MitMSession() {
serviceClose(&forward_service);
}
Result handle_message(IpcParsedCommand &r) override {
IpcCommand c;
ipcInitialize(&c);
u64 cmd_id = ((u32 *)r.Raw)[2];
Result retval = 0xF601;
cur_out_r.NumHandles = 0;
Log(armGetTls(), 0x100);
u32 *cmdbuf = (u32 *)armGetTls();
if (r.CommandType == IpcCommandType_Close) {
Reboot();
}
if (r.CommandType == IpcCommandType_Request || r.CommandType == IpcCommandType_RequestWithContext) {
std::shared_ptr<IServiceObject> obj;
if (r.IsDomainMessage) {
obj = this->domain->get_domain_object(r.ThisObjectId);
if (obj != nullptr && r.MessageType == DomainMessageType_Close) {
if (r.ThisObjectId == this->mitm_domain_id) {
Reboot();
}
this->domain->delete_object(r.ThisObjectId);
struct {
u64 magic;
u64 result;
} *o_resp;
o_resp = (decltype(o_resp)) ipcPrepareHeaderForDomain(&c, sizeof(*o_resp), 0);
*(DomainMessageHeader *)((uintptr_t)o_resp - sizeof(DomainMessageHeader)) = {0};
o_resp->magic = SFCO_MAGIC;
o_resp->result = 0x0;
Log(armGetTls(), 0x100);
return o_resp->result;
}
} else {
obj = this->service_object;
}
if (obj != nullptr) {
retval = obj->dispatch(r, c, cmd_id, (u8 *)this->pointer_buffer.data(), this->pointer_buffer.size());
if (R_SUCCEEDED(retval)) {
if (r.IsDomainMessage) {
ipcParseForDomain(&cur_out_r);
} else {
ipcParse(&cur_out_r);
}
return retval;
}
}
} else if (r.CommandType == IpcCommandType_Control || r.CommandType == IpcCommandType_ControlWithContext) {
/* Ipc Clone Current Object. */
retval = serviceIpcDispatch(&forward_service);
Log(armGetTls(), 0x100);
if (R_SUCCEEDED(retval)) {
ipcParse(&cur_out_r);
struct {
u64 magic;
u64 result;
} *resp = (decltype(resp))cur_out_r.Raw;
retval = resp->result;
if ((cmd_id == IpcCtrl_Cmd_CloneCurrentObject || cmd_id == IpcCtrl_Cmd_CloneCurrentObjectEx)) {
if (R_SUCCEEDED(retval)) {
Handle s_h;
Handle c_h;
Result rc;
if (R_FAILED((rc = svcCreateSession(&s_h, &c_h, 0, 0)))) {
fatalSimple(rc);
}
if (cur_out_r.NumHandles != 1) {
Reboot();
}
MitMSession<T> *new_sess = new MitMSession<T>((MitMServer<T> *)this->server, s_h, c_h, cur_out_r.Handles[0]);
new_sess->service_object = this->service_object;
if (this->is_domain) {
new_sess->is_domain = true;
new_sess->domain = this->domain;
new_sess->mitm_domain_id = this->mitm_domain_id;
new_sess->forward_service.type = this->forward_service.type;
new_sess->forward_service.object_id = this->forward_service.object_id;
}
this->get_manager()->add_waitable(new_sess);
ipcSendHandleMove(&c, c_h);
struct {
u64 magic;
u64 result;
} *o_resp;
o_resp = (decltype(o_resp)) ipcPrepareHeader(&c, sizeof(*o_resp));
o_resp->magic = SFCO_MAGIC;
o_resp->result = 0x0;
}
}
}
Log(armGetTls(), 0x100);
return retval;
}
/* 0xF601 --> Dispatch onwards. */
if (retval == 0xF601) {
/* Patch PID Descriptor, if relevant. */
if (r.HasPid) {
/* [ctrl 0] [ctrl 1] [handle desc 0] [pid low] [pid high] */
cmdbuf[4] = 0xFFFE0000UL | (cmdbuf[4] & 0xFFFFUL);
}
Log(armGetTls(), 0x100);
retval = serviceIpcDispatch(&forward_service);
if (R_SUCCEEDED(retval)) {
if (r.IsDomainMessage) {
ipcParseForDomain(&cur_out_r);
} else {
ipcParse(&cur_out_r);
}
struct {
u64 magic;
u64 result;
} *resp = (decltype(resp))cur_out_r.Raw;
retval = resp->result;
}
}
Log(armGetTls(), 0x100);
Log(&cmd_id, sizeof(u64));
u64 retval_for_log = retval;
Log(&retval_for_log, sizeof(u64));
if (R_FAILED(retval)) {
//Reboot();
}
return retval;
}
void postprocess(IpcParsedCommand &r, u64 cmd_id) override {
if (this->active_object == this->service_object && (r.CommandType == IpcCommandType_Request || r.CommandType == IpcCommandType_RequestWithContext)) {
IpcCommand c;
ipcInitialize(&c);
this->service_object->postprocess(cur_out_r, c, cmd_id, (u8 *)this->pointer_buffer.data(), this->pointer_buffer.size());
} else if (r.CommandType == IpcCommandType_Control || r.CommandType == IpcCommandType_ControlWithContext) {
if (cmd_id == IpcCtrl_Cmd_ConvertCurrentObjectToDomain) {
this->is_domain = true;
this->domain = std::make_shared<DomainOwner>();
struct {
u64 magic;
u64 result;
u32 domain_id;
} *resp = (decltype(resp))cur_out_r.Raw;
Result rc;
if (R_FAILED((rc = this->domain->set_object(this->service_object, resp->domain_id)))) {
fatalSimple(rc);
}
this->mitm_domain_id = resp->domain_id;
this->forward_service.type = ServiceType_Domain;
this->forward_service.object_id = resp->domain_id;
}
}
}
void cleanup() override {
/* Clean up copy handles. */
for (unsigned int i = 0; i < cur_out_r.NumHandles; i++) {
if (cur_out_r.WasHandleCopied[i]) {
svcCloseHandle(cur_out_r.Handles[i]);
}
}
}
};

View File

@@ -18,7 +18,7 @@ include $(DEVKITPRO)/libnx/switch_rules
TARGET := $(notdir $(CURDIR))
SOURCES := source
DATA := data
INCLUDES := include
INCLUDES := include ../../common/include
#---------------------------------------------------------------------------------
# options for code generation

View File

@@ -1,47 +0,0 @@
/*
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_BOOST_CLBL_TRTS_HPP
#define BOOST_CLBL_TRTS_BOOST_CLBL_TRTS_HPP
#include <boost/callable_traits/detail/core.hpp>
#include <boost/callable_traits/add_member_const.hpp>
#include <boost/callable_traits/add_member_cv.hpp>
#include <boost/callable_traits/add_member_lvalue_reference.hpp>
#include <boost/callable_traits/add_member_rvalue_reference.hpp>
#include <boost/callable_traits/add_member_volatile.hpp>
#include <boost/callable_traits/add_noexcept.hpp>
#include <boost/callable_traits/add_transaction_safe.hpp>
#include <boost/callable_traits/add_varargs.hpp>
#include <boost/callable_traits/apply_member_pointer.hpp>
#include <boost/callable_traits/apply_return.hpp>
#include <boost/callable_traits/args.hpp>
#include <boost/callable_traits/class_of.hpp>
#include <boost/callable_traits/function_type.hpp>
#include <boost/callable_traits/has_member_qualifiers.hpp>
#include <boost/callable_traits/has_varargs.hpp>
#include <boost/callable_traits/has_void_return.hpp>
#include <boost/callable_traits/is_const_member.hpp>
#include <boost/callable_traits/is_invocable.hpp>
#include <boost/callable_traits/is_lvalue_reference_member.hpp>
#include <boost/callable_traits/is_reference_member.hpp>
#include <boost/callable_traits/is_rvalue_reference_member.hpp>
#include <boost/callable_traits/is_noexcept.hpp>
#include <boost/callable_traits/is_transaction_safe.hpp>
#include <boost/callable_traits/is_volatile_member.hpp>
#include <boost/callable_traits/qualified_class_of.hpp>
#include <boost/callable_traits/remove_member_const.hpp>
#include <boost/callable_traits/remove_member_cv.hpp>
#include <boost/callable_traits/remove_member_reference.hpp>
#include <boost/callable_traits/remove_member_volatile.hpp>
#include <boost/callable_traits/remove_noexcept.hpp>
#include <boost/callable_traits/remove_transaction_safe.hpp>
#include <boost/callable_traits/remove_varargs.hpp>
#include <boost/callable_traits/return_type.hpp>
#endif

View File

@@ -1,105 +0,0 @@
/*
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_ADD_MEMBER_CONST_HPP
#define BOOST_CLBL_TRTS_ADD_MEMBER_CONST_HPP
#include <boost/callable_traits/detail/core.hpp>
namespace boost { namespace callable_traits {
//[ add_member_const_hpp
/*`
[section:ref_add_member_const add_member_const]
[heading Header]
``#include <boost/callable_traits/add_member_const.hpp>``
[heading Definition]
*/
template<typename T>
using add_member_const_t = //see below
//<-
#ifdef BOOST_CLBL_TRTS_DISABLE_ABOMINABLE_FUNCTIONS
detail::sfinae_try<
typename detail::traits<T>::add_member_const,
detail::fail_when_same<typename detail::traits<T>::add_member_const,
detail::abominable_functions_not_supported_on_this_compiler,
this_compiler_doesnt_support_abominable_function_types>,
detail::fail_if_invalid<typename detail::traits<T>::add_member_const,
member_qualifiers_are_illegal_for_this_type>>;
#else
detail::try_but_fail_if_invalid<
typename detail::traits<T>::add_member_const,
member_qualifiers_are_illegal_for_this_type>;
#endif // #ifdef BOOST_CLBL_TRTS_DISABLE_ABOMINABLE_FUNCTIONS
namespace detail {
template<typename T, typename = std::false_type>
struct add_member_const_impl {};
template<typename T>
struct add_member_const_impl <T, typename std::is_same<
add_member_const_t<T>, detail::dummy>::type>
{
using type = add_member_const_t<T>;
};
}
//->
template<typename T>
struct add_member_const : detail::add_member_const_impl<T> {};
//<-
}} // namespace boost::callable_traits
//->
/*`
[heading Constraints]
* `T` must be a function type or a member function pointer type
* If `T` is a pointer, it may not be cv/ref qualified
[heading Behavior]
* A substitution failure occurs if the constraints are violated.
* Adds a member `const` qualifier to `T`, if not already present.
[heading Input/Output Examples]
[table
[[`T`] [`add_member_const_t<T>`]]
[[`int()`] [`int() const`]]
[[`int(foo::*)()`] [`int(foo::*)() const`]]
[[`int(foo::*)() &`] [`int(foo::*)() const &`]]
[[`int(foo::*)() &&`] [`int(foo::*)() const &&`]]
[[`int(foo::*)() const`] [`int(foo::*)() const`]]
[[`int(foo::*)() volatile`] [`int(foo::*)() const volatile`]]
[[`int(foo::*)() transaction_safe`] [`int(foo::*)() const transaction_safe`]]
[[`int`] [(substitution failure)]]
[[`int (&)()`] [(substitution failure)]]
[[`int (*)()`] [(substitution failure)]]
[[`int foo::*`] [(substitution failure)]]
[[`int (foo::* const)()`] [(substitution failure)]]
]
[heading Example Program]
[import ../example/add_member_const.cpp]
[add_member_const]
[endsect]
*/
//]
#endif // #ifndef BOOST_CLBL_TRTS_ADD_MEMBER_CONST_HPP

View File

@@ -1,101 +0,0 @@
/*
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_ADD_MEMBER_CV_HPP
#define BOOST_CLBL_TRTS_ADD_MEMBER_CV_HPP
#include <boost/callable_traits/detail/core.hpp>
namespace boost { namespace callable_traits {
//[ add_member_cv_hpp
/*`
[section:ref_add_member_cv add_member_cv]
[heading Header]
``#include <boost/callable_traits/add_member_cv.hpp>``
[heading Definition]
*/
template<typename T>
using add_member_cv_t = //see below
//<-
#ifdef BOOST_CLBL_TRTS_DISABLE_ABOMINABLE_FUNCTIONS
detail::sfinae_try<
typename detail::traits<T>::add_member_cv,
detail::fail_when_same<typename detail::traits<T>::add_member_cv,
detail::abominable_functions_not_supported_on_this_compiler,
this_compiler_doesnt_support_abominable_function_types>,
detail::fail_if_invalid<typename detail::traits<T>::add_member_cv,
member_qualifiers_are_illegal_for_this_type>>;
#else
detail::try_but_fail_if_invalid<
typename detail::traits<T>::add_member_cv,
member_qualifiers_are_illegal_for_this_type>;
#endif // #ifdef BOOST_CLBL_TRTS_DISABLE_ABOMINABLE_FUNCTIONS
namespace detail {
template<typename T, typename = std::false_type>
struct add_member_cv_impl {};
template<typename T>
struct add_member_cv_impl <T, typename std::is_same<
add_member_cv_t<T>, detail::dummy>::type>
{
using type = add_member_cv_t<T>;
};
}
//->
template<typename T>
struct add_member_cv : detail::add_member_cv_impl<T> {};
//<-
}} // namespace boost::callable_traits
//->
/*`
[heading Constraints]
* `T` must be a function type or a member function pointer type
* If `T` is a pointer, it may not be cv/ref qualified
[heading Behavior]
* A substitution failure occurs if the constraints are violated.
* Adds member `const` and `volatile` qualifiers to `T`, if not already present.
[heading Input/Output Examples]
[table
[[`T`] [`add_member_cv_t<T>`]]
[[`int()`] [`int() const volatile`]]
[[`int(foo::*)()`] [`int(foo::*)() const volatile`]]
[[`int(foo::*)() &`] [`int(foo::*)() const volatile &`]]
[[`int(foo::*)() &&`] [`int(foo::*)() const volatile &&`]]
[[`int(foo::*)() const`] [`int(foo::*)() const volatile`]]
[[`int(foo::*)() volatile`] [`int(foo::*)() const volatile`]]
[[`int(foo::*)() transaction_safe`] [`int(foo::*)() const volatile transaction_safe`]]
[[`int`] [(substitution failure)]]
[[`int (&)()`] [(substitution failure)]]
[[`int (*)()`] [(substitution failure)]]
[[`int foo::*`] [(substitution failure)]]
[[`int (foo::* const)()`] [(substitution failure)]]
]
[heading Example Program]
[import ../example/add_member_cv.cpp]
[add_member_cv]
[endsect]
*/
//]
#endif

View File

@@ -1,114 +0,0 @@
/*
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_ADD_MEMBER_LVALUE_REFERENCE_HPP
#define BOOST_CLBL_TRTS_ADD_MEMBER_LVALUE_REFERENCE_HPP
#include <boost/callable_traits/detail/core.hpp>
namespace boost { namespace callable_traits {
//[ add_member_lvalue_reference_hpp
/*`
[section:ref_add_member_lvalue_reference add_member_lvalue_reference]
[heading Header]
``#include <boost/callable_traits/add_member_lvalue_reference.hpp>``
[heading Definition]
*/
#ifdef BOOST_CLBL_TRTS_DISABLE_REFERENCE_QUALIFIERS
template<typename T>
struct add_member_lvalue_reference_t {
static_assert(std::is_same<T, detail::dummy>::value,
"Reference member qualifiers are not supported by this configuration.");
};
#else
template<typename T>
using add_member_lvalue_reference_t = //see below
//<-
#ifdef BOOST_CLBL_TRTS_DISABLE_ABOMINABLE_FUNCTIONS
detail::sfinae_try<
typename detail::traits<T>::add_member_lvalue_reference,
detail::fail_when_same<typename detail::traits<T>::add_member_lvalue_reference,
detail::abominable_functions_not_supported_on_this_compiler,
this_compiler_doesnt_support_abominable_function_types>,
detail::fail_if_invalid<
typename detail::traits<T>::add_member_lvalue_reference,
member_qualifiers_are_illegal_for_this_type>>;
#else
detail::try_but_fail_if_invalid<
typename detail::traits<T>::add_member_lvalue_reference,
member_qualifiers_are_illegal_for_this_type>;
#endif // #ifdef BOOST_CLBL_TRTS_DISABLE_ABOMINABLE_FUNCTIONS
#endif // #ifdef BOOST_CLBL_TRTS_DISABLE_REFERENCE_QUALIFIERS
namespace detail {
template<typename T, typename = std::false_type>
struct add_member_lvalue_reference_impl {};
template<typename T>
struct add_member_lvalue_reference_impl <T, typename std::is_same<
add_member_lvalue_reference_t<T>, detail::dummy>::type>
{
using type = add_member_lvalue_reference_t<T>;
};
}
//->
template<typename T>
struct add_member_lvalue_reference
: detail::add_member_lvalue_reference_impl<T> {};
//<-
}} // namespace boost::callable_traits
//->
/*`
[heading Constraints]
* `T` must be a function type or a member function pointer type
* If `T` is a pointer, it may not be cv/ref qualified
[heading Behavior]
* A substitution failure occurs if the constraints are violated.
* Adds a member lvalue reference qualifier (`&`) to `T`, if not already present.
* If an rvalue reference qualifier is present, the lvalue reference qualifier replaces it (in accordance with reference collapsing rules).
[heading Input/Output Examples]
[table
[[`T`] [`add_member_lvalue_reference_t<T>`]]
[[`int()`] [`int() &`]]
[[`int(foo::*)()`] [`int(foo::*)() &`]]
[[`int(foo::*)() &`] [`int(foo::*)() &`]]
[[`int(foo::*)() &&`] [`int(foo::*)() &`]]
[[`int(foo::*)() const`] [`int(foo::*)() const &`]]
[[`int(foo::*)() transaction_safe`] [`int(foo::*)() & transaction_safe`]]
[[`int`] [(substitution failure)]]
[[`int (&)()`] [(substitution failure)]]
[[`int (*)()`] [(substitution failure)]]
[[`int foo::*`] [(substitution failure)]]
[[`int (foo::* const)()`] [(substitution failure)]]
]
[heading Example Program]
[import ../example/add_member_lvalue_reference.cpp]
[add_member_lvalue_reference]
[endsect]
*/
//]
#endif

View File

@@ -1,113 +0,0 @@
/*
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_ADD_MEMBER_RVALUE_REFERENCE_HPP
#define BOOST_CLBL_TRTS_ADD_MEMBER_RVALUE_REFERENCE_HPP
#include <boost/callable_traits/detail/core.hpp>
namespace boost { namespace callable_traits {
//[ add_member_rvalue_reference_hpp
/*`
[section:ref_add_member_rvalue_reference add_member_rvalue_reference]
[heading Header]
``#include <boost/callable_traits/add_member_rvalue_reference.hpp>``
[heading Definition]
*/
#ifdef BOOST_CLBL_TRTS_DISABLE_REFERENCE_QUALIFIERS
template<typename T>
struct add_member_rvalue_reference_t {
static_assert(std::is_same<T, detail::dummy>::value,
"Reference member qualifiers are not supported by this configuration.");
};
#else
template<typename T>
using add_member_rvalue_reference_t = //see below
//<-
#ifdef BOOST_CLBL_TRTS_DISABLE_ABOMINABLE_FUNCTIONS
detail::sfinae_try<
typename detail::traits<T>::add_member_rvalue_reference,
detail::fail_when_same<typename detail::traits<T>::add_member_rvalue_reference,
detail::abominable_functions_not_supported_on_this_compiler,
this_compiler_doesnt_support_abominable_function_types>,
detail::fail_if_invalid<typename detail::traits<T>::add_member_rvalue_reference,
member_qualifiers_are_illegal_for_this_type>>;
#else
detail::try_but_fail_if_invalid<
typename detail::traits<T>::add_member_rvalue_reference,
member_qualifiers_are_illegal_for_this_type>;
#endif // #ifdef BOOST_CLBL_TRTS_DISABLE_ABOMINABLE_FUNCTIONS
#endif // #ifdef BOOST_CLBL_TRTS_DISABLE_REFERENCE_QUALIFIERS
namespace detail {
template<typename T, typename = std::false_type>
struct add_member_rvalue_reference_impl {};
template<typename T>
struct add_member_rvalue_reference_impl <T, typename std::is_same<
add_member_rvalue_reference_t<T>, detail::dummy>::type>
{
using type = add_member_rvalue_reference_t<T>;
};
}
//->
template<typename T>
struct add_member_rvalue_reference
: detail::add_member_rvalue_reference_impl<T> {};
//<-
}} // namespace boost::callable_traits
//->
/*`
[heading Constraints]
* `T` must be a function type or a member function pointer type
* If `T` is a pointer, it may not be cv/ref qualified
[heading Behavior]
* A substitution failure occurs if the constraints are violated.
* Adds a member rvalue reference qualifier (`&&`) to `T`, if not already present.
* If an lvalue reference qualifier is present, the lvalue reference qualifier remains (in accordance with reference collapsing rules).
[heading Input/Output Examples]
[table
[[`T`] [`add_member_rvalue_reference_t<T>`]]
[[`int()`] [`int() &&`]]
[[`int(foo::*)()`] [`int(foo::*)() &&`]]
[[`int(foo::*)() &`] [`int(foo::*)() &`]]
[[`int(foo::*)() &&`] [`int(foo::*)() &&`]]
[[`int(foo::*)() const`] [`int(foo::*)() const &&`]]
[[`int(foo::*)() transaction_safe`] [`int(foo::*)() && transaction_safe`]]
[[`int`] [(substitution failure)]]
[[`int (&)()`] [(substitution failure)]]
[[`int (*)()`] [(substitution failure)]]
[[`int foo::*`] [(substitution failure)]]
[[`int (foo::* const)()`] [(substitution failure)]]
]
[heading Example Program]
[import ../example/add_member_rvalue_reference.cpp]
[add_member_rvalue_reference]
[endsect][/section:ref_add_member_rvalue_reference]
*/
//]
#endif

View File

@@ -1,100 +0,0 @@
/*
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_ADD_MEMBER_VOLATILE_HPP
#define BOOST_CLBL_TRTS_ADD_MEMBER_VOLATILE_HPP
#include <boost/callable_traits/detail/core.hpp>
namespace boost { namespace callable_traits {
//[ add_member_volatile_hpp
/*`
[section:ref_add_member_volatile add_member_volatile]
[heading Header]
``#include <boost/callable_traits/add_member_volatile.hpp>``
[heading Definition]
*/
template<typename T>
using add_member_volatile_t = //see below
//<-
#ifdef BOOST_CLBL_TRTS_DISABLE_ABOMINABLE_FUNCTIONS
detail::sfinae_try<
typename detail::traits<T>::add_member_volatile,
detail::fail_when_same<typename detail::traits<T>::add_member_volatile,
detail::abominable_functions_not_supported_on_this_compiler,
this_compiler_doesnt_support_abominable_function_types>,
detail::fail_if_invalid<
typename detail::traits<T>::add_member_volatile,
member_qualifiers_are_illegal_for_this_type>>;
#else
detail::try_but_fail_if_invalid<
typename detail::traits<T>::add_member_volatile,
member_qualifiers_are_illegal_for_this_type>;
#endif // #ifdef BOOST_CLBL_TRTS_DISABLE_ABOMINABLE_FUNCTIONS
namespace detail {
template<typename T, typename = std::false_type>
struct add_member_volatile_impl {};
template<typename T>
struct add_member_volatile_impl <T, typename std::is_same<
add_member_volatile_t<T>, detail::dummy>::type>
{
using type = add_member_volatile_t<T>;
};
}
//->
template<typename T>
struct add_member_volatile : detail::add_member_volatile_impl<T> {};
//<-
}} // namespace boost::callable_traits
//->
/*`
[heading Constraints]
* `T` must be a function type or a member function pointer type
* If `T` is a pointer, it may not be cv/ref qualified
[heading Behavior]
* A substitution failure occurs if the constraints are violated.
* Adds a member volatile qualifier to `T`, if not already present.
[heading Input/Output Examples]
[table
[[`T`] [`add_member_volatile_t<T>`]]
[[`int()`] [`int() volatile`]]
[[`int(foo::*)()`] [`int(foo::*)() volatile`]]
[[`int(foo::*)() &`] [`int(foo::*)() volatile &`]]
[[`int(foo::*)() &&`] [`int(foo::*)() volatile &&`]]
[[`int(foo::*)() const`] [`int(foo::*)() const volatile`]]
[[`int(foo::*)() transaction_safe`] [`int(foo::*)() volatile transaction_safe`]]
[[`int`] [(substitution failure)]]
[[`int (&)()`] [(substitution failure)]]
[[`int (*)()`] [(substitution failure)]]
[[`int foo::*`] [(substitution failure)]]
[[`int (foo::* const)()`] [(substitution failure)]]
]
[heading Example Program]
[import ../example/add_member_volatile.cpp]
[add_member_volatile]
[endsect][/section:ref_add_member_volatile]
*/
//]
#endif

View File

@@ -1,108 +0,0 @@
/*
@file add_noexcept
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_ADD_NOEXCEPT_HPP
#define BOOST_CLBL_TRTS_ADD_NOEXCEPT_HPP
#include <boost/callable_traits/detail/core.hpp>
namespace boost { namespace callable_traits {
BOOST_CLBL_TRTS_DEFINE_SFINAE_ERROR_ORIGIN(add_noexcept)
BOOST_CLBL_TRTS_SFINAE_MSG(add_noexcept, cannot_add_noexcept_to_this_type)
#ifndef BOOST_CLBL_TRTS_ENABLE_NOEXCEPT_TYPES
template<typename T>
struct add_noexcept_t {
static_assert(std::is_same<T, detail::dummy>::value,
"noexcept types not supported by this configuration.");
};
template<typename T>
struct add_noexcept {
static_assert(std::is_same<T, detail::dummy>::value,
"noexcept types not supported by this configuration.");
};
#else
//[ add_noexcept_hpp
/*`
[section:ref_add_noexcept add_noexcept]
[heading Header]
``#include <boost/callable_traits/add_noexcept.hpp>``
[heading Definition]
*/
template<typename T>
using add_noexcept_t = //see below
//<-
detail::try_but_fail_if_invalid<
typename detail::traits<T>::add_noexcept,
cannot_add_noexcept_to_this_type>;
namespace detail {
template<typename T, typename = std::false_type>
struct add_noexcept_impl {};
template<typename T>
struct add_noexcept_impl <T, typename std::is_same<
add_noexcept_t<T>, detail::dummy>::type>
{
using type = add_noexcept_t<T>;
};
}
//->
template<typename T>
struct add_noexcept : detail::add_noexcept_impl<T> {};
//<-
#endif // #ifdef BOOST_CLBL_TRTS_ENABLE_NOEXCEPT_TYPES
}} // namespace boost::callable_traits
//->
/*`
[heading Constraints]
* `T` must be one of the following:
* function type
* function pointer type
* function reference type
* member function pointer type
* If `T` is a pointer, it may not be cv/ref qualified
[heading Behavior]
* A substitution failure occurs if the constraints are violated.
* Adds a `noexcept` specifier to `T`, if not already present.
[heading Input/Output Examples]
[table
[[`T`] [`add_noexcept_t<T>`]]
[[`int()`] [`int() noexcept`]]
[[`int (&)()`] [`int(&)() noexcept`]]
[[`int (*)()`] [`int(*)() noexcept`]]
[[`int(foo::*)()`] [`int(foo::*)() noexcept`]]
[[`int(foo::*)() &`] [`int(foo::*)() & noexcept`]]
[[`int(foo::*)() &&`] [`int(foo::*)() && noexcept`]]
[[`int(foo::*)() const transaction_safe`] [`int(foo::*)() const transaction_safe noexcept`]]
[[`int(foo::*)() noexcept`] [`int(foo::*)() noexcept`]]
[[`int`] [(substitution failure)]]
[[`int foo::*`] [(substitution failure)]]
[[`int (*&)()`] [(substitution failure)]]
]
[heading Example Program]
[import ../example/add_noexcept.cpp]
[add_noexcept]
[endsect]
*/
//]
#endif // #ifndef BOOST_CLBL_TRTS_ADD_NOEXCEPT_HPP

View File

@@ -1,110 +0,0 @@
/*
@file add_transaction_safe
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_ADD_TRANSACTION_SAFE_HPP
#define BOOST_CLBL_TRTS_ADD_TRANSACTION_SAFE_HPP
#include <boost/callable_traits/detail/core.hpp>
namespace boost { namespace callable_traits {
BOOST_CLBL_TRTS_DEFINE_SFINAE_ERROR_ORIGIN(add_transaction_safe)
BOOST_CLBL_TRTS_SFINAE_MSG(add_transaction_safe, cannot_add_transaction_safe_to_this_type)
#ifndef BOOST_CLBL_TRTS_ENABLE_TRANSACTION_SAFE
template<typename T>
struct add_transaction_safe_t {
static_assert(std::is_same<T, detail::dummy>::value,
"transaction_safe not supported by this configuration.");
};
template<typename T>
struct add_transaction_safe {
static_assert(std::is_same<T, detail::dummy>::value,
"transaction_safe not supported by this configuration.");
};
#else
//[ add_transaction_safe_hpp
/*`
[section:ref_add_transaction_safe add_transaction_safe]
[heading Header]
``#include <boost/callable_traits/add_transaction_safe.hpp>``
[heading Definition]
*/
template<typename T>
using add_transaction_safe_t = //see below
//<-
detail::try_but_fail_if_invalid<
typename detail::traits<T>::add_transaction_safe,
cannot_add_transaction_safe_to_this_type>;
namespace detail {
template<typename T, typename = std::false_type>
struct add_transaction_safe_impl {};
template<typename T>
struct add_transaction_safe_impl <T, typename std::is_same<
add_transaction_safe_t<T>, detail::dummy>::type>
{
using type = add_transaction_safe_t<T>;
};
}
//->
template<typename T>
struct add_transaction_safe
: detail::add_transaction_safe_impl<T> {};
//<-
#endif // #ifndef BOOST_CLBL_TRTS_ENABLE_TRANSACTION_SAFE
}} // namespace boost::callable_traits
//->
/*`
[heading Constraints]
* `T` must be one of the following:
* function type
* function pointer type
* function reference type
* member function pointer type
* If `T` is a pointer, it may not be cv/ref qualified
[heading Behavior]
* A substitution failure occurs if the constraints are violated.
* Adds the `transaction_safe` specifier to `T`, if not already present.
[heading Input/Output Examples]
[table
[[`T`] [`add_transaction_safe_t<T>`]]
[[`int()`] [`int() transaction_safe`]]
[[`int (&)()`] [`int(&)() transaction_safe`]]
[[`int (*)()`] [`int(*)() transaction_safe`]]
[[`int(foo::*)()`] [`int(foo::*)() transaction_safe`]]
[[`int(foo::*)() &`] [`int(foo::*)() & transaction_safe`]]
[[`int(foo::*)() &&`] [`int(foo::*)() && transaction_safe`]]
[[`int(foo::*)() const`] [`int(foo::*)() const transaction_safe`]]
[[`int(foo::*)() transaction_safe`] [`int(foo::*)() transaction_safe`]]
[[`int`] [(substitution failure)]]
[[`int foo::*`] [(substitution failure)]]
[[`int (*&)()`] [(substitution failure)]]
]
[heading Example Program]
[import ../example/add_transaction_safe.cpp]
[add_transaction_safe]
[endsect]
*/
//]
#endif // #ifndef BOOST_CLBL_TRTS_ADD_TRANSACTION_SAFE_HPP

View File

@@ -1,90 +0,0 @@
/*
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_ADD_VARARGS_HPP
#define BOOST_CLBL_TRTS_ADD_VARARGS_HPP
#include <boost/callable_traits/detail/core.hpp>
namespace boost { namespace callable_traits {
//[ add_varargs_hpp
/*`
[section:ref_add_varargs add_varargs]
[heading Header]
``#include <boost/callable_traits/add_varargs.hpp>``
[heading Definition]
*/
template<typename T>
using add_varargs_t = //see below
//<-
detail::try_but_fail_if_invalid<
typename detail::traits<T>::add_varargs,
varargs_are_illegal_for_this_type>;
namespace detail {
template<typename T, typename = std::false_type>
struct add_varargs_impl {};
template<typename T>
struct add_varargs_impl <T, typename std::is_same<
add_varargs_t<T>, detail::dummy>::type>
{
using type = add_varargs_t<T>;
};
}
//->
template<typename T>
struct add_varargs : detail::add_varargs_impl<T> {};
//<-
}} // namespace boost::callable_traits
//->
/*`
[heading Constraints]
* `T` must be one of the following:
* function type
* function pointer type
* function reference type
* member function pointer type
* If `T` is a pointer, it may not be cv/ref qualified
[heading Behavior]
* A substitution failure occurs if the constraints are violated.
* Adds C-style variadics (`...`) to the signature of `T`, if not already present.
[heading Input/Output Examples]
[table
[[`T`] [`add_varargs_t<T>`]]
[[`int()`] [`int(...)`]]
[[`int(int)`] [`int(int, ...)`]]
[[`int (&)()`] [`int(&)(...)`]]
[[`int (*)()`] [`int(*)(...)`]]
[[`int (*)(...)`] [`int(*)(...)`]]
[[`int(foo::*)()`] [`int(foo::*)(...)`]]
[[`int(foo::*)() &`] [`int(foo::*)(...) &`]]
[[`int(foo::*)() &&`] [`int(foo::*)(...) &&`]]
[[`int(foo::*)() const`] [`int(foo::*)(...) const`]]
[[`int(foo::*)() transaction_safe`] [`int(foo::*)(...) transaction_safe`]]
[[`int`] [(substitution failure)]]
[[`int foo::*`] [(substitution failure)]]
[[`int (*&)()`] [(substitution failure)]]
]
[heading Example Program]
[import ../example/add_varargs.cpp]
[add_varargs]
[endsect]
*/
//]
#endif

View File

@@ -1,123 +0,0 @@
/*
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_APPLY_MEMBER_POINTER_HPP
#define BOOST_CLBL_TRTS_APPLY_MEMBER_POINTER_HPP
#include <boost/callable_traits/detail/core.hpp>
namespace boost { namespace callable_traits {
BOOST_CLBL_TRTS_DEFINE_SFINAE_ERROR_ORIGIN(apply_member_pointer)
BOOST_CLBL_TRTS_SFINAE_MSG(apply_member_pointer, members_cannot_have_a_type_of_void)
BOOST_CLBL_TRTS_SFINAE_MSG(apply_member_pointer, second_template_argument_must_be_a_class_or_struct)
namespace detail {
template<typename T, typename C, bool = std::is_class<C>::value>
struct make_member_pointer;
template<typename T, typename C>
struct make_member_pointer<T, C, true> {
using type = typename std::remove_reference<T>::type C::*;
};
template<typename C>
struct make_member_pointer<void, C, true> {
using type = invalid_type;
};
template<typename T, typename C>
struct make_member_pointer<T, C, false> {
using type = error_type<T>;
};
template<typename T, typename C>
using make_member_pointer_t = typename make_member_pointer<T, C>::type;
}
//[ apply_member_pointer_hpp
/*`
[section:ref_apply_member_pointer apply_member_pointer]
[heading Header]
``#include <boost/callable_traits/apply_member_pointer.hpp>``
[heading Definition]
*/
template<typename T, typename C>
using apply_member_pointer_t = //see below
//<-
detail::sfinae_try<
detail::fallback_if_invalid<
typename detail::traits<T>::template apply_member_pointer<C>,
typename detail::make_member_pointer<T, C>::type>,
detail::fail_when_same<void, T, members_cannot_have_a_type_of_void>,
detail::fail_if<!std::is_class<C>::value,
second_template_argument_must_be_a_class_or_struct> >;
namespace detail {
template<typename T, typename C, typename = std::false_type>
struct apply_member_pointer_impl {};
template<typename T, typename C>
struct apply_member_pointer_impl <T, C, typename std::is_same<
apply_member_pointer_t<T, C>, detail::dummy>::type>
{
using type = apply_member_pointer_t<T, C>;
};
}
//->
template<typename T, typename C>
struct apply_member_pointer : detail::apply_member_pointer_impl<T, C> {};
//<-
}} // namespace boost::callable_traits
//->
/*`
[heading Constraints]
* `T` may be any type except `void`
* `C` must be a user-defined type
[heading Behavior]
* A substitution failure occurs if the constraints are violated.
* When `T` is a function, function pointer (unqualified), or function reference, then the aliased type is a member function pointer of `C` with the same parameters and return type.
* When `T` is a member function pointer (unqualified) of any type, the aliased type is a member function pointer of `C` with the same parameters and return type.
* Otherwise, the aliased type is a member data pointer equivalent to `std::remove_reference_t<T> C::*`.
[heading Input/Output Examples]
[table
[[`T`] [`apply_member_pointer_t<T, foo>`]]
[[`int()`] [`int(foo::*)()`]]
[[`int (&)()`] [`int(foo::*)()`]]
[[`int (*)()`] [`int(foo::*)()`]]
[[`int(bar::*)()`] [`int(foo::*)()`]]
[[`int(bar::*)() &`] [`int(foo::*)() &`]]
[[`int(bar::*)() &&`] [`int(foo::*)() &&`]]
[[`int(bar::*)() const`] [`int(foo::*)() const`]]
[[`int(bar::*)() transaction_safe`] [`int(foo::*)() transaction_safe`]]
[[`int bar::*`] [`int foo::*`]]
[[`int`] [`int foo::*`]]
[[`int &`] [`int foo::*`]]
[[`const int &`] [`const int foo::*`]]
[[`int (*const)()`] [`int (*const foo::*)()`]]
[[`void`] [(substitution failure)]]
]
[heading Example Program]
[import ../example/apply_member_pointer.cpp]
[apply_member_pointer]
[endsect]
*/
//]
#endif

View File

@@ -1,109 +0,0 @@
/*
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_APPLY_RETURN_HPP
#define BOOST_CLBL_TRTS_APPLY_RETURN_HPP
#include <boost/callable_traits/detail/core.hpp>
namespace boost { namespace callable_traits {
BOOST_CLBL_TRTS_DEFINE_SFINAE_ERROR_ORIGIN(apply_return)
BOOST_CLBL_TRTS_SFINAE_MSG(apply_return, invalid_types_for_apply_return)
namespace detail {
template<typename T, typename R>
struct apply_return_helper {
using type = typename detail::traits<T>::template apply_return<R>;
};
//special case
template<typename... Args, typename R>
struct apply_return_helper<std::tuple<Args...>, R> {
using type = R(Args...);
};
}
//[ apply_return_hpp
/*`
[section:ref_apply_return apply_return]
[heading Header]
``#include <boost/callable_traits/apply_return.hpp>``
[heading Definition]
*/
template<typename T, typename R>
using apply_return_t = //see below
//<-
detail::try_but_fail_if_invalid<
typename detail::apply_return_helper<T, R>::type,
invalid_types_for_apply_return>;
namespace detail {
template<typename T, typename R, typename = std::false_type>
struct apply_return_impl {};
template<typename T, typename R>
struct apply_return_impl <T, R, typename std::is_same<
apply_return_t<T, R>, detail::dummy>::type>
{
using type = apply_return_t<T, R>;
};
}
//->
template<typename T, typename R>
struct apply_return : detail::apply_return_impl<T, R> {};
//<-
}} // namespace boost::callable_traits
//->
/*`
[heading Constraints]
* `T` must one of the following:
* `std::tuple` template instantiation
* function
* function pointer
* function reference
* member function pointer
* member data pointer
* If `T` is a pointer, it may not be cv/ref qualified
[heading Behavior]
* When `T` is `std::tuple<Args...>`, the aliased type is `R(Args...)`.
* When `T` is a function, function pointer, function reference, or member function pointer, the aliased type's return type is `R`, but is otherwise identical to `T`.
* When `T` is a member data pointer of class `foo` to a `U` type (such that `T` is `U foo::*`), the aliased type is `R foo::*`.
[heading Input/Output Examples]
[table
[[`T`] [`apply_return_t<T, float>`]]
[[`std::tuple<int, int>`] [`float(int, int)`]]
[[`int()`] [`float()`]]
[[`int (&)()`] [`float(&)()`]]
[[`int (*)()`] [`float(*)()`]]
[[`int (*)(...)`] [`float(*)()`]]
[[`int(foo::*)()`] [`float(foo::*)()`]]
[[`int(foo::*)() &`] [`float(foo::*)() &`]]
[[`int(foo::*)() &&`] [`float(foo::*)() &&`]]
[[`int(foo::*)() const`] [`float(foo::*)() const`]]
[[`int(foo::*)() transaction_safe`] [`float(foo::*)() transaction_safe`]]
[[`int foo::*`] [`float foo::*`]]
[[`int`] [(substitution failure)]]
[[`int (*const)()`] [(substitution failure)]]
]
[heading Example Program]
[/import ../example/apply_return.cpp]
[apply_return]
[endsect]
*/
//]
#endif

View File

@@ -1,97 +0,0 @@
/*
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_ARGS_HPP
#define BOOST_CLBL_TRTS_ARGS_HPP
#include <boost/callable_traits/detail/core.hpp>
namespace boost { namespace callable_traits {
//[ args_hpp
/*`[section:ref_args args]
[heading Header]
``#include <boost/callable_traits/args.hpp>``
[heading Definition]
*/
template<typename T, template<class...> class Container = std::tuple>
using args_t = //see below
//<-
detail::try_but_fail_if_invalid<
typename detail::traits<
detail::shallow_decay<T>>::template expand_args<Container>,
cannot_expand_the_parameter_list_of_first_template_argument>;
namespace detail {
template<typename T, template<class...> class Container,
typename = std::false_type>
struct args_impl {};
template<typename T, template<class...> class Container>
struct args_impl <T, Container, typename std::is_same<
args_t<T, Container>, detail::dummy>::type>
{
using type = args_t<T, Container>;
};
}
//->
template<typename T,
template<class...> class Container = std::tuple>
struct args : detail::args_impl<T, Container> {};
//<-
}} // namespace boost::callable_traits
//->
/*`
[heading Constraints]
* `T` must be one of the following:
* function
* function pointer
* function reference
* member function pointer
* member data pointer
* user-defined type with a non-overloaded `operator()`
* type of a non-generic lambda
[heading Behavior]
* When the constraints are violated, a substitution failure occurs.
* When `T` is a function, function pointer, or function reference, the aliased type is `Container` instantiated with the function's parameter types.
* When `T` is a function object, the aliased type is `Container` instantiated with the `T::operator()` parameter types.
* When `T` is a member function pointer, the aliased type is a `Container` instantiation, where the first type argument is a reference to the parent class of `T`, qualified according to the member qualifiers on `T`, such that the first type is equivalent to `boost::callable_traits::qualified_class_of_t<T>`. The subsequent type arguments, if any, are the parameter types of the member function.
* When `T` is a member data pointer, the aliased type is `Container` with a single element, which is a `const` reference to the parent class of `T`.
[heading Input/Output Examples]
[table
[[`T`] [`args_t<T>`]]
[[`void(float, char, int)`] [`std::tuple<float, char, int>`]]
[[`void(*)(float, char, int)`] [`std::tuple<float, char, int`]]
[[`void(&)(float, char, int)`] [`std::tuple<float, char, int`]]
[[`void(float, char, int) const &&`][`std::tuple<float, char, int>`]]
[[`void(*)()`] [`std::tuple<>`]]
[[`void(foo::* const &)(float, char, int)`] [`std::tuple<foo&, float, char, int>`]]
[[`int(foo::*)(int) const`] [`std::tuple<const foo&, int>`]]
[[`void(foo::*)() volatile &&`] [`std::tuple<volatile foo &&>`]]
[[`int foo::*`] [`std::tuple<const foo&>`]]
[[`const int foo::*`] [`std::tuple<const foo&>`]]
[[`int`] [(substitution failure)]]
[[`int (*const)()`] [(substitution failure)]]
]
[heading Example Program]
[import ../example/args.cpp]
[args]
[endsect]
*/
//]
#endif // #ifndef BOOST_CLBL_TRTS_ARGS_HPP

View File

@@ -1,75 +0,0 @@
/*
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_class_of_HPP
#define BOOST_CLBL_TRTS_class_of_HPP
#include <boost/callable_traits/detail/core.hpp>
namespace boost { namespace callable_traits {
//[ class_of_hpp
/*`
[section:ref_class_of class_of]
[heading Header]
``#include <boost/callable_traits/class_of.hpp>``
[heading Definition]
*/
template<typename T>
using class_of_t = //see below
//<-
detail::try_but_fail_if_invalid<
typename detail::traits<detail::shallow_decay<T>>::class_type,
type_is_not_a_member_pointer>;
namespace detail {
template<typename T, typename = std::false_type>
struct class_of_impl {};
template<typename T>
struct class_of_impl <T, typename std::is_same<
class_of_t<T>, detail::dummy>::type>
{
using type = class_of_t<T>;
};
}
//->
template<typename T>
struct class_of : detail::class_of_impl<T> {};
//<-
}} // namespace boost::callable_traits
//->
/*`
[heading Constraints]
* `T` must be a member pointer
[heading Behavior]
* A substitution failure occurs if the constraints are violated.
* The aliased type is the parent class of the member. In other words, if `T` is expanded to `U C::*`, the aliased type is `C`.
[heading Input/Output Examples]
[table
[[`T`] [`class_of_t<T>`]]
[[`int foo::*`] [`foo`]]
[[`void(foo::* const &)() const`] [`foo`]]
]
[heading Example Program]
[import ../example/class_of.cpp]
[class_of]
[endsect]
*/
//]
#endif // #ifndef BOOST_CLBL_TRTS_class_of_HPP

View File

@@ -1,109 +0,0 @@
/*
@Copyright Barrett Adair 2016-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_DETAIL_CONFIG_HPP
#define BOOST_CLBL_TRTS_DETAIL_CONFIG_HPP
#include <type_traits>
#include <tuple>
#include <utility>
#include <cstdint>
#define BOOST_CLBL_TRTS_EMPTY_
#define BOOST_CLBL_TRTS_EMPTY BOOST_CLBL_TRTS_EMPTY_
#ifdef __cpp_transactional_memory
# define BOOST_CLBL_TRTS_ENABLE_TRANSACTION_SAFE
#endif
#ifdef __cpp_inline_variables
# define BOOST_CLBL_TRAITS_INLINE_VAR inline
#else
# define BOOST_CLBL_TRAITS_INLINE_VAR
#endif
#ifdef __cpp_noexcept_function_type
# define BOOST_CLBL_TRTS_ENABLE_NOEXCEPT_TYPES
#endif
#ifdef BOOST_CLBL_TRTS_ENABLE_TRANSACTION_SAFE
# define BOOST_CLBL_TRTS_TRANSACTION_SAFE_SPECIFIER transaction_safe
#else
# define BOOST_CLBL_TRTS_TRANSACTION_SAFE_SPECIFIER
#endif
#ifndef __clang__
# if defined(__GNUC__)
# define BOOST_CLBL_TRTS_GCC
# if __GNUC__ >= 6
# define BOOST_CLBL_TRTS_GCC_AT_LEAST_6_0_0
# endif
# if __GNUC__ < 5
# define BOOST_CLBL_TRTS_GCC_OLDER_THAN_5_0_0
# endif
# if __GNUC__ >= 5
# define BOOST_CLBL_TRTS_GCC_AT_LEAST_4_9_2
# elif __GNUC__ == 4 && __GNUC_MINOR__ == 9 && __GNUC_PATCHLEVEL__ >= 2
# define BOOST_CLBL_TRTS_GCC_AT_LEAST_4_9_2
# else
# define BOOST_CLBL_TRTS_GCC_OLDER_THAN_4_9_2
# endif //#if __GNUC__ >= 5
# endif //#if defined __GNUC__
#endif // #ifndef __clang__
#ifdef _MSC_VER
# ifdef __clang__
# define BOOST_CLBL_TRTS_CLANG_C2
# else
# define BOOST_CLBL_TRTS_MSVC
# endif // #ifdef __clang__
#endif // #ifdef _MSC_VER
#define BOOST_CLBL_TRTS_IX_SEQ(...) ::std::index_sequence< __VA_ARGS__ >
#define BOOST_CLBL_TRTS_MAKE_IX_SEQ(...) ::std::make_index_sequence< __VA_ARGS__ >
#define BOOST_CLBL_TRTS_DISJUNCTION(...) ::std::disjunction< __VA_ARGS__ >
#ifndef __cpp_variable_templates
# define BOOST_CLBL_TRTS_DISABLE_VARIABLE_TEMPLATES
#endif
#ifndef __cpp_lib_logical_traits
# include <boost/callable_traits/detail/polyfills/disjunction.hpp>
#endif //__cpp_lib_logical_traits
#ifndef __cpp_lib_integer_sequence
# include <boost/callable_traits/detail/polyfills/make_index_sequence.hpp>
#endif // __cpp_lib_integer_sequence
#if defined(BOOST_CLBL_TRTS_MSVC) && !defined(BOOST_DISABLE_WIN32)
# define BOOST_CLBL_TRTS_DEFAULT_VARARGS_CC __cdecl
# define BOOST_CLBL_TRTS_PMF_VARGARGS_CDECL_DEFAULT
#else
# define BOOST_CLBL_TRTS_DEFAULT_VARARGS_CC
#endif // #if defined(BOOST_CLBL_TRTS_MSVC) && !defined(BOOST_DISABLE_WIN32))
#if (defined(BOOST_CLBL_TRTS_GCC) && !defined(BOOST_CLBL_TRTS_GCC_AT_LEAST_4_9_2)) || defined(__INTEL_COMPILER)
# define BOOST_CLBL_TRTS_DISABLE_REFERENCE_QUALIFIERS
# define BOOST_CLBL_TRTS_DISABLE_ABOMINABLE_FUNCTIONS
#endif // #if defined BOOST_CLBL_TRTS_GCC && !defined(BOOST_CLBL_TRTS_GCC_AT_LEAST_4_9_2)
#ifdef BOOST_CLBL_TRTS_DISABLE_ABOMINABLE_FUNCTIONS
# define BOOST_CLBL_TRTS_ABOMINABLE_CONST BOOST_CLBL_TRTS_EMPTY
# define BOOST_CLBL_TRTS_ABOMINABLE_VOLATILE BOOST_CLBL_TRTS_EMPTY
#else
# define BOOST_CLBL_TRTS_ABOMINABLE_CONST const
# define BOOST_CLBL_TRTS_ABOMINABLE_VOLATILE volatile
#endif // #ifdef BOOST_CLBL_TRTS_DISABLE_ABOMINABLE_FUNCTIONS
#ifdef BOOST_CLBL_TRTS_ENABLE_NOEXCEPT_TYPES
# define BOOST_CLBL_TRTS_NOEXCEPT_SPECIFIER noexcept
#else
# define BOOST_CLBL_TRTS_NOEXCEPT_SPECIFIER BOOST_CLBL_TRTS_EMPTY
#endif // #ifdef BOOST_CLBL_TRTS_ENABLE_NOEXCEPT_TYPES
#endif // #ifndef BOOST_CLBL_TRTS_DETAIL_CONFIG_HPP

View File

@@ -1,19 +0,0 @@
/*
@Copyright Barrett Adair 2016-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_DETAIL_CORE_HPP
#define BOOST_CLBL_TRTS_DETAIL_CORE_HPP
#include <boost/callable_traits/detail/utility.hpp>
#include <boost/callable_traits/detail/traits.hpp>
#include <boost/callable_traits/detail/function_object.hpp>
#include <boost/callable_traits/detail/function.hpp>
#include <boost/callable_traits/detail/pmf.hpp>
#include <boost/callable_traits/detail/pmd.hpp>
#endif // #ifndef BOOST_CLBL_TRTS_DETAIL_CORE_HPP

View File

@@ -1,207 +0,0 @@
/*
Copyright Barrett Adair 2016-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http ://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_DETAIL_DEFAULT_BOOST_CLBL_TRTS_HPP
#define BOOST_CLBL_TRTS_DETAIL_DEFAULT_BOOST_CLBL_TRTS_HPP
namespace boost { namespace callable_traits { namespace detail {
template<typename T = void>
struct default_callable_traits {
// value is used by all traits classes to participate
// in the <callable_traits/detail/traits.hpp> disjunction.
static constexpr bool value = false;
// used facilitate the disjunction in
// <callable_traits/detail/traits.hpp>
using traits = default_callable_traits;
using error_t = error_type<T>;
// represents the type under consideration
using type = error_t;
// std::true_type for callables with C-style variadics
using has_varargs = std::false_type;
using return_type = error_t;
// arg_types is a std::tuple of argument types for
// callables that are not overloaded/templated function objects.
// arg_types IS defined in terms of INVOKE, which means
// a PMF's arg_types tuple will use a reference to its
// parent class as the first argument, with qualifiers added to
// match the PMF's own qualifiers.
using arg_types = error_t;
// arg_types without the decltype(*this) parameter for member functions
using non_invoke_arg_types = error_t;
// An "approximation" of a callable type, in the form
// of a plain function type. Defined in terms of INVOKE.
// An identity alias for qualified/unqualified plain function
// types.
using function_type = error_t;
// Used to smoothen the edges between PMFs and function objects
using function_object_signature = error_t;
// An identity alias for qualified/unqualified plain function
// types. Equivalent to remove_member_pointer for PMFs. Same
// as function_type for other callable types.
using qualified_function_type = error_t;
// Removes C-style variadics from a signature, if present.
// Aliases error_t for function objects and PMDs.
using remove_varargs = error_t;
// Adds C-style variadics to a signature. Aliases
// error_t for function objects and PMDs.
using add_varargs = error_t;
// std::true_type when the signature includes noexcept, when
// the feature is available
using is_noexcept = std::false_type;
// adds noexcept to a signature if the feature is available
using add_noexcept = error_t;
// removes noexcept from a signature if present
using remove_noexcept = error_t;
// std::true_type when the signature includes transaction_safe, when
// the feature is available
using is_transaction_safe = std::false_type;
// adds transaction_safe to a signature if the feature is available
using add_transaction_safe = error_t;
// removes transaction_safe from a signature if present
using remove_transaction_safe = error_t;
// The class of a PMD or PMF. error_t for other types
using class_type = error_t;
// The qualified reference type of class_type. error_t
// for non-member-pointers.
using invoke_type = error_t;
// Removes reference qualifiers from a signature.
using remove_reference = error_t;
// Adds an lvalue qualifier to a signature, in arbitrary
// accordance with C++11 reference collapsing rules.
using add_member_lvalue_reference = error_t;
// Adds an rvalue qualifier to a signature, in arbitrary
// accordance with C++11 reference collapsing rules.
using add_member_rvalue_reference = error_t;
// Adds a const qualifier to a signature.
using add_member_const = error_t;
// Adds a volatile qualifier to a signature.
using add_member_volatile = error_t;
// Adds both const and volatile qualifiers to a signature.
using add_member_cv = error_t;
// Removes a const qualifier from a signature, if present.
using remove_member_const = error_t;
// Removes a volatile qualifier from a signature, if present.
using remove_member_volatile = error_t;
// Removes both const and volatile qualifiers from a
// signature, if any.
using remove_member_cv = error_t;
// Removes the member pointer from PMDs and PMFs. An identity
// alias for other callable types.
using remove_member_pointer = error_t;
// Changes the parent class type for PMDs and PMFs. Turns
// function pointers, function references, and
// qualified/unqualified function types into PMFs. Turns
// everything else into member data pointers.
template<typename C,
typename U = T,
typename K = typename std::remove_reference<U>::type,
typename L = typename std::conditional<
std::is_same<void, K>::value, error_t, K>::type,
typename Class = typename std::conditional<
std::is_class<C>::value, C, error_t>::type>
using apply_member_pointer = typename std::conditional<
std::is_same<L, error_t>::value || std::is_same<Class, error_t>::value,
error_t, L Class::*>::type;
// Changes the return type of PMFs, function pointers, function
// references, and qualified/unqualified function types. Changes
// the data type of PMDs. error_t for function objects.
template<typename>
using apply_return = error_t;
// Expands the argument types into a template
template<template<class...> class Container>
using expand_args = error_t;
template<template<class...> class Container, typename... RightArgs>
using expand_args_left = error_t;
template<template<class...> class Container, typename... LeftArgs>
using expand_args_right = error_t;
using clear_args = error_t;
template<typename... NewArgs>
using push_front = error_t;
template<typename... NewArgs>
using push_back = error_t;
template<std::size_t ElementCount>
using pop_front = error_t;
template<std::size_t ElementCount>
using pop_back = error_t;
template<std::size_t Index, typename... NewArgs>
using insert_args = error_t;
template<std::size_t Index, std::size_t Count>
using remove_args = error_t;
template<std::size_t Index, typename... NewArgs>
using replace_args = error_t;
static constexpr qualifier_flags cv_flags = cv_of<T>::value;
static constexpr qualifier_flags ref_flags = ref_of<T>::value;
static constexpr qualifier_flags q_flags = cv_flags | ref_flags;
using has_member_qualifiers = std::integral_constant<bool, q_flags != default_>;
using is_const_member = std::integral_constant<bool, 0 < (cv_flags & const_)>;
using is_volatile_member = std::integral_constant<bool, 0 < (cv_flags & volatile_)>;
using is_cv_member = std::integral_constant<bool, cv_flags == (const_ | volatile_)>;
#ifdef BOOST_CLBL_TRTS_DISABLE_REFERENCE_QUALIFIERS
using is_reference_member = std::false_type;
using is_lvalue_reference_member = std::false_type;
using is_rvalue_reference_member = std::false_type;
#else
using is_reference_member = std::integral_constant<bool, 0 < ref_flags>;
using is_lvalue_reference_member = std::integral_constant<bool, ref_flags == lref_>;
using is_rvalue_reference_member = std::integral_constant<bool, ref_flags == rref_>;
#endif //#ifdef BOOST_CLBL_TRTS_DISABLE_REFERENCE_QUALIFIERS
};
}}} // namespace boost::callable_traits::detail
#endif // BOOST_CLBL_TRTS_DETAIL_DEFAULT_BOOST_CLBL_TRTS_HPP

View File

@@ -1,54 +0,0 @@
#ifndef BOOST_CLBL_TRTS_DETAIL_FORWARD_DECLARATIONS
#define BOOST_CLBL_TRTS_DETAIL_FORWARD_DECLARATIONS
#include <boost/callable_traits/detail/config.hpp>
#include <boost/callable_traits/detail/default_callable_traits.hpp>
namespace boost { namespace callable_traits { namespace detail {
template<typename T>
struct function;
template<typename T>
struct has_normal_call_operator
{
template<typename N, N Value>
struct check { check(std::nullptr_t) {} };
template<typename U>
static std::int8_t test(
check<decltype(&U::operator()), &U::operator()>);
template<typename>
static std::int16_t test(...);
static constexpr bool value =
sizeof(test<T>(nullptr)) == sizeof(std::int8_t);
};
struct callable_dummy {
void operator()() {}
};
template<typename T>
using default_to_function_object = typename std::conditional<
has_normal_call_operator<T>::value,
T, callable_dummy>::type;
template<typename T>
struct pmf;
template<typename T>
struct pmd;
template<typename F, typename T = typename std::remove_reference<F>::type>
using function_object_base = typename std::conditional<
has_normal_call_operator<T>::value,
pmf<decltype(&default_to_function_object<T>::operator())>,
default_callable_traits<T>>::type;
template<typename T, typename Base = function_object_base<T>>
struct function_object;
}}} // namespace boost::callable_traits::detail
#endif // #ifndef BOOST_CLBL_TRTS_DETAIL_FORWARD_DECLARATIONS

View File

@@ -1,192 +0,0 @@
/*
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_DETAIL_FUNCTION_HPP
#define BOOST_CLBL_TRTS_DETAIL_FUNCTION_HPP
#include <boost/callable_traits/detail/config.hpp>
#include <boost/callable_traits/detail/qualifier_flags.hpp>
#include <boost/callable_traits/detail/forward_declarations.hpp>
#include <boost/callable_traits/detail/set_function_qualifiers.hpp>
#include <boost/callable_traits/detail/default_callable_traits.hpp>
namespace boost { namespace callable_traits { namespace detail {
template<typename T>
struct function : default_callable_traits<T> {};
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#include <boost/callable_traits/detail/unguarded/function.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#ifndef BOOST_CLBL_TRTS_DISABLE_ABOMINABLE_FUNCTIONS
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS const
#include <boost/callable_traits/detail/unguarded/function.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS volatile
#include <boost/callable_traits/detail/unguarded/function.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS const volatile
#include <boost/callable_traits/detail/unguarded/function.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#ifndef BOOST_CLBL_TRTS_DISABLE_REFERENCE_QUALIFIERS
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS &
#include <boost/callable_traits/detail/unguarded/function.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS &&
#include <boost/callable_traits/detail/unguarded/function.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS const &
#include <boost/callable_traits/detail/unguarded/function.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS const &&
#include <boost/callable_traits/detail/unguarded/function.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS volatile &
#include <boost/callable_traits/detail/unguarded/function.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS volatile &&
#include <boost/callable_traits/detail/unguarded/function.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS const volatile &
#include <boost/callable_traits/detail/unguarded/function.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS const volatile &&
#include <boost/callable_traits/detail/unguarded/function.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#endif // #ifndef BOOST_CLBL_TRTS_DISABLE_REFERENCE_QUALIFIERS
#endif // #ifndef BOOST_CLBL_TRTS_DISABLE_ABOMINABLE_FUNCTIONS
// function pointers
#define BOOST_CLBL_TRTS_CC_TAG dummy
#define BOOST_CLBL_TRTS_VARARGS_CC BOOST_CLBL_TRTS_DEFAULT_VARARGS_CC
#define BOOST_CLBL_TRTS_CC
#define BOOST_CLBL_TRTS_ST
#include <boost/callable_traits/detail/unguarded/function_ptr.hpp>
#include <boost/callable_traits/detail/unguarded/function_ptr_varargs.hpp>
#undef BOOST_CLBL_TRTS_ST
#undef BOOST_CLBL_TRTS_CC
#undef BOOST_CLBL_TRTS_CC_TAG
#undef BOOST_CLBL_TRTS_VARARGS_CC
/* ?
#ifdef BOOST_CLBL_TRTS_ENABLE_CDECL
#define BOOST_CLBL_TRTS_CC_TAG cdecl_tag
#define BOOST_CLBL_TRTS_VARARGS_CC __cdecl
#define BOOST_CLBL_TRTS_CC __cdecl
#define BOOST_CLBL_TRTS_ST
#include <boost/callable_traits/detail/unguarded/function_ptr.hpp>
#undef BOOST_CLBL_TRTS_ST
#undef BOOST_CLBL_TRTS_CC
#undef BOOST_CLBL_TRTS_CC_TAG
#undef BOOST_CLBL_TRTS_VARARGS_CC
#endif*/
#ifdef BOOST_CLBL_TRTS_ENABLE_STDCALL
#define BOOST_CLBL_TRTS_CC_TAG stdcall_tag
#define BOOST_CLBL_TRTS_VARARGS_CC BOOST_CLBL_TRTS_DEFAULT_VARARGS_CC
#define BOOST_CLBL_TRTS_CC __stdcall
#define BOOST_CLBL_TRTS_ST
#include <boost/callable_traits/detail/unguarded/function_ptr.hpp>
#undef BOOST_CLBL_TRTS_ST
#undef BOOST_CLBL_TRTS_CC
#undef BOOST_CLBL_TRTS_CC_TAG
#undef BOOST_CLBL_TRTS_VARARGS_CC
#endif
#ifdef BOOST_CLBL_TRTS_ENABLE_FASTCALL
#define BOOST_CLBL_TRTS_CC_TAG fastcall_tag
#define BOOST_CLBL_TRTS_VARARGS_CC BOOST_CLBL_TRTS_DEFAULT_VARARGS_CC
#define BOOST_CLBL_TRTS_CC __fastcall
#define BOOST_CLBL_TRTS_ST
#include <boost/callable_traits/detail/unguarded/function_ptr.hpp>
#undef BOOST_CLBL_TRTS_CC
#undef BOOST_CLBL_TRTS_ST
#undef BOOST_CLBL_TRTS_CC_TAG
#undef BOOST_CLBL_TRTS_VARARGS_CC
#endif
#ifdef BOOST_CLBL_TRTS_ENABLE_PASCAL
#define BOOST_CLBL_TRTS_CC_TAG pascal_tag
#define BOOST_CLBL_TRTS_VARARGS_CC BOOST_CLBL_TRTS_DEFAULT_VARARGS_CC
#define BOOST_CLBL_TRTS_CC
#define BOOST_CLBL_TRTS_ST pascal
#include <boost/callable_traits/detail/unguarded/function_ptr.hpp>
#undef BOOST_CLBL_TRTS_CC
#undef BOOST_CLBL_TRTS_ST
#undef BOOST_CLBL_TRTS_CC_TAG
#undef BOOST_CLBL_TRTS_VARARGS_CC
#endif
template<typename T>
struct function<T&> : std::conditional<function<T>::value,
function<T>, default_callable_traits<T&>>::type {
static constexpr const bool value = !std::is_pointer<T>::value;
using traits = function;
using base = function<T>;
using type = T&;
using remove_varargs = typename base::remove_varargs&;
using add_varargs = typename base::add_varargs&;
using remove_member_reference = reference_error;
using add_member_lvalue_reference = reference_error;
using add_member_rvalue_reference = reference_error;
using add_member_const = reference_error;
using add_member_volatile = reference_error;
using add_member_cv = reference_error;
using remove_member_const = reference_error;
using remove_member_volatile = reference_error;
using remove_member_cv = reference_error;
template<typename NewReturn>
using apply_return = typename base::template apply_return<NewReturn>&;
using clear_args = typename base::clear_args&;
template<typename... NewArgs>
using push_front = typename base::template push_front<NewArgs...>&;
template<typename... NewArgs>
using push_back = typename base::template push_back<NewArgs...>&;
template<std::size_t Count>
using pop_back = typename base::template pop_back<Count>&;
template<std::size_t Count>
using pop_front = typename base::template pop_front<Count>&;
template<std::size_t Index, typename... NewArgs>
using insert_args = typename base::template insert_args<Index, NewArgs...>&;
template<std::size_t Index, std::size_t Count>
using remove_args = typename base::template remove_args<Index, Count>&;
template<std::size_t Index, typename... NewArgs>
using replace_args = typename base::template replace_args<Index, NewArgs...>&;
};
}}} // namespace boost::callable_traits::detail
#endif // #ifndef BOOST_CLBL_TRTS_DETAIL_FUNCTION_HPP

View File

@@ -1,107 +0,0 @@
/*
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_DETAIL_FUNCTION_OBJECT_HPP
#define BOOST_CLBL_TRTS_DETAIL_FUNCTION_OBJECT_HPP
#include <boost/callable_traits/detail/pmf.hpp>
#include <boost/callable_traits/detail/default_callable_traits.hpp>
#include <boost/callable_traits/detail/forward_declarations.hpp>
#include <boost/callable_traits/detail/utility.hpp>
namespace boost { namespace callable_traits { namespace detail {
template<typename T, typename Base>
struct function_object : Base {
using type = T;
using error_t = error_type<T>;
using function_type = typename Base::function_object_signature;
using arg_types = typename Base::non_invoke_arg_types;
using non_invoke_arg_types = arg_types;
static constexpr const bool value = std::is_class<
typename std::remove_reference<T>::type>::value;
using traits = function_object;
using class_type = error_t;
using invoke_type = error_t;
using remove_varargs = error_t;
using add_varargs = error_t;
using is_noexcept = typename Base::is_noexcept;
using add_noexcept = error_t;
using remove_noexcept = error_t;
using is_transaction_safe = typename Base::is_transaction_safe;
using add_transaction_safe = error_t;
using remove_transaction_safe = error_t;
using clear_args = error_t;
template<template<class...> class Container>
using expand_args = typename function<function_type>::template
expand_args<Container>;
template<template<class...> class Container, typename... RightArgs>
using expand_args_left = typename function<function_type>::template
expand_args_left<Container, RightArgs...>;
template<template<class...> class Container, typename... LeftArgs>
using expand_args_right = typename function<function_type>::template
expand_args_right<Container, LeftArgs...>;
template<typename C, typename U = T>
using apply_member_pointer =
typename std::remove_reference<U>::type C::*;
template<typename>
using apply_return = error_t;
template<typename...>
using push_front = error_t;
template<typename...>
using push_back = error_t;
template<std::size_t ElementCount>
using pop_args_front = error_t;
template<std::size_t ElementCount>
using pop_args_back = error_t;
template<std::size_t Index, typename... NewArgs>
using insert_args = error_t;
template<std::size_t Index, std::size_t Count>
using remove_args = error_t;
template<std::size_t Index, typename... NewArgs>
using replace_args = error_t;
template<std::size_t Count>
using pop_front = error_t;
template<std::size_t Count>
using pop_back = error_t;
using remove_member_reference = error_t;
using add_member_lvalue_reference = error_t;
using add_member_rvalue_reference = error_t;
using add_member_const = error_t;
using add_member_volatile = error_t;
using add_member_cv = error_t;
using remove_member_const = error_t;
using remove_member_volatile = error_t;
using remove_member_cv = error_t;
};
template<typename T, typename U, typename Base>
struct function_object <T U::*, Base>
: default_callable_traits<> {};
}}} // namespace boost::callable_traits::detail
#endif // #ifndef BOOST_CLBL_TRTS_DETAIL_FUNCTION_OBJECT_HPP

View File

@@ -1,148 +0,0 @@
/*!
@file
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_IS_INVOCABLE_IMPL_HPP
#define BOOST_CLBL_TRTS_IS_INVOCABLE_IMPL_HPP
#include <boost/callable_traits/detail/config.hpp>
#include <boost/callable_traits/detail/forward_declarations.hpp>
#include <boost/callable_traits/detail/utility.hpp>
#include <type_traits>
#include <utility>
namespace boost { namespace callable_traits { namespace detail {
template<typename T>
struct can_dereference_t
{
template<typename>
struct check {};
template<typename U>
static std::int8_t test(
check<typename std::remove_reference<decltype(*std::declval<U>())>::type>*
);
template<typename>
static std::int16_t test(...);
static constexpr const bool value =
sizeof(test<T>(nullptr)) == sizeof(std::int8_t);
};
//returns std::true_type for pointers and smart pointers
template<typename T>
using can_dereference = std::integral_constant<bool,
can_dereference_t<T>::value>;
template<typename T, typename = std::true_type>
struct generalize_t {
using type = T;
};
template<typename T>
struct generalize_t<T, std::integral_constant<bool,
can_dereference<T>::value && !is_reference_wrapper<T>::value
>>{
using type = decltype(*std::declval<T>());
};
template<typename T>
struct generalize_t<T, is_reference_wrapper<T>> {
using type = decltype(std::declval<T>().get());
};
// When T is a pointer, generalize<T> is the resulting type of the
// pointer dereferenced. When T is an std::reference_wrapper, generalize<T>
// is the underlying reference type. Otherwise, generalize<T> is T.
template<typename T>
using generalize = typename generalize_t<T>::type;
// handles the member pointer rules of INVOKE
template<typename Base, typename T,
typename IsBaseOf = std::is_base_of<Base, shallow_decay<T>>,
typename IsSame = std::is_same<Base, shallow_decay<T>>>
using generalize_if_dissimilar = typename std::conditional<
IsBaseOf::value || IsSame::value, T, generalize<T>>::type;
template<typename Traits, bool = Traits::is_const_member::value
|| Traits::is_volatile_member::value
|| Traits::is_lvalue_reference_member::value
|| Traits::is_rvalue_reference_member::value>
struct test_invoke {
template<typename... Rgs,
typename U = typename Traits::type>
auto operator()(Rgs&&... rgs) const ->
success<decltype(std::declval<U>()(static_cast<Rgs&&>(rgs)...))>;
auto operator()(...) const -> substitution_failure;
};
template<typename F>
struct test_invoke<function<F>, true /*abominable*/> {
auto operator()(...) const -> substitution_failure;
};
template<typename Pmf, bool Ignored>
struct test_invoke<pmf<Pmf>, Ignored> {
using class_t = typename pmf<Pmf>::class_type;
template<typename U, typename... Rgs,
typename Obj = generalize_if_dissimilar<class_t, U&&>>
auto operator()(U&& u, Rgs&&... rgs) const ->
success<decltype((std::declval<Obj>().*std::declval<Pmf>())(static_cast<Rgs&&>(rgs)...))>;
auto operator()(...) const -> substitution_failure;
};
template<typename Pmd, bool Ignored>
struct test_invoke<pmd<Pmd>, Ignored> {
using class_t = typename pmd<Pmd>::class_type;
template<typename U,
typename Obj = generalize_if_dissimilar<class_t, U&&>>
auto operator()(U&& u) const ->
success<decltype(std::declval<Obj>().*std::declval<Pmd>())>;
auto operator()(...) const -> substitution_failure;
};
template<typename T, typename... Args>
struct is_invocable_impl {
using traits = detail::traits<T>;
using test = detail::test_invoke<traits>;
using result = decltype(test{}(::std::declval<Args>()...));
using type = std::integral_constant<bool, result::value>;
};
template<typename... Args>
struct is_invocable_impl<void, Args...> {
using type = std::false_type;
};
template<typename IsInvocable, typename Ret, typename T, typename... Args>
struct is_invocable_r_impl {
using traits = detail::traits<T>;
using test = detail::test_invoke<traits>;
using result = decltype(test{}(::std::declval<Args>()...));
using type = typename std::is_convertible<typename result::_::type, Ret>::type;
};
template<typename Ret, typename T, typename... Args>
struct is_invocable_r_impl<std::false_type, Ret, T, Args...> {
using type = std::false_type;
};
}}} // namespace boost::callable_traits::detail
#endif // #ifndef BOOST_CLBL_TRTS_IS_INVOCABLE_IMPL_HPP

View File

@@ -1,51 +0,0 @@
#ifndef BOOST_CLBL_TRTS_PARAMETER_INDEX_HELPER_HPP
#define BOOST_CLBL_TRTS_PARAMETER_INDEX_HELPER_HPP
#include <boost/callable_traits/detail/config.hpp>
namespace boost { namespace callable_traits { namespace detail {
template<std::size_t I, typename T, bool IgnoreThisPointer = false,
bool AllowPlus1 = false, std::size_t Count = 0>
struct parameter_index_helper {
using error_t = error_type<T>;
using args_tuple = typename std::conditional<IgnoreThisPointer,
typename detail::traits<T>::non_invoke_arg_types,
typename detail::traits<T>::arg_types>::type;
static constexpr bool has_parameter_list =
!std::is_same<args_tuple, invalid_type>::value
&& !std::is_same<args_tuple, reference_error>::value;
using temp_tuple = typename std::conditional<has_parameter_list,
args_tuple, std::tuple<error_t>>::type;
static constexpr std::size_t parameter_list_size =
std::tuple_size<temp_tuple>::value;
static constexpr bool is_out_of_range = has_parameter_list &&
I >= parameter_list_size + static_cast<std::size_t>(AllowPlus1);
static constexpr bool is_count_out_of_range = has_parameter_list &&
I + Count > parameter_list_size + static_cast<std::size_t>(AllowPlus1);
static constexpr std::size_t index =
has_parameter_list && !is_out_of_range ? I : 0;
static constexpr std::size_t count =
has_parameter_list && !is_count_out_of_range ? Count : 0;
using permissive_tuple = typename std::conditional<
has_parameter_list && !is_out_of_range,
args_tuple, std::tuple<error_t>>::type;
using permissive_function = typename std::conditional<
has_parameter_list && !is_out_of_range,
T, error_t(error_t)>::type;
};
}}} // namespace boost::callable_traits::detail
#endif // #ifndef BOOST_CLBL_TRTS_PARAMETER_INDEX_HELPER_HPP

View File

@@ -1,53 +0,0 @@
/*
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_DETAIL_PMD_HPP
#define BOOST_CLBL_TRTS_DETAIL_PMD_HPP
#include <boost/callable_traits/detail/forward_declarations.hpp>
#include <boost/callable_traits/detail/function.hpp>
#include <boost/callable_traits/detail/traits.hpp>
#include <boost/callable_traits/detail/default_callable_traits.hpp>
#include <boost/callable_traits/detail/utility.hpp>
namespace boost { namespace callable_traits { namespace detail {
template<typename T>
struct pmd : default_callable_traits<T> {};
template<typename D, typename T>
struct pmd<D T::*> : default_callable_traits<> {
static constexpr bool value = true;
using traits = pmd;
using class_type = T;
using invoke_type = T const &;
using type = D T::*;
using function_type = typename std::add_lvalue_reference<D>::type(invoke_type);
using qualified_function_type = D(invoke_type);
using arg_types = std::tuple<invoke_type>;
using non_invoke_arg_types = std::tuple<>;
using return_type = typename std::add_lvalue_reference<D>::type;
template<typename C>
using apply_member_pointer = D C::*;
template<typename R>
using apply_return = R T::*;
template<template<class...> class Container>
using expand_args = Container<invoke_type>;
using is_member_pointer = std::true_type;
};
}}} // namespace boost::callable_traits::detail
#endif

View File

@@ -1,97 +0,0 @@
/*
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_DETAIL_PMF_HPP
#define BOOST_CLBL_TRTS_DETAIL_PMF_HPP
#include <boost/callable_traits/detail/forward_declarations.hpp>
#include <boost/callable_traits/detail/set_function_qualifiers.hpp>
#include <boost/callable_traits/detail/qualifier_flags.hpp>
#include <boost/callable_traits/detail/default_callable_traits.hpp>
#include <boost/callable_traits/detail/utility.hpp>
namespace boost { namespace callable_traits { namespace detail {
template<qualifier_flags Applied, bool IsTransactionSafe, bool IsNoExcept,
typename CallingConvention, typename T, typename Return,
typename... Args>
struct set_member_function_qualifiers_t;
template<qualifier_flags Applied, bool IsTransactionSafe, bool IsNoexcept,
typename CallingConvention, typename T, typename Return,
typename... Args>
struct set_varargs_member_function_qualifiers_t;
template<qualifier_flags Flags, bool IsTransactionSafe, bool IsNoexcept,
typename... Ts>
using set_member_function_qualifiers =
typename set_member_function_qualifiers_t<Flags, IsTransactionSafe,
IsNoexcept, Ts...>::type;
template<qualifier_flags Flags, bool IsTransactionSafe, bool IsNoexcept,
typename... Ts>
using set_varargs_member_function_qualifiers =
typename set_varargs_member_function_qualifiers_t<Flags,
IsTransactionSafe, IsNoexcept, Ts...>::type;
template<typename T>
struct pmf : default_callable_traits<T> {};
#define BOOST_CLBL_TRTS_CC_TAG dummy
#define BOOST_CLBL_TRTS_VARARGS_CC BOOST_CLBL_TRTS_DEFAULT_VARARGS_CC
#define BOOST_CLBL_TRTS_CC
#include <boost/callable_traits/detail/unguarded/pmf.hpp>
#undef BOOST_CLBL_TRTS_CC
#undef BOOST_CLBL_TRTS_CC_TAG
#undef BOOST_CLBL_TRTS_VARARGS_CC
#define BOOST_CLBL_TRTS_CC_TAG dummy
#define BOOST_CLBL_TRTS_VARARGS_CC BOOST_CLBL_TRTS_DEFAULT_VARARGS_CC
#define BOOST_CLBL_TRTS_CC
#include <boost/callable_traits/detail/unguarded/pmf_varargs.hpp>
#undef BOOST_CLBL_TRTS_CC
#undef BOOST_CLBL_TRTS_CC_TAG
#undef BOOST_CLBL_TRTS_VARARGS_CC
#ifdef BOOST_CLBL_TRTS_ENABLE_CDECL
#define BOOST_CLBL_TRTS_CC_TAG cdecl_tag
#define BOOST_CLBL_TRTS_VARARGS_CC __cdecl
#define BOOST_CLBL_TRTS_CC __cdecl
#include <boost/callable_traits/detail/unguarded/pmf.hpp>
#undef BOOST_CLBL_TRTS_CC
#undef BOOST_CLBL_TRTS_CC_TAG
#undef BOOST_CLBL_TRTS_VARARGS_CC
#endif // #ifdef BOOST_CLBL_TRTS_ENABLE_CDECL
// Defining this macro enables undocumented features, likely broken.
// Too much work to maintain, but knock yourself out
#ifdef BOOST_CLBL_TRTS_ENABLE_STDCALL
#define BOOST_CLBL_TRTS_CC_TAG stdcall_tag
#define BOOST_CLBL_TRTS_VARARGS_CC BOOST_CLBL_TRTS_DEFAULT_VARARGS_CC
#define BOOST_CLBL_TRTS_CC __stdcall
#include <boost/callable_traits/detail/unguarded/pmf.hpp>
#undef BOOST_CLBL_TRTS_CC
#undef BOOST_CLBL_TRTS_CC_TAG
#undef BOOST_CLBL_TRTS_VARARGS_CC
#endif // #ifdef BOOST_CLBL_TRTS_ENABLE_STDCALL
// Defining this macro enables undocumented features, likely broken.
// Too much work to officially maintain, but knock yourself out
#ifdef BOOST_CLBL_TRTS_ENABLE_FASTCALL
#define BOOST_CLBL_TRTS_CC_TAG fastcall_tag
#define BOOST_CLBL_TRTS_VARARGS_CC BOOST_CLBL_TRTS_DEFAULT_VARARGS_CC
#define BOOST_CLBL_TRTS_CC __fastcall
#include <boost/callable_traits/detail/unguarded/pmf.hpp>
#undef BOOST_CLBL_TRTS_CC
#undef BOOST_CLBL_TRTS_CC_TAG
#undef BOOST_CLBL_TRTS_VARARGS_CC
#endif // #ifdef BOOST_CLBL_TRTS_ENABLE_FASTCALL
}}} // namespace boost::callable_traits::detail
#endif // #ifndef BOOST_CLBL_TRTS_DETAIL_PMF_HPP

View File

@@ -1,31 +0,0 @@
/*
Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_DETAIL_POLYFILLS_DISJUNCTION_HPP
#define BOOST_CLBL_TRTS_DETAIL_POLYFILLS_DISJUNCTION_HPP
#undef BOOST_CLBL_TRTS_DISJUNCTION
#define BOOST_CLBL_TRTS_DISJUNCTION(...) \
::boost::callable_traits::detail::disjunction<__VA_ARGS__>
namespace boost { namespace callable_traits { namespace detail {
//polyfill for C++17 std::disjunction
template<typename...>
struct disjunction : std::false_type {};
template<typename T>
struct disjunction<T> : T {};
template<typename T, typename... Ts>
struct disjunction<T, Ts...>
: std::conditional<T::value != false, T, disjunction<Ts...>>::type {};
}}} // namespace boost::callable_traits::detail
#endif // #ifndef BOOST_CLBL_TRTS_DETAIL_POLYFILLS_DISJUNCTION_HPP

View File

@@ -1,50 +0,0 @@
/*
Copyright Barrett Adair 2016-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_DETAIL_POLYFILLS_MAKE_INDEX_SEQUENCE_HPP
#define BOOST_CLBL_TRTS_DETAIL_POLYFILLS_MAKE_INDEX_SEQUENCE_HPP
#undef BOOST_CLBL_TRTS_IX_SEQ
#define BOOST_CLBL_TRTS_IX_SEQ(...) \
::boost::callable_traits::detail::index_sequence<__VA_ARGS__>
#undef BOOST_CLBL_TRTS_MAKE_IX_SEQ
#define BOOST_CLBL_TRTS_MAKE_IX_SEQ(...) \
::boost::callable_traits::detail::make_index_sequence<__VA_ARGS__>
namespace boost { namespace callable_traits { namespace detail {
template<std::size_t...>
struct index_sequence { using type = index_sequence; };
template<typename, typename>
struct concat;
template<std::size_t... I1, std::size_t... I2>
struct concat<index_sequence<I1...>, index_sequence<I2...>>
: index_sequence<I1..., (sizeof...(I1)+I2)...> {};
template<std::size_t N>
struct make_index_sequence_t;
template<std::size_t N>
struct make_index_sequence_t : concat<
typename make_index_sequence_t<N/2>::type,
typename make_index_sequence_t<N - N/2>::type >::type {};
template<>
struct make_index_sequence_t<0> : index_sequence<> {};
template<>
struct make_index_sequence_t<1> : index_sequence<0> {};
template<std::size_t... I>
using make_index_sequence = typename make_index_sequence_t<I...>::type;
}}} // namespace boost::callable_traits::detail
#endif // #ifndef BOOST_CLBL_TRTS_DETAIL_POLYFILLS_MAKE_INDEX_SEQUENCE_HPP

View File

@@ -1,123 +0,0 @@
/*
Defines `qualifier_flags`
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_QUALIFIER_FLAGS_HPP
#define BOOST_CLBL_TRTS_QUALIFIER_FLAGS_HPP
#include <boost/callable_traits/detail/config.hpp>
namespace boost { namespace callable_traits { namespace detail {
//bit qualifier_flags used to signify cv/ref qualifiers
using qualifier_flags = std::uint32_t;
/*
| && & V C |
--------------------------------------------
0 | 0 0 0 0 | default
1 | 0 0 0 1 | const
2 | 0 0 1 0 | volatile
3 | 0 0 1 1 | const volatile
--------------------------------------------
4 | 0 1 0 0 | &
5 | 0 1 0 1 | const &
6 | 0 1 1 0 | volatile &
7 | 0 1 1 1 | const volatile &
--------------------------------------------
8 | 1 0 0 0 | &&
9 | 1 0 0 1 | const &&
10 | 1 0 1 0 | volatile &&
11 | 1 0 1 1 | const volatile &&
*/
// Flag representing the default qualifiers on a type
// or member function overload.
constexpr qualifier_flags default_ = 0;
// Flag representing a const qualifier on a type or
// member function overload.
constexpr qualifier_flags const_ = 1;
// Flag representing a volatile qualifier on a type
// or member function overload.
constexpr qualifier_flags volatile_ = 2;
#ifdef BOOST_CLBL_TRTS_DISABLE_REFERENCE_QUALIFIERS
constexpr qualifier_flags lref_ = default_;
constexpr qualifier_flags rref_ = default_;
#else
// Flag representing an lvalue reference type, or
// an lvalue-reference-qualified member function
// overload.
constexpr qualifier_flags lref_ = 4;
// Flag representing an lvalue reference type, or
// an rvalue-reference-qualified member function
// overload.
constexpr qualifier_flags rref_ = 8;
#endif //#ifdef BOOST_CLBL_TRTS_DISABLE_REFERENCE_QUALIFIERS
constexpr qualifier_flags cv_ = 3;
template<qualifier_flags Flags>
using remove_const_flag = std::integral_constant<
qualifier_flags, Flags & ~const_>;
template<qualifier_flags Flags>
using is_const = std::integral_constant<bool,
(Flags & const_) != 0>;
template<qualifier_flags Flags>
using remove_volatile_flag = std::integral_constant<
qualifier_flags, Flags & ~volatile_>;
template<typename U, typename T = typename std::remove_reference<U>::type>
using cv_of = std::integral_constant<qualifier_flags,
(std::is_const<T>::value ? const_ : default_)
| (std::is_volatile<T>::value ? volatile_ : default_)>;
template<typename T>
using ref_of = std::integral_constant<qualifier_flags,
std::is_rvalue_reference<T>::value ? rref_
: (std::is_lvalue_reference<T>::value ? lref_
: default_)>;
//bit-flag implementation of C++11 reference collapsing rules
template<qualifier_flags Existing,
qualifier_flags Other,
bool AlreadyHasRef = (Existing & (lref_ | rref_)) != 0,
bool AlreadyHasLRef = (Existing & lref_) == lref_,
bool IsAddingLRef = (Other & lref_) == lref_
>
using collapse_flags = std::integral_constant<qualifier_flags,
!AlreadyHasRef ? (Existing | Other)
: (AlreadyHasLRef ? (Existing | (Other & ~rref_))
: (IsAddingLRef ? ((Existing & ~rref_) | Other )
: (Existing | Other)))>;
template<typename T> struct flag_map { static constexpr qualifier_flags value = default_; };
template<typename T> struct flag_map<T &> { static constexpr qualifier_flags value = lref_; };
template<typename T> struct flag_map<T &&> { static constexpr qualifier_flags value = rref_; };
template<typename T> struct flag_map<T const> { static constexpr qualifier_flags value = const_; };
template<typename T> struct flag_map<T const &> { static constexpr qualifier_flags value = const_ | lref_; };
template<typename T> struct flag_map<T const &&> { static constexpr qualifier_flags value = const_ | rref_; };
template<typename T> struct flag_map<T volatile> { static constexpr qualifier_flags value = volatile_; };
template<typename T> struct flag_map<T volatile &> { static constexpr qualifier_flags value = volatile_ | lref_; };
template<typename T> struct flag_map<T volatile &&> { static constexpr qualifier_flags value = volatile_ | rref_; };
template<typename T> struct flag_map<T const volatile> { static constexpr qualifier_flags value = const_ | volatile_; };
template<typename T> struct flag_map<T const volatile &> { static constexpr qualifier_flags value = const_ | volatile_ | lref_; };
template<typename T> struct flag_map<T const volatile &&> { static constexpr qualifier_flags value = const_ | volatile_ | rref_; };
}}} // namespace boost::callable_traits::detail
#endif // #ifndef BOOST_CLBL_TRTS_QUALIFIER_FLAGS_HPP

View File

@@ -1,120 +0,0 @@
/*
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_DETAIL_SET_FUNCTION_QUALIFIERS_HPP
#define BOOST_CLBL_TRTS_DETAIL_SET_FUNCTION_QUALIFIERS_HPP
#include <boost/callable_traits/detail/qualifier_flags.hpp>
#define BOOST_CLBL_TRTS_SET_FUNCTION_QUALIFIERS(QUAL) \
template<typename Return, typename... Args> \
struct set_function_qualifiers_t < \
flag_map<int QUAL>::value, false, false, Return, Args...> { \
using type = Return(Args...) QUAL; \
}; \
\
template<typename Return, typename... Args> \
struct set_function_qualifiers_t < \
flag_map<int QUAL>::value, true, false, Return, Args...> { \
using type = Return(Args...) QUAL \
BOOST_CLBL_TRTS_TRANSACTION_SAFE_SPECIFIER; \
}; \
\
template<typename Return, typename... Args> \
struct set_function_qualifiers_t < \
flag_map<int QUAL>::value, false, true, Return, Args...> { \
using type = Return(Args...) QUAL \
BOOST_CLBL_TRTS_NOEXCEPT_SPECIFIER; \
}; \
\
template<typename Return, typename... Args> \
struct set_function_qualifiers_t < \
flag_map<int QUAL>::value, true, true, Return, Args...> { \
using type = Return(Args...) QUAL \
BOOST_CLBL_TRTS_TRANSACTION_SAFE_SPECIFIER \
BOOST_CLBL_TRTS_NOEXCEPT_SPECIFIER; \
}; \
\
template<typename Return, typename... Args> \
struct set_varargs_function_qualifiers_t < \
flag_map<int QUAL>::value, false, false, Return, Args...> { \
using type = Return(Args..., ...) QUAL; \
}; \
\
template<typename Return, typename... Args> \
struct set_varargs_function_qualifiers_t < \
flag_map<int QUAL>::value, true, false, Return, Args...> { \
using type = Return(Args..., ...) QUAL \
BOOST_CLBL_TRTS_TRANSACTION_SAFE_SPECIFIER; \
}; \
\
template<typename Return, typename... Args> \
struct set_varargs_function_qualifiers_t < \
flag_map<int QUAL>::value, false, true, Return, Args...> { \
using type = Return(Args..., ...) QUAL \
BOOST_CLBL_TRTS_NOEXCEPT_SPECIFIER; \
}; \
\
template<typename Return, typename... Args> \
struct set_varargs_function_qualifiers_t < \
flag_map<int QUAL>::value, true, true, Return, Args...> { \
using type = Return(Args..., ...) QUAL \
BOOST_CLBL_TRTS_TRANSACTION_SAFE_SPECIFIER \
BOOST_CLBL_TRTS_NOEXCEPT_SPECIFIER; \
} \
/**/
namespace boost { namespace callable_traits { namespace detail {
template<qualifier_flags Applied, bool IsTransactionSafe,
bool IsNoexcept, typename Return, typename... Args>
struct set_function_qualifiers_t {
using type = Return(Args...);
};
template<qualifier_flags Applied, bool IsTransactionSafe,
bool IsNoexcept, typename Return, typename... Args>
struct set_varargs_function_qualifiers_t {
using type = Return(Args..., ...);
};
#ifndef BOOST_CLBL_TRTS_DISABLE_ABOMINABLE_FUNCTIONS
BOOST_CLBL_TRTS_SET_FUNCTION_QUALIFIERS(const);
BOOST_CLBL_TRTS_SET_FUNCTION_QUALIFIERS(volatile);
BOOST_CLBL_TRTS_SET_FUNCTION_QUALIFIERS(const volatile);
#ifndef BOOST_CLBL_TRTS_DISABLE_REFERENCE_QUALIFIERS
BOOST_CLBL_TRTS_SET_FUNCTION_QUALIFIERS(&);
BOOST_CLBL_TRTS_SET_FUNCTION_QUALIFIERS(&&);
BOOST_CLBL_TRTS_SET_FUNCTION_QUALIFIERS(const &);
BOOST_CLBL_TRTS_SET_FUNCTION_QUALIFIERS(const &&);
BOOST_CLBL_TRTS_SET_FUNCTION_QUALIFIERS(volatile &);
BOOST_CLBL_TRTS_SET_FUNCTION_QUALIFIERS(volatile &&);
BOOST_CLBL_TRTS_SET_FUNCTION_QUALIFIERS(const volatile &);
BOOST_CLBL_TRTS_SET_FUNCTION_QUALIFIERS(const volatile &&);
#endif // #ifndef BOOST_CLBL_TRTS_DISABLE_REFERENCE_QUALIFIERS
#endif // #ifndef BOOST_CLBL_TRTS_DISABLE_ABOMINABLE_FUNCTIONS
template<qualifier_flags Flags, bool IsTransactionSafe, bool IsNoexcept,
typename... Ts>
using set_function_qualifiers =
typename set_function_qualifiers_t<Flags, IsTransactionSafe, IsNoexcept,
Ts...>::type;
template<qualifier_flags Flags, bool IsTransactionSafe, bool IsNoexcept,
typename... Ts>
using set_varargs_function_qualifiers =
typename set_varargs_function_qualifiers_t<Flags, IsTransactionSafe,
IsNoexcept, Ts...>::type;
}}} // namespace boost::callable_traits::detail
#endif //BOOST_CLBL_TRTS_DETAIL_SET_FUNCTION_QUALIFIERS_HPP

View File

@@ -1,89 +0,0 @@
/*
@Copyright Barrett Adair 2016-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_SFINAE_ERRORS_HPP
#define BOOST_CLBL_TRTS_SFINAE_ERRORS_HPP
#include <boost/callable_traits/detail/config.hpp>
namespace boost { namespace callable_traits { namespace detail {
struct sfinae_error{};
template<typename T>
struct success {
static constexpr bool value = true;
struct _ { using type = T; };
};
template<bool B, typename T>
struct fail_if : T {
static_assert(std::is_base_of<sfinae_error, T>::value,
"incorrect usage of fail_if");
static constexpr bool value = B;
};
template<typename T, typename... FailIfs>
using sfinae_try = typename BOOST_CLBL_TRTS_DISJUNCTION(
FailIfs..., success<T>)::_::type;
template<typename FailMsg, typename ForceTwoPhaseLookup>
struct fail {
using type = typename std::conditional<std::is_same<ForceTwoPhaseLookup, std::false_type>::value,
FailMsg, FailMsg>::type::_::type;
};
}}} // namespace boost::callable_traits::detail
#define BOOST_CLBL_TRTS_PP_CAT_(x, y) x ## y
#define BOOST_CLBL_TRTS_PP_CAT(x, y) BOOST_CLBL_TRTS_PP_CAT_(x, y)
#define BOOST_CLBL_TRTS_DEFINE_SFINAE_ERROR_ORIGIN(origin) \
namespace error { \
template<typename ErrorMessage> \
struct origin : \
::boost::callable_traits::detail::sfinae_error \
{ struct _ {}; }; \
} \
/**/
#define BOOST_CLBL_TRTS_SFINAE_MSG(origin, name) \
struct BOOST_CLBL_TRTS_PP_CAT(name, _ ){}; \
struct name : error::origin< \
BOOST_CLBL_TRTS_PP_CAT(name, _ )>{}; \
/**/
namespace boost { namespace callable_traits {
BOOST_CLBL_TRTS_DEFINE_SFINAE_ERROR_ORIGIN(parameters)
BOOST_CLBL_TRTS_SFINAE_MSG(parameters, index_out_of_range_for_parameter_list)
BOOST_CLBL_TRTS_SFINAE_MSG(parameters, cannot_determine_parameters_for_this_type)
BOOST_CLBL_TRTS_DEFINE_SFINAE_ERROR_ORIGIN(varargs)
BOOST_CLBL_TRTS_SFINAE_MSG(varargs, varargs_are_illegal_for_this_type)
BOOST_CLBL_TRTS_DEFINE_SFINAE_ERROR_ORIGIN(member_qualifiers)
BOOST_CLBL_TRTS_SFINAE_MSG(member_qualifiers, member_qualifiers_are_illegal_for_this_type)
BOOST_CLBL_TRTS_SFINAE_MSG(member_qualifiers, this_compiler_doesnt_support_abominable_function_types)
BOOST_CLBL_TRTS_DEFINE_SFINAE_ERROR_ORIGIN(transaction_safe_)
BOOST_CLBL_TRTS_SFINAE_MSG(transaction_safe_, transaction_safe_is_not_supported_by_this_configuration)
BOOST_CLBL_TRTS_DEFINE_SFINAE_ERROR_ORIGIN(expand_args)
BOOST_CLBL_TRTS_SFINAE_MSG(expand_args, cannot_expand_the_parameter_list_of_first_template_argument)
BOOST_CLBL_TRTS_DEFINE_SFINAE_ERROR_ORIGIN(member_pointer_required)
BOOST_CLBL_TRTS_SFINAE_MSG(member_pointer_required, type_is_not_a_member_pointer)
BOOST_CLBL_TRTS_DEFINE_SFINAE_ERROR_ORIGIN(reference_error)
BOOST_CLBL_TRTS_SFINAE_MSG(reference_error, reference_type_not_supported_by_this_metafunction)
}} // namespace boost::callable_traits
#endif // #ifndef BOOST_CLBL_TRTS_SFINAE_ERRORS_HPP

View File

@@ -1,29 +0,0 @@
/*
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_DETAIL_TRAITS_HPP
#define BOOST_CLBL_TRTS_DETAIL_TRAITS_HPP
#include <boost/callable_traits/detail/forward_declarations.hpp>
#include <boost/callable_traits/detail/utility.hpp>
namespace boost { namespace callable_traits { namespace detail {
// Here is where the magic happens
template<typename T>
using traits = typename BOOST_CLBL_TRTS_DISJUNCTION(
function_object<unwrap_reference<T>>,
function<T>,
pmf<T>,
pmd<T>,
default_callable_traits<T>
)::traits;
}}} // namespace boost::callable_traits::detail
#endif // #ifndef BOOST_CLBL_TRTS_DETAIL_TRAITS_HPP

View File

@@ -1,23 +0,0 @@
/*
Copyright (c) 2016 Barrett Adair
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
HEADER GUARDS INTENTIONALLY OMITTED
DO NOT INCLUDE THIS HEADER DIRECTLY
*/
#define BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
#define BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE std::false_type
#include <boost/callable_traits/detail/unguarded/function_2.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
#undef BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE
#ifdef BOOST_CLBL_TRTS_ENABLE_TRANSACTION_SAFE
#define BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE std::true_type
#define BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE transaction_safe
#include <boost/callable_traits/detail/unguarded/function_2.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
#undef BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE
#endif // #ifdef BOOST_CLBL_TRTS_ENABLE_TRANSACTION_SAFE

View File

@@ -1,23 +0,0 @@
/*
Copyright (c) 2016 Barrett Adair
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
HEADER GUARDS INTENTIONALLY OMITTED
DO NOT INCLUDE THIS HEADER DIRECTLY
*/
#define BOOST_CLBL_TRTS_NOEXCEPT_SPEC
#define BOOST_CLBL_TRTS_IS_NOEXCEPT std::false_type
#include <boost/callable_traits/detail/unguarded/function_3.hpp>
#undef BOOST_CLBL_TRTS_NOEXCEPT_SPEC
#undef BOOST_CLBL_TRTS_IS_NOEXCEPT
#ifdef BOOST_CLBL_TRTS_ENABLE_NOEXCEPT_TYPES
#define BOOST_CLBL_TRTS_NOEXCEPT_SPEC noexcept
#define BOOST_CLBL_TRTS_IS_NOEXCEPT std::true_type
#include <boost/callable_traits/detail/unguarded/function_3.hpp>
#undef BOOST_CLBL_TRTS_NOEXCEPT_SPEC
#undef BOOST_CLBL_TRTS_IS_NOEXCEPT
#endif // #ifdef BOOST_CLBL_TRTS_ENABLE_NOEXCEPT_TYPES

View File

@@ -1,260 +0,0 @@
/*
Copyright (c) 2016 Barrett Adair
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
HEADER GUARDS INTENTIONALLY OMITTED
DO NOT INCLUDE THIS HEADER DIRECTLY
macros used:
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS - the function-level qualifiers for the
current inclusion (combinations of `const` `volatile` `&` `&&`, or nothing)
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE - the transaction_safe specifier for
the current include (`transaction_safe` or nothing)
BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE - `std::true_type` or `std::false_type`,
tied on whether BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE is `transaction_safe`
BOOST_CLBL_TRTS_TRANSACTION_SAFE_SPECIFIER - `transaction_safe` when
BOOST_CLBL_TRTS_ENABLE_TRANSACTION_SAFE is enabled, otherwise nothing
BOOST_CLBL_TRTS_NOEXCEPT_SPEC - the noexcept specifier for
the current include (`noexcept` or nothing)
BOOST_CLBL_TRTS_IS_NOEXCEPT - `std::true_type` or `std::false_type`,
tied on whether BOOST_CLBL_TRTS_NOEXCEPT_SPEC is `noexcept`
BOOST_CLBL_TRTS_NOEXCEPT_SPECIFIER - `noexcept` if
BOOST_CLBL_TRTS_ENABLE_NOEXCEPT_TYPES is defined, otherwise nothing
*/
template<typename Return, typename... Args>
struct function<Return(Args...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPEC>
: default_callable_traits<dummy BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS> {
static constexpr bool value = true;
using traits = function;
using return_type = Return;
using arg_types = std::tuple<Args...>;
using non_invoke_arg_types = arg_types;
using type = Return(Args...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
using function_type = Return(Args...);
using qualified_function_type = Return(Args...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
using remove_varargs = type;
using add_varargs = Return (Args..., ...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
using is_noexcept = BOOST_CLBL_TRTS_IS_NOEXCEPT;
using remove_noexcept = Return(Args...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE;
using add_noexcept = Return(Args...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPECIFIER;
using is_transaction_safe = BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE;
using remove_transaction_safe = Return(Args...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
using add_transaction_safe = Return(Args...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_TRANSACTION_SAFE_SPECIFIER
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
using qualifiers = default_callable_traits<dummy BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS>;
template<qualifier_flags Flags>
using set_qualifiers = set_function_qualifiers<Flags, is_transaction_safe::value,
is_noexcept::value, Return, Args...>;
#ifdef BOOST_CLBL_TRTS_DISABLE_ABOMINABLE_FUNCTIONS
using add_member_lvalue_reference = abominable_functions_not_supported_on_this_compiler;
using add_member_rvalue_reference = abominable_functions_not_supported_on_this_compiler;
using add_member_const = abominable_functions_not_supported_on_this_compiler;
using add_member_volatile = abominable_functions_not_supported_on_this_compiler;
using add_member_cv = abominable_functions_not_supported_on_this_compiler;
#else
using add_member_lvalue_reference = set_qualifiers<
collapse_flags<qualifiers::q_flags, lref_>::value>;
using add_member_rvalue_reference = set_qualifiers<
collapse_flags<qualifiers::q_flags, rref_>::value>;
using add_member_const = set_qualifiers<qualifiers::q_flags | const_>;
using add_member_volatile = set_qualifiers<qualifiers::q_flags | volatile_>;
using add_member_cv = set_qualifiers<qualifiers::q_flags | cv_>;
#endif // #ifdef BOOST_CLBL_TRTS_DISABLE_ABOMINABLE_FUNCTIONS
using remove_member_reference = set_qualifiers<qualifiers::cv_flags>;
using remove_member_const = set_qualifiers<
qualifiers::ref_flags | remove_const_flag<qualifiers::cv_flags>::value>;
using remove_member_volatile = set_qualifiers<
qualifiers::ref_flags | remove_volatile_flag<qualifiers::cv_flags>::value>;
using remove_member_cv = set_qualifiers<qualifiers::ref_flags>;
template<typename U>
using apply_member_pointer = add_member_pointer<type, U>;
template<typename NewReturn>
using apply_return = NewReturn(Args...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
template<template<class...> class Container>
using expand_args = Container<Args...>;
using is_member_pointer = std::false_type;
};
template<typename Return, typename... Args>
struct function<Return (Args..., ...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPEC>
: default_callable_traits<dummy BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS> {
static constexpr bool value = true;
using has_varargs = std::true_type;
using traits = function;
using return_type = Return;
using arg_types = std::tuple<Args...>;
using type = Return (Args..., ...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
using function_type = Return(Args..., ...);
using qualified_function_type = Return(Args..., ...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
using remove_varargs = Return (Args...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
using add_varargs = type;
using is_noexcept = BOOST_CLBL_TRTS_IS_NOEXCEPT;
using remove_noexcept = Return(Args..., ...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE;
using add_noexcept = Return(Args..., ...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPECIFIER;
using is_transaction_safe = BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE;
using remove_transaction_safe = Return(Args..., ...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
using add_transaction_safe = Return(Args..., ...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_TRANSACTION_SAFE_SPECIFIER
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
using qualifiers = default_callable_traits<dummy BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS>;
template<qualifier_flags Flags>
using set_qualifiers = set_varargs_function_qualifiers<Flags, is_transaction_safe::value,
is_noexcept::value, Return, Args...>;
#ifdef BOOST_CLBL_TRTS_DISABLE_ABOMINABLE_FUNCTIONS
using add_member_lvalue_reference = abominable_functions_not_supported_on_this_compiler;
using add_member_rvalue_reference = abominable_functions_not_supported_on_this_compiler;
using add_member_const = abominable_functions_not_supported_on_this_compiler;
using add_member_volatile = abominable_functions_not_supported_on_this_compiler;
using add_member_cv = abominable_functions_not_supported_on_this_compiler;
#else
using add_member_lvalue_reference = set_qualifiers<
collapse_flags<qualifiers::q_flags, lref_>::value>;
using add_member_rvalue_reference = set_qualifiers<
collapse_flags<qualifiers::q_flags, rref_>::value>;
using add_member_const = set_qualifiers<qualifiers::q_flags | const_>;
using add_member_volatile = set_qualifiers<qualifiers::q_flags | volatile_>;
using add_member_cv = set_qualifiers<qualifiers::q_flags | cv_>;
#endif // #ifdef BOOST_CLBL_TRTS_DISABLE_ABOMINABLE_FUNCTIONS
using remove_member_reference = set_qualifiers<qualifiers::cv_flags>;
using remove_member_const = set_qualifiers<
qualifiers::ref_flags | remove_const_flag<qualifiers::cv_flags>::value>;
using remove_member_volatile = set_qualifiers<
qualifiers::ref_flags | remove_volatile_flag<qualifiers::cv_flags>::value>;
using remove_member_cv = set_qualifiers<qualifiers::ref_flags>;
template<typename U>
using apply_member_pointer =
Return( BOOST_CLBL_TRTS_DEFAULT_VARARGS_CC U::*)(Args..., ...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
template<typename NewReturn>
using apply_return = NewReturn(Args..., ...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
template<template<class...> class Container>
using expand_args = Container<Args...>;
using is_member_pointer = std::false_type;
};

View File

@@ -1,25 +0,0 @@
/*
Copyright (c) 2016 Modified Work Barrett Adair
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
HEADER GUARDS INTENTIONALLY OMITTED
DO NOT INCLUDE THIS HEADER DIRECTLY
*/
#define BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
#define BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE std::false_type
#include <boost/callable_traits/detail/unguarded/function_ptr_2.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
#undef BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE
#ifdef BOOST_CLBL_TRTS_ENABLE_TRANSACTION_SAFE
#define BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE std::true_type
#define BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE transaction_safe
#include <boost/callable_traits/detail/unguarded/function_ptr_2.hpp>
#endif
#undef BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
#undef BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE

View File

@@ -1,23 +0,0 @@
/*
Copyright (c) 2016 Barrett Adair
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
HEADER GUARDS INTENTIONALLY OMITTED
DO NOT INCLUDE THIS HEADER DIRECTLY
*/
#define BOOST_CLBL_TRTS_NOEXCEPT_SPEC
#define BOOST_CLBL_TRTS_IS_NOEXCEPT std::false_type
#include <boost/callable_traits/detail/unguarded/function_ptr_3.hpp>
#undef BOOST_CLBL_TRTS_NOEXCEPT_SPEC
#undef BOOST_CLBL_TRTS_IS_NOEXCEPT
#ifdef BOOST_CLBL_TRTS_ENABLE_NOEXCEPT_TYPES
#define BOOST_CLBL_TRTS_NOEXCEPT_SPEC noexcept
#define BOOST_CLBL_TRTS_IS_NOEXCEPT std::true_type
#include <boost/callable_traits/detail/unguarded/function_ptr_3.hpp>
#undef BOOST_CLBL_TRTS_NOEXCEPT_SPEC
#undef BOOST_CLBL_TRTS_IS_NOEXCEPT
#endif // #ifdef BOOST_CLBL_TRTS_ENABLE_NOEXCEPT_TYPES

View File

@@ -1,94 +0,0 @@
/*
Copyright (c) 2016 Modified Work Barrett Adair
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
HEADER GUARDS INTENTIONALLY OMITTED
DO NOT INCLUDE THIS HEADER DIRECTLY
macros used:
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE - the transaction_safe specifier for
the current include (`transaction_safe` or nothing)
BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE - `std::true_type` or `std::false_type`,
tied on whether BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE is `transaction_safe`
BOOST_CLBL_TRTS_TRANSACTION_SAFE_SPECIFIER - `transaction_safe` when
BOOST_CLBL_TRTS_ENABLE_TRANSACTION_SAFE is enabled, otherwise nothing
BOOST_CLBL_TRTS_NOEXCEPT_SPEC - the noexcept specifier for
the current include (`noexcept` or nothing)
BOOST_CLBL_TRTS_IS_NOEXCEPT - `std::true_type` or `std::false_type`,
tied on whether BOOST_CLBL_TRTS_NOEXCEPT_SPEC is `noexcept`
BOOST_CLBL_TRTS_NOEXCEPT_SPECIFIER - `noexcept` if
BOOST_CLBL_TRTS_ENABLE_NOEXCEPT_TYPES is defined, otherwise nothing
*/
template<typename Return, typename... Args>
struct function<
BOOST_CLBL_TRTS_ST Return(BOOST_CLBL_TRTS_CC *)(Args...)
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPEC>
: default_callable_traits<> {
static constexpr bool value = true;
using traits = function;
using return_type = Return;
using arg_types = std::tuple<Args...>;
using non_invoke_arg_types = arg_types;
using type = BOOST_CLBL_TRTS_ST Return(BOOST_CLBL_TRTS_CC *)(Args...)
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE;
using function_type = Return(Args...);
using qualified_function_type = function_type;
using remove_varargs = type;
using add_varargs =
BOOST_CLBL_TRTS_ST Return (BOOST_CLBL_TRTS_VARARGS_CC *)(Args..., ...)
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
using is_noexcept = BOOST_CLBL_TRTS_IS_NOEXCEPT;
using remove_noexcept = Return(BOOST_CLBL_TRTS_CC *)(Args...)
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE;
using add_noexcept = Return(BOOST_CLBL_TRTS_CC *)(Args...)
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPECIFIER;
using is_transaction_safe = BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE;
using remove_transaction_safe = Return(BOOST_CLBL_TRTS_CC *)(Args...)
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
using add_transaction_safe = Return(BOOST_CLBL_TRTS_CC *)(Args...)
BOOST_CLBL_TRTS_TRANSACTION_SAFE_SPECIFIER
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
template<typename U>
using apply_member_pointer =
BOOST_CLBL_TRTS_ST Return(BOOST_CLBL_TRTS_CC U::*)(Args...)
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
template<typename NewReturn>
using apply_return =
BOOST_CLBL_TRTS_ST NewReturn(BOOST_CLBL_TRTS_CC *)(Args...)
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
template<template<class...> class Container>
using expand_args = Container<Args...>;
using is_member_pointer = std::false_type;
};

View File

@@ -1,23 +0,0 @@
/*
Copyright (c) 2016 Modified Work Barrett Adair
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
HEADER GUARDS INTENTIONALLY OMITTED
DO NOT INCLUDE THIS HEADER DIRECTLY
*/
#define BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
#define BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE std::false_type
#include <boost/callable_traits/detail/unguarded/function_ptr_varargs_2.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
#undef BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE
#ifdef BOOST_CLBL_TRTS_ENABLE_TRANSACTION_SAFE
#define BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE std::true_type
#define BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE transaction_safe
#include <boost/callable_traits/detail/unguarded/function_ptr_varargs_2.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
#undef BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE
#endif // #ifdef BOOST_CLBL_TRTS_ENABLE_TRANSACTION_SAFE

View File

@@ -1,23 +0,0 @@
/*
Copyright (c) 2016 Barrett Adair
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
HEADER GUARDS INTENTIONALLY OMITTED
DO NOT INCLUDE THIS HEADER DIRECTLY
*/
#define BOOST_CLBL_TRTS_NOEXCEPT_SPEC
#define BOOST_CLBL_TRTS_IS_NOEXCEPT std::false_type
#include <boost/callable_traits/detail/unguarded/function_ptr_varargs_3.hpp>
#undef BOOST_CLBL_TRTS_NOEXCEPT_SPEC
#undef BOOST_CLBL_TRTS_IS_NOEXCEPT
#ifdef BOOST_CLBL_TRTS_ENABLE_NOEXCEPT_TYPES
#define BOOST_CLBL_TRTS_NOEXCEPT_SPEC noexcept
#define BOOST_CLBL_TRTS_IS_NOEXCEPT std::true_type
#include <boost/callable_traits/detail/unguarded/function_ptr_varargs_3.hpp>
#undef BOOST_CLBL_TRTS_NOEXCEPT_SPEC
#undef BOOST_CLBL_TRTS_IS_NOEXCEPT
#endif // #ifdef BOOST_CLBL_TRTS_ENABLE_NOEXCEPT_TYPES

View File

@@ -1,98 +0,0 @@
/*
Copyright (c) 2016 Modified Work Barrett Adair
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
HEADER GUARDS INTENTIONALLY OMITTED
DO NOT INCLUDE THIS HEADER DIRECTLY
macros used:
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE - the transaction_safe specifier for
the current include (`transaction_safe` or nothing)
BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE - `std::true_type` or `std::false_type`,
tied on whether BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE is `transaction_safe`
BOOST_CLBL_TRTS_TRANSACTION_SAFE_SPECIFIER - `transaction_safe` when
BOOST_CLBL_TRTS_ENABLE_TRANSACTION_SAFE is enabled, otherwise nothing
BOOST_CLBL_TRTS_NOEXCEPT_SPEC - the noexcept specifier for
the current include (`noexcept` or nothing)
BOOST_CLBL_TRTS_IS_NOEXCEPT - `std::true_type` or `std::false_type`,
tied on whether BOOST_CLBL_TRTS_NOEXCEPT_SPEC is `noexcept`
BOOST_CLBL_TRTS_NOEXCEPT_SPECIFIER - `noexcept` if
BOOST_CLBL_TRTS_ENABLE_NOEXCEPT_TYPES is defined, otherwise nothing
*/
template<typename Return, typename... Args>
struct function<BOOST_CLBL_TRTS_ST Return(BOOST_CLBL_TRTS_VARARGS_CC *)(Args..., ...)
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPEC>
: default_callable_traits<> {
static constexpr bool value = true;
using has_varargs = std::true_type;
using traits = function;
using return_type = Return;
using arg_types = std::tuple<Args...>;
using non_invoke_arg_types = arg_types;
using type =
BOOST_CLBL_TRTS_ST Return(BOOST_CLBL_TRTS_VARARGS_CC *)(Args..., ...)
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
using function_type = Return(Args..., ...);
using qualified_function_type = function_type;
using remove_varargs =
BOOST_CLBL_TRTS_ST Return(BOOST_CLBL_TRTS_CC *)(Args...)
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE;
using add_varargs = type;
using is_noexcept = BOOST_CLBL_TRTS_IS_NOEXCEPT;
using remove_noexcept = BOOST_CLBL_TRTS_ST Return(BOOST_CLBL_TRTS_CC *)(Args..., ...)
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE;
using add_noexcept = BOOST_CLBL_TRTS_ST Return(BOOST_CLBL_TRTS_CC *)(Args..., ...)
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPECIFIER;
using is_transaction_safe = BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE;
using remove_transaction_safe = Return(BOOST_CLBL_TRTS_VARARGS_CC *)(Args..., ...)
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
using add_transaction_safe = Return(BOOST_CLBL_TRTS_VARARGS_CC *)(Args..., ...)
BOOST_CLBL_TRTS_TRANSACTION_SAFE_SPECIFIER
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
template<typename U>
using apply_member_pointer =
BOOST_CLBL_TRTS_ST Return(BOOST_CLBL_TRTS_VARARGS_CC U::*)(Args..., ...)
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
template<typename NewReturn>
using apply_return =
BOOST_CLBL_TRTS_ST NewReturn(BOOST_CLBL_TRTS_VARARGS_CC *)(Args..., ...)
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
template<template<class...> class Container>
using expand_args = Container<Args...>;
using is_member_pointer = std::false_type;
};

View File

@@ -1,94 +0,0 @@
/*
Copyright (c) 2001 Peter Dimov and Multi Media Ltd.
Copyright (c) 2016 Modified Work Barrett Adair
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
HEADER GUARDS INTENTIONALLY OMITTED
DO NOT INCLUDE THIS HEADER DIRECTLY
*/
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#define BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
#include <boost/callable_traits/detail/unguarded/pmf_2.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS const
#define BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS \
BOOST_CLBL_TRTS_ABOMINABLE_CONST
#include <boost/callable_traits/detail/unguarded/pmf_2.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS volatile
#define BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS \
BOOST_CLBL_TRTS_ABOMINABLE_VOLATILE
#include <boost/callable_traits/detail/unguarded/pmf_2.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS const volatile
#define BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS \
BOOST_CLBL_TRTS_ABOMINABLE_CONST BOOST_CLBL_TRTS_ABOMINABLE_VOLATILE
#include <boost/callable_traits/detail/unguarded/pmf_2.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
#ifndef BOOST_CLBL_TRTS_DISABLE_REFERENCE_QUALIFIERS
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS &
#define BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS &
#include <boost/callable_traits/detail/unguarded/pmf_2.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS &&
#define BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS &&
#include <boost/callable_traits/detail/unguarded/pmf_2.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS const &
#define BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS const &
#include <boost/callable_traits/detail/unguarded/pmf_2.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS volatile &
#define BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS volatile &
#include <boost/callable_traits/detail/unguarded/pmf_2.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS const volatile &
#define BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS const volatile &
#include <boost/callable_traits/detail/unguarded/pmf_2.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS const &&
#define BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS const &&
#include <boost/callable_traits/detail/unguarded/pmf_2.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS volatile &&
#define BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS volatile &&
#include <boost/callable_traits/detail/unguarded/pmf_2.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS const volatile &&
#define BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS const volatile &&
#include <boost/callable_traits/detail/unguarded/pmf_2.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
#endif // #ifndef BOOST_CLBL_TRTS_DISABLE_REFERENCE_QUALIFIERS

View File

@@ -1,74 +0,0 @@
/*
Copyright (c) 2016 Barrett Adair
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
HEADER GUARDS INTENTIONALLY OMITTED
DO NOT INCLUDE THIS HEADER DIRECTLY
*/
template<typename Return, typename T, typename... Args>
struct set_member_function_qualifiers_t<
flag_map<int BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS>::value,
false, // IsTransactionSafe
false, // IsNoexcept
BOOST_CLBL_TRTS_CC_TAG, T, Return, Args...> {
using type = Return(BOOST_CLBL_TRTS_CC T::*)(Args...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS;
};
template<typename Return, typename T, typename... Args>
struct set_member_function_qualifiers_t<
flag_map<int BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS>::value,
false,
true,
BOOST_CLBL_TRTS_CC_TAG, T, Return, Args...> {
using type = Return(BOOST_CLBL_TRTS_CC T::*)(Args...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_NOEXCEPT_SPECIFIER;
};
template<typename Return, typename T, typename... Args>
struct set_member_function_qualifiers_t<
flag_map<int BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS>::value,
true,
false,
BOOST_CLBL_TRTS_CC_TAG, T, Return, Args...> {
using type = Return(BOOST_CLBL_TRTS_CC T::*)(Args...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_TRANSACTION_SAFE_SPECIFIER;
};
template<typename Return, typename T, typename... Args>
struct set_member_function_qualifiers_t<
flag_map<int BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS>::value,
true,
true,
BOOST_CLBL_TRTS_CC_TAG, T, Return, Args...> {
using type = Return(BOOST_CLBL_TRTS_CC T::*)(Args...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_TRANSACTION_SAFE_SPECIFIER
BOOST_CLBL_TRTS_NOEXCEPT_SPECIFIER;
};
#define BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
#define BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE std::false_type
#include <boost/callable_traits/detail/unguarded/pmf_3.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
#undef BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE
#ifdef BOOST_CLBL_TRTS_ENABLE_TRANSACTION_SAFE
#define BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE std::true_type
#define BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE transaction_safe
#include <boost/callable_traits/detail/unguarded/pmf_3.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
#undef BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE
#endif

View File

@@ -1,23 +0,0 @@
/*
Copyright (c) 2016 Barrett Adair
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
HEADER GUARDS INTENTIONALLY OMITTED
DO NOT INCLUDE THIS HEADER DIRECTLY
*/
#define BOOST_CLBL_TRTS_NOEXCEPT_SPEC
#define BOOST_CLBL_TRTS_IS_NOEXCEPT std::false_type
#include <boost/callable_traits/detail/unguarded/pmf_4.hpp>
#undef BOOST_CLBL_TRTS_NOEXCEPT_SPEC
#undef BOOST_CLBL_TRTS_IS_NOEXCEPT
#ifdef BOOST_CLBL_TRTS_ENABLE_NOEXCEPT_TYPES
#define BOOST_CLBL_TRTS_NOEXCEPT_SPEC noexcept
#define BOOST_CLBL_TRTS_IS_NOEXCEPT std::true_type
#include <boost/callable_traits/detail/unguarded/pmf_4.hpp>
#undef BOOST_CLBL_TRTS_NOEXCEPT_SPEC
#undef BOOST_CLBL_TRTS_IS_NOEXCEPT
#endif // #ifdef BOOST_CLBL_TRTS_ENABLE_NOEXCEPT_TYPES

View File

@@ -1,147 +0,0 @@
/*
Copyright (c) 2016 Barrett Adair
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
HEADER GUARDS INTENTIONALLY OMITTED
DO NOT INCLUDE THIS HEADER DIRECTLY
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS - the function-level qualifiers for the
current inclusion (combinations of `const` `volatile` `&` `&&`, or nothing)
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE - the transaction_safe specifier for
the current include (`transaction_safe` or nothing)
BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE - `std::true_type` or `std::false_type`,
tied on whether BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE is `transaction_safe`
BOOST_CLBL_TRTS_TRANSACTION_SAFE_SPECIFIER - `transaction_safe` when
BOOST_CLBL_TRTS_ENABLE_TRANSACTION_SAFE is defined, otherwise nothing
BOOST_CLBL_TRTS_NOEXCEPT_SPEC - the noexcept specifier for
the current include (`noexcept` or nothing)
BOOST_CLBL_TRTS_IS_NOEXCEPT - `std::true_type` or `std::false_type`,
tied on whether BOOST_CLBL_TRTS_NOEXCEPT_SPEC is `noexcept`
BOOST_CLBL_TRTS_NOEXCEPT_SPECIFIER - `noexcept` if
BOOST_CLBL_TRTS_ENABLE_NOEXCEPT_TYPES is defined, otherwise nothing
*/
template<typename Return, typename T, typename... Args>
struct pmf<Return(BOOST_CLBL_TRTS_CC T::*)(Args...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPEC>
: default_callable_traits<dummy BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS> {
static constexpr bool value = true;
using traits = pmf;
using return_type = Return;
using type = Return(BOOST_CLBL_TRTS_CC T::*)(Args...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
using invoke_type = typename std::conditional<
std::is_rvalue_reference<T BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS>::value,
T BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS,
typename std::add_lvalue_reference<T BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS>::type
>::type;
using arg_types = std::tuple<invoke_type, Args...>;
using non_invoke_arg_types = std::tuple<Args...>;
using function_object_signature = Return(Args...);
using function_type = Return(invoke_type, Args...);
using qualified_function_type = Return(Args...)
BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
using remove_varargs = type;
using add_varargs =
Return(BOOST_CLBL_TRTS_VARARGS_CC T::*)(Args..., ...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
using is_noexcept = BOOST_CLBL_TRTS_IS_NOEXCEPT;
using remove_noexcept = Return(BOOST_CLBL_TRTS_CC T::*)(Args...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE;
using add_noexcept = Return(BOOST_CLBL_TRTS_CC T::*)(Args...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPECIFIER;
using is_transaction_safe = BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE;
using remove_transaction_safe = Return(BOOST_CLBL_TRTS_CC T::*)(Args...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
using add_transaction_safe = Return(BOOST_CLBL_TRTS_CC T::*)(Args...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_TRANSACTION_SAFE_SPECIFIER
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
using class_type = T;
using qualifiers = default_callable_traits<dummy BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS>;
template<qualifier_flags Flags>
using set_qualifiers = set_member_function_qualifiers<
Flags, is_transaction_safe::value, is_noexcept::value,
BOOST_CLBL_TRTS_CC_TAG, T, Return, Args...>;
using remove_member_reference = set_qualifiers<qualifiers::cv_flags>;
using add_member_lvalue_reference = set_qualifiers<
collapse_flags<qualifiers::q_flags, lref_>::value>;
using add_member_rvalue_reference = set_qualifiers<
collapse_flags<qualifiers::q_flags, rref_>::value>;
using add_member_const = set_qualifiers<qualifiers::q_flags | const_>;
using add_member_volatile = set_qualifiers<qualifiers::q_flags | volatile_>;
using add_member_cv = set_qualifiers<qualifiers::q_flags | cv_>;
using remove_member_const = set_qualifiers<
qualifiers::ref_flags | remove_const_flag<qualifiers::cv_flags>::value>;
using remove_member_volatile = set_qualifiers<
qualifiers::ref_flags | remove_volatile_flag<qualifiers::cv_flags>::value>;
using remove_member_cv = set_qualifiers<qualifiers::ref_flags>;
template<typename U>
using apply_member_pointer =
Return(BOOST_CLBL_TRTS_CC U::*)(Args...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
template<typename NewReturn>
using apply_return =
NewReturn(BOOST_CLBL_TRTS_CC T::*)(Args...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
template<template<class...> class Container>
using expand_args = Container<invoke_type, Args...>;
using is_member_pointer = std::true_type;
};

View File

@@ -1,89 +0,0 @@
/*
Copyright (c) 2016 Barrett Adair
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
HEADER GUARDS INTENTIONALLY OMITTED
DO NOT INCLUDE THIS HEADER DIRECTLY
*/
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#define BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
#include <boost/callable_traits/detail/unguarded/pmf_varargs_2.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS const
#define BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS \
BOOST_CLBL_TRTS_ABOMINABLE_CONST
#include <boost/callable_traits/detail/unguarded/pmf_varargs_2.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS volatile
#define BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS \
BOOST_CLBL_TRTS_ABOMINABLE_VOLATILE
#include <boost/callable_traits/detail/unguarded/pmf_varargs_2.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS const volatile
#define BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS \
BOOST_CLBL_TRTS_ABOMINABLE_CONST BOOST_CLBL_TRTS_ABOMINABLE_VOLATILE
#include <boost/callable_traits/detail/unguarded/pmf_varargs_2.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
#ifndef BOOST_CLBL_TRTS_DISABLE_REFERENCE_QUALIFIERS
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS &
#define BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS &
#include <boost/callable_traits/detail/unguarded/pmf_varargs_2.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS &&
#define BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS &&
#include <boost/callable_traits/detail/unguarded/pmf_varargs_2.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS const &
#define BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS const &
#include <boost/callable_traits/detail/unguarded/pmf_varargs_2.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS volatile &
#define BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS volatile &
#include <boost/callable_traits/detail/unguarded/pmf_varargs_2.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS const volatile &
#define BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS const volatile &
#include <boost/callable_traits/detail/unguarded/pmf_varargs_2.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS const &&
#define BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS const &&
#include <boost/callable_traits/detail/unguarded/pmf_varargs_2.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS volatile &&
#define BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS volatile &&
#include <boost/callable_traits/detail/unguarded/pmf_varargs_2.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS const volatile &&
#define BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS const volatile &&
#include <boost/callable_traits/detail/unguarded/pmf_varargs_2.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
#endif // #ifndef BOOST_CLBL_TRTS_DISABLE_REFERENCE_QUALIFIERS

View File

@@ -1,78 +0,0 @@
/*
Copyright (c) 2016 Barrett Adair
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
HEADER GUARDS INTENTIONALLY OMITTED
DO NOT INCLUDE THIS HEADER DIRECTLY
*/
template<typename T, typename Return, typename... Args>
struct set_varargs_member_function_qualifiers_t <
flag_map<int BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS>::value,
false, // IsTransactionSafe
false, // IsNoexcept
BOOST_CLBL_TRTS_CC_TAG, T, Return, Args...> {
using type =
Return(BOOST_CLBL_TRTS_VARARGS_CC T::*)(Args..., ...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS;
};
template<typename T, typename Return, typename... Args>
struct set_varargs_member_function_qualifiers_t <
flag_map<int BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS>::value,
false,
true,
BOOST_CLBL_TRTS_CC_TAG, T, Return, Args...> {
using type =
Return(BOOST_CLBL_TRTS_VARARGS_CC T::*)(Args..., ...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS BOOST_CLBL_TRTS_NOEXCEPT_SPECIFIER;
};
template<typename T, typename Return, typename... Args>
struct set_varargs_member_function_qualifiers_t <
flag_map<int BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS>::value,
true,
false,
BOOST_CLBL_TRTS_CC_TAG, T, Return, Args...> {
using type =
Return(BOOST_CLBL_TRTS_VARARGS_CC T::*)(Args..., ...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_TRANSACTION_SAFE_SPECIFIER;
};
template<typename T, typename Return, typename... Args>
struct set_varargs_member_function_qualifiers_t <
flag_map<int BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS>::value,
true,
true,
BOOST_CLBL_TRTS_CC_TAG, T, Return, Args...> {
using type =
Return(BOOST_CLBL_TRTS_VARARGS_CC T::*)(Args..., ...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_TRANSACTION_SAFE_SPECIFIER
BOOST_CLBL_TRTS_NOEXCEPT_SPECIFIER;
};
#define BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
#define BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE std::false_type
#include <boost/callable_traits/detail/unguarded/pmf_varargs_3.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
#undef BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE
#ifdef BOOST_CLBL_TRTS_ENABLE_TRANSACTION_SAFE
#define BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE std::true_type
#define BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE transaction_safe
#include <boost/callable_traits/detail/unguarded/pmf_varargs_3.hpp>
#endif
#undef BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
#undef BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE

View File

@@ -1,23 +0,0 @@
/*
Copyright (c) 2016 Barrett Adair
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
HEADER GUARDS INTENTIONALLY OMITTED
DO NOT INCLUDE THIS HEADER DIRECTLY
*/
#define BOOST_CLBL_TRTS_NOEXCEPT_SPEC
#define BOOST_CLBL_TRTS_IS_NOEXCEPT std::false_type
#include <boost/callable_traits/detail/unguarded/pmf_varargs_4.hpp>
#undef BOOST_CLBL_TRTS_NOEXCEPT_SPEC
#undef BOOST_CLBL_TRTS_IS_NOEXCEPT
#ifdef BOOST_CLBL_TRTS_ENABLE_NOEXCEPT_TYPES
#define BOOST_CLBL_TRTS_NOEXCEPT_SPEC noexcept
#define BOOST_CLBL_TRTS_IS_NOEXCEPT std::true_type
#include <boost/callable_traits/detail/unguarded/pmf_varargs_4.hpp>
#undef BOOST_CLBL_TRTS_NOEXCEPT_SPEC
#undef BOOST_CLBL_TRTS_IS_NOEXCEPT
#endif // #ifdef BOOST_CLBL_TRTS_ENABLE_NOEXCEPT_TYPES

View File

@@ -1,149 +0,0 @@
/*
Copyright (c) 2016 Barrett Adair
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
HEADER GUARDS INTENTIONALLY OMITTED
DO NOT INCLUDE THIS HEADER DIRECTLY
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS - the function-level qualifiers for the
current inclusion (combinations of `const` `volatile` `&` `&&`, or nothing)
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE - the transaction_safe specifier for
the current include (`transaction_safe` or nothing)
BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE - `std::true_type` or `std::false_type`,
tied on whether BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE is `transaction_safe`
BOOST_CLBL_TRTS_TRANSACTION_SAFE_SPECIFIER - `transaction_safe` when
BOOST_CLBL_TRTS_ENABLE_TRANSACTION_SAFE is enabled, otherwise nothing
BOOST_CLBL_TRTS_NOEXCEPT_SPEC - the noexcept specifier for
the current include (`noexcept` or nothing)
BOOST_CLBL_TRTS_IS_NOEXCEPT - `std::true_type` or `std::false_type`,
tied on whether BOOST_CLBL_TRTS_NOEXCEPT_SPEC is `noexcept`
BOOST_CLBL_TRTS_NOEXCEPT_SPECIFIER - `noexcept` if
BOOST_CLBL_TRTS_ENABLE_NOEXCEPT_TYPES is defined, otherwise nothing
*/
template<typename Return, typename T, typename... Args>
struct pmf<Return(BOOST_CLBL_TRTS_VARARGS_CC T::*)(Args..., ...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPEC>
: default_callable_traits<dummy BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS> {
static constexpr bool value = true;
using has_varargs = std::true_type;
using traits = pmf;
using return_type = Return;
using type = Return(BOOST_CLBL_TRTS_VARARGS_CC T::*)(Args..., ...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
using invoke_type = typename std::conditional<
std::is_rvalue_reference<T BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS>::value,
T BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS,
typename std::add_lvalue_reference<T BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS>::type
>::type;
using arg_types = std::tuple<invoke_type, Args...>;
using non_invoke_arg_types = std::tuple<Args...>;
using function_object_signature = Return(Args..., ...);
using function_type = Return(invoke_type, Args..., ...);
using qualified_function_type = Return(Args..., ...)
BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
using remove_varargs =
Return(BOOST_CLBL_TRTS_CC T::*)(Args...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
using add_varargs = type;
using is_noexcept = BOOST_CLBL_TRTS_IS_NOEXCEPT;
using remove_noexcept = Return(BOOST_CLBL_TRTS_CC T::*)(Args..., ...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE;
using add_noexcept = Return(BOOST_CLBL_TRTS_CC T::*)(Args..., ...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPECIFIER;
using is_transaction_safe = BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE;
using remove_transaction_safe = Return(BOOST_CLBL_TRTS_VARARGS_CC T::*)(Args..., ...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
using add_transaction_safe = Return(BOOST_CLBL_TRTS_VARARGS_CC T::*)(Args..., ...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_TRANSACTION_SAFE_SPECIFIER
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
using class_type = T;
using qualifiers = default_callable_traits<dummy BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS>;
template<qualifier_flags Flags>
using set_qualifiers = set_varargs_member_function_qualifiers<
Flags, is_transaction_safe::value, is_noexcept::value,
BOOST_CLBL_TRTS_CC_TAG, T, Return, Args...>;
using remove_member_reference = set_qualifiers<qualifiers::cv_flags>;
using add_member_lvalue_reference = set_qualifiers<
collapse_flags<qualifiers::q_flags, lref_>::value>;
using add_member_rvalue_reference = set_qualifiers<
collapse_flags<qualifiers::q_flags, rref_>::value>;
using add_member_const = set_qualifiers<qualifiers::q_flags | const_>;
using add_member_volatile = set_qualifiers<qualifiers::q_flags | volatile_>;
using add_member_cv = set_qualifiers<qualifiers::q_flags | cv_>;
using remove_member_const = set_qualifiers<
qualifiers::ref_flags | remove_const_flag<qualifiers::cv_flags>::value>;
using remove_member_volatile = set_qualifiers<
qualifiers::ref_flags | remove_volatile_flag<qualifiers::cv_flags>::value>;
using remove_member_cv = set_qualifiers<qualifiers::ref_flags>;
template<typename U>
using apply_member_pointer =
Return(BOOST_CLBL_TRTS_VARARGS_CC U::*)(Args..., ...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
template<typename NewReturn>
using apply_return =
NewReturn(BOOST_CLBL_TRTS_VARARGS_CC T::*)(Args..., ...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
template<template<class...> class Container>
using expand_args = Container<invoke_type, Args...>;
using is_member_pointer = std::true_type;
};

View File

@@ -1,111 +0,0 @@
/*
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_DETAIL_UTILITY_HPP
#define BOOST_CLBL_TRTS_DETAIL_UTILITY_HPP
#include <boost/callable_traits/detail/config.hpp>
#include <boost/callable_traits/detail/sfinae_errors.hpp>
#include <boost/callable_traits/detail/qualifier_flags.hpp>
namespace boost { namespace callable_traits { namespace detail {
struct cdecl_tag{};
struct stdcall_tag{};
struct fastcall_tag{};
struct pascal_tag{};
struct invalid_type { invalid_type() = delete; };
struct reference_error { reference_error() = delete; };
template<typename T>
using error_type = typename std::conditional<
std::is_reference<T>::value, reference_error, invalid_type>::type;
#ifdef BOOST_CLBL_TRTS_DISABLE_ABOMINABLE_FUNCTIONS
struct abominable_functions_not_supported_on_this_compiler{};
#endif
// used to convey "this type doesn't matter" in code
struct dummy {};
// used as return type in failed SFINAE tests
struct substitution_failure : std::false_type{};
template<bool Value>
using bool_type = std::integral_constant<bool, Value>;
// shorthand for std::tuple_element
template<std::size_t I, typename Tup>
using at = typename std::tuple_element<I, Tup>::type;
template<typename T, typename Class>
using add_member_pointer = T Class::*;
template<typename L, typename R, typename ErrorType>
using fail_when_same = fail_if<std::is_same<L, R>::value, ErrorType>;
template<typename T, typename ErrorType,
typename U = typename std::remove_reference<T>::type>
using try_but_fail_if_invalid = sfinae_try<T,
fail_when_same<U, invalid_type, ErrorType>,
fail_when_same<U, reference_error,
reference_type_not_supported_by_this_metafunction>>;
template<typename T, typename ErrorType,
typename U = typename std::remove_reference<T>::type,
bool is_reference_error = std::is_same<reference_error, U>::value>
using fail_if_invalid = fail_if<
std::is_same<U, invalid_type>::value || is_reference_error,
typename std::conditional<is_reference_error,
reference_type_not_supported_by_this_metafunction, ErrorType>::type>;
template<typename T, typename Fallback>
using fallback_if_invalid = typename std::conditional<
std::is_same<T, invalid_type>::value, Fallback, T>::type;
template<typename T, template<class> class Alias, typename U = Alias<T>>
struct force_sfinae {
using type = U;
};
template<typename T>
using shallow_decay = typename std::remove_cv<
typename std::remove_reference<T>::type>::type;
template<typename T>
struct is_reference_wrapper_t {
using type = std::false_type;
};
template<typename T>
struct is_reference_wrapper_t<std::reference_wrapper<T>> {
using type = std::true_type;
};
template<typename T>
using is_reference_wrapper =
typename is_reference_wrapper_t<shallow_decay<T>>::type;
template<typename T, typename = std::true_type>
struct unwrap_reference_t {
using type = T;
};
template<typename T>
struct unwrap_reference_t<T, is_reference_wrapper<T>> {
using type = decltype(std::declval<T>().get());
};
// removes std::reference_wrapper
template<typename T>
using unwrap_reference = typename unwrap_reference_t<T>::type;
}}} // namespace boost::callable_traits::detail
#endif // #ifndef BOOST_CLBL_TRTS_DETAIL_UTILITY_HPP

View File

@@ -1,97 +0,0 @@
/*
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_FUNCTION_TYPE_HPP
#define BOOST_CLBL_TRTS_FUNCTION_TYPE_HPP
#include <boost/callable_traits/detail/core.hpp>
namespace boost { namespace callable_traits {
//[ function_type_hpp
/*`[section:ref_function_type function_type]
[heading Header]
``#include <boost/callable_traits/function_type.hpp>``
[heading Definition]
*/
template<typename T>
using function_type_t = //see below
//<-
detail::try_but_fail_if_invalid<typename detail::traits<
detail::shallow_decay<T>>::function_type,
cannot_determine_parameters_for_this_type>;
namespace detail {
template<typename T, typename = std::false_type>
struct function_type_impl {};
template<typename T>
struct function_type_impl <T, typename std::is_same<
function_type_t<T>, detail::dummy>::type>
{
using type = function_type_t<T>;
};
}
//->
template<typename T>
struct function_type : detail::function_type_impl<T> {};
//<-
}} // namespace boost::callable_traits
//->
/*`
[heading Constraints]
* `T` must be one of the following:
* function
* function pointer
* function reference
* member function pointer
* member data pointer
* user-defined type with a non-overloaded `operator()`
* type of a non-generic lambda
[heading Behavior]
* When the constraints are violated, a substitution failure occurs.
* When `T` is a function, the aliased type is identical to `T`, except that the aliased function type will not have member qualifiers or the `transaction_safe` specifier.
* When `T` is a function pointer, the aliased type is equivalent to `std::remove_pointer_t<T>`.
* When `T` is a function reference, the aliased type is equivalent to `std::remove_reference_t<T>`.
* When `T` is a function object, the aliased type is a function type with the same return type and parameter list as `T`'s `operator()`.
* When `T` is a member function pointer, the aliased type is a function type with the same return type as `T`, and the first parameter is a reference to the parent class of `T`, qualified according to the member qualifiers on `T`. The subsequent parameters, if any, are the parameter types of `T`.
* When `T` is a member data pointer, the aliased type is a function type returning the underlying member type of `T`, taking a single parameter, which is a `const` reference to the parent type of `T`.
* In all cases, the aliased function type will not have member qualifiers, and will not have the `transaction_safe` specifier.
[heading Input/Output Examples]
[table
[[`T`] [`function_type_t<T>`]]
[[`void(int)`] [`void(int)`]]
[[`void(int) const`] [`void(int)`]]
[[`void(int) transaction_safe`] [`void(int)`]]
[[`void(*const &)(int)`] [`void(int)`]]
[[`void(&)(int)`] [`void(int)`]]
[[`void(* volatile)()`] [`void()`]]
[[`int(foo::*)(int)`] [`int(foo&, int)`]]
[[`int(foo::*)(int) const`] [`int(const foo&, int)`]]
[[`void(foo::*)() volatile &&`] [`void(volatile foo&&)`]]
[[`int foo::*`] [`int(const foo&)`]]
[[`const int foo::*`] [`int(const foo&)`]]
[[`int`] [(substitution failure)]]
]
[heading Example Program]
[import ../example/function_type.cpp]
[function_type]
[endsect]
*/
//]
#endif

View File

@@ -1,99 +0,0 @@
/*
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_HAS_MEMBER_QUALIFIERS_HPP
#define BOOST_CLBL_TRTS_HAS_MEMBER_QUALIFIERS_HPP
#include <boost/callable_traits/detail/core.hpp>
namespace boost { namespace callable_traits {
//[ has_member_qualifiers_hpp
/*`[section:ref_has_member_qualifiers has_member_qualifiers]
[heading Header]
``#include <boost/callable_traits/has_member_qualifiers.hpp>``
[heading Definition]
*/
// inherits from either std::true_type or std::false_type
template<typename T>
struct has_member_qualifiers;
//<-
template<typename T>
struct has_member_qualifiers : detail::traits<
detail::shallow_decay<T>>::has_member_qualifiers {
using type = typename detail::traits<
detail::shallow_decay<T>>::has_member_qualifiers;
};
// older compilers don't support variable templates
#ifdef BOOST_CLBL_TRTS_DISABLE_VARIABLE_TEMPLATES
template<typename T>
struct has_member_qualifiers_v {
static_assert(std::is_same<T, detail::dummy>::value,
"Variable templates not supported on this compiler.");
};
#else
//->
// only available when variable templates are supported
template<typename T>
//<-
BOOST_CLBL_TRAITS_INLINE_VAR
//->
constexpr bool has_member_qualifiers_v = //see below
//<-
detail::traits<detail::shallow_decay<T>>::has_member_qualifiers::value;
#endif
}} // namespace boost::callable_traits
//->
/*`
[heading Constraints]
* none
[heading Behavior]
* `std::false_type` is inherited by `has_member_qualifiers<T>` and is aliased by `typename has_member_qualifiers<T>::type`, except when one of the following criteria is met, in which case `std::true_type` would be similarly inherited and aliased:
* `T` is a function with member qualifiers
* `T` is a member function pointer with member qualifiers
* `T` is a function object with a member-qualified `operator()`
* On compilers that support variable templates, `has_member_qualifiers_v<T>` is equivalent to `has_member_qualifiers<T>::value`.
[heading Input/Output Examples]
[table
[[`T`] [`has_member_qualifiers_v<T>`]]
[[`void() const`] [`true`]]
[[`void() const transaction_safe`] [`true`]]
[[`void() volatile &&`] [`true`]]
[[`int(foo::*)() &`] [`true`]]
[[`void(foo::*)() const`] [`true`]]
[[`void(foo::*&)() const`] [`true`]]
[[`void(foo::* const)() const`] [`true`]]
[[`void()`] [`false`]]
[[`void() transaction_safe`] [`false`]]
[[`void(*)()`] [`false`]]
[[`void(*&)()`] [`false`]]
[[`int`] [`false`]]
[[`const int`] [`false`]]
[[`int foo::*`] [`false`]]
[[`const int foo::*`] [`false`]]
]
[heading Example Program]
[import ../example/has_member_qualifiers.cpp]
[has_member_qualifiers]
[endsect]
*/
//]
#endif //BOOST_CLBL_TRTS_HAS_MEMBER_QUALIFIERS_HPP

View File

@@ -1,94 +0,0 @@
/*
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_HAS_VARARGS_HPP
#define BOOST_CLBL_TRTS_HAS_VARARGS_HPP
#include <boost/callable_traits/detail/core.hpp>
namespace boost { namespace callable_traits {
//[ has_varargs_hpp
/*`[section:ref_has_varargs has_varargs]
[heading Header]
``#include <boost/callable_traits/has_varargs.hpp>``
[heading Definition]
*/
// inherits from either std::true_type or std::false_type
template<typename T>
struct has_varargs;
//<-
template<typename T>
struct has_varargs : detail::traits<
detail::shallow_decay<T>>::has_varargs {
using type = typename detail::traits<
detail::shallow_decay<T>>::has_varargs;
};
#ifdef BOOST_CLBL_TRTS_DISABLE_VARIABLE_TEMPLATES
template<typename T>
struct has_varargs_v {
static_assert(std::is_same<T, detail::dummy>::value,
"Variable templates not supported on this compiler.");
};
#else
//->
// only available when variable templates are supported
template<typename T>
//<-
BOOST_CLBL_TRAITS_INLINE_VAR
//->
constexpr bool has_varargs_v = //see below
//<-
detail::traits<detail::shallow_decay<T>>::has_varargs::value;
#endif
}} // namespace boost::callable_traits
//->
/*`
[heading Constraints]
* none
[heading Behavior]
* `std::false_type` is inherited by `has_varargs<T>` and is aliased by `typename has_varargs<T>::type`, except when one of the following criteria is met, in which case `std::true_type` would be similarly inherited and aliased:
* `T` is a function, function pointer, or function reference where the function's parameter list includes C-style variadics.
* `T` is a pointer to a member function with C-style variadics in the parameter list.
* `T` is a function object with a non-overloaded `operator()`, which has C-style variadics in the parameter list of its `operator()`.
* On compilers that support variable templates, `has_varargs_v<T>` is equivalent to `has_varargs<T>::value`.
[heading Input/Output Examples]
[table
[[`T`] [`has_varargs_v<T>`]]
[[`void(...)`] [`true`]]
[[`void(int, ...) const`] [`true`]]
[[`void(* volatile)(...)`] [`true`]]
[[`void(&)(...)`] [`true`]]
[[`void(foo::*)(...) const`] [`true`]]
[[`void(*)()`] [`false`]]
[[`void(*&)()`] [`false`]]
[[`int`] [`false`]]
[[`const int`] [`false`]]
[[`int foo::*`] [`false`]]
]
[heading Example Program]
[import ../example/has_varargs.cpp]
[has_varargs]
[endsect]
*/
//]
#endif

View File

@@ -1,93 +0,0 @@
/*
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_HAS_VOID_RETURN_HPP
#define BOOST_CLBL_TRTS_HAS_VOID_RETURN_HPP
#include <boost/callable_traits/detail/core.hpp>
namespace boost { namespace callable_traits {
//[ has_void_return_hpp
/*`[section:ref_has_void_return has_void_return]
[heading Header]
``#include <boost/callable_traits/has_void_return.hpp>``
[heading Definition]
*/
// inherits from either std::true_type or std::false_type
template<typename T>
struct has_void_return;
//<-
template<typename T>
struct has_void_return
: std::is_same<typename detail::traits<
detail::shallow_decay<T>>::return_type, void> {};
#ifdef BOOST_CLBL_TRTS_DISABLE_VARIABLE_TEMPLATES
template<typename T>
struct has_void_return_v {
static_assert(std::is_same<T, detail::dummy>::value,
"Variable templates not supported on this compiler.");
};
#else
//->
// only available when variable templates are supported
template<typename T>
//<-
BOOST_CLBL_TRAITS_INLINE_VAR
//->
constexpr bool has_void_return_v = //see below
//<-
std::is_same<typename detail::traits<
detail::shallow_decay<T>>::return_type, void>::value;
#endif
}} // namespace boost::callable_traits
//->
/*`
[heading Constraints]
* none
[heading Behavior]
* `std::false_type` is inherited by `has_void_return<T>` and is aliased by `typename has_void_return<T>::type`, except when one of the following criteria is met, in which case `std::true_type` would be similarly inherited and aliased:
* `T` is a function, function pointer, or function reference where the function's return type is `void`.
* `T` is a pointer to a member function whose return type is `void`.
* `T` is a function object with a non-overloaded `operator()`, where the `operator()` function returns `void`.
* On compilers that support variable templates, `has_void_return_v<T>` is equivalent to `has_void_return<T>::value`.
[heading Input/Output Examples]
[table
[[`T`] [`has_void_return_v<T>`]]
[[`void()`] [`true`]]
[[`void(int) const`] [`true`]]
[[`void(* const &)()`] [`true`]]
[[`void(&)()`] [`true`]]
[[`void(foo::*)() const`] [`true`]]
[[`int(*)()`] [`false`]]
[[`int(*&)()`] [`false`]]
[[`int`] [`false`]]
[[`int foo::*`] [`false`]]
[[`void* foo::*`] [`false`]]
]
[heading Example Program]
[import ../example/has_void_return.cpp]
[has_void_return]
[endsect]
*/
//]
#endif

View File

@@ -1,97 +0,0 @@
/*
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_IS_CONST_MEMBER_HPP
#define BOOST_CLBL_TRTS_IS_CONST_MEMBER_HPP
#include <boost/callable_traits/detail/core.hpp>
namespace boost { namespace callable_traits {
//[ is_const_member_hpp
/*`[section:ref_is_const_member is_const_member]
[heading Header]
``#include <boost/callable_traits/is_const_member.hpp>``
[heading Definition]
*/
// inherits from either std::true_type or std::false_type
template<typename T>
struct is_const_member;
//<-
template<typename T>
struct is_const_member
: detail::traits<detail::shallow_decay<T>>::is_const_member {
using type = typename detail::traits<
detail::shallow_decay<T>>::is_const_member;
};
#ifdef BOOST_CLBL_TRTS_DISABLE_VARIABLE_TEMPLATES
template<typename T>
struct is_const_member_v {
static_assert(std::is_same<T, detail::dummy>::value,
"Variable templates not supported on this compiler.");
};
#else
//->
// only available when variable templates are supported
template<typename T>
//<-
BOOST_CLBL_TRAITS_INLINE_VAR
//->
constexpr bool is_const_member_v = //see below
//<-
detail::traits<detail::shallow_decay<T>>::is_const_member::value;
#endif
}} // namespace boost::callable_traits
//->
/*`
[heading Constraints]
* none
[heading Behavior]
* `is_const_member<T>::value` is `true` when either:
* `T` is a function type with a `const` member qualifier
* `T` is a pointer to a member function with a `const` member qualifier
* `T` is a function object with a non-overloaded `operator()`, where the `operator()` has a `const` member qualifier
* On compilers that support variable templates, `is_const_member_v<T>` is equivalent to `is_const_member<T>::value`.
[heading Input/Output Examples]
[table
[[`T`] [`is_const_member_v<T>`]]
[[`int() const`] [`true`]]
[[`int() const volatile`] [`true`]]
[[`int() const & transaction_safe`] [`true`]]
[[`int() const &&`] [`true`]]
[[`int(foo::*&)() const`] [`true`]]
[[`int(foo::*)() const volatile`] [`true`]]
[[`int(foo::*)() const volatile &&`][`true`]]
[[`int(foo::* const)() const`] [`true`]]
[[`int()`] [`false`]]
[[`int() volatile`] [`false`]]
[[`int() &&`] [`false`]]
[[`int(*)()`] [`false`]]
[[`int`] [`false`]]
[[`int foo::*`] [`false`]]
[[`const int foo::*`] [`false`]]
]
[heading Example Program]
[import ../example/is_const_member.cpp]
[is_const_member]
[endsect]
*/
//]
#endif // #ifndef BOOST_CLBL_TRTS_IS_CONST_MEMBER_HPP

View File

@@ -1,95 +0,0 @@
/*
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_IS_CV_MEMBER_HPP
#define BOOST_CLBL_TRTS_IS_CV_MEMBER_HPP
#include <boost/callable_traits/detail/core.hpp>
namespace boost { namespace callable_traits {
//[ is_cv_member_hpp
/*`[section:ref_is_cv_member is_cv_member]
[heading Header]
``#include <boost/callable_traits/is_cv_member.hpp>``
[heading Definition]
*/
// inherits from either std::true_type or std::false_type
template<typename T>
struct is_cv_member;
//<-
template<typename T>
struct is_cv_member
: detail::traits<detail::shallow_decay<T>>::is_cv_member {
using type = typename detail::traits<
detail::shallow_decay<T>>::is_cv_member;
};
#ifdef BOOST_CLBL_TRTS_DISABLE_VARIABLE_TEMPLATES
template<typename T>
struct is_cv_member_v {
static_assert(std::is_same<T, detail::dummy>::value,
"Variable templates not supported on this compiler.");
};
#else
//->
// only available when variable templates are supported
template<typename T>
//<-
BOOST_CLBL_TRAITS_INLINE_VAR
//->
constexpr bool is_cv_member_v = //see below
//<-
detail::traits<detail::shallow_decay<T>>::is_cv_member::value;
#endif
}} // namespace boost::callable_traits
//->
/*`
[heading Constraints]
* none
[heading Behavior]
* `is_cv_member<T>::value` is `true` when either:
* `T` is a function type with both `const` and `volatile` member qualifiers
* `T` is a pointer to a member function with both `const` and `volatile` member qualifiers
* `T` is a function object with a non-overloaded `operator()`, where the `operator()` has both `const` and `volatile` member qualifiers
* On compilers that support variable templates, `is_cv_member_v<T>` is equivalent to `is_cv_member<T>::value`.
[heading Input/Output Examples]
[table
[[`T`] [`is_cv_member_v<T>`]]
[[`int() const volatile`] [`true`]]
[[`int() const volatile &`] [`true`]]
[[`int(foo::* const &)() const volatile`] [`true`]]
[[`int() const`] [`false`]]
[[`int() volatile`] [`false`]]
[[`int(foo::*)() const`] [`false`]]
[[`int() const`] [`false`]]
[[`int() volatile`] [`false`]]
[[`int() &&`] [`false`]]
[[`int(*)()`] [`false`]]
[[`int`] [`false`]]
[[`int foo::*`] [`false`]]
[[`const int foo::*`] [`false`]]
]
[heading Example Program]
[import ../example/is_cv_member.cpp]
[is_cv_member]
[endsect]
*/
//]
#endif // #ifndef BOOST_CLBL_TRTS_IS_CV_MEMBER_HPP

View File

@@ -1,103 +0,0 @@
/*
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_IS_INVOCABLE_HPP
#define BOOST_CLBL_TRTS_IS_INVOCABLE_HPP
#include <boost/callable_traits/detail/core.hpp>
#include <boost/callable_traits/detail/is_invocable_impl.hpp>
namespace boost { namespace callable_traits {
//[ is_invocable_hpp
/*`[section:ref_is_invocable is_invocable]
[heading Header]
``#include <boost/callable_traits/is_invocable.hpp>``
[heading Definition]
*/
// inherits from either std::true_type or std::false_type
template<typename T, typename... Args>
struct is_invocable;
// inherits from either std::true_type or std::false_type
template<typename Ret, typename T, typename... Args>
struct is_invocable_r;
//<-
template<typename T, typename... Args>
struct is_invocable : detail::is_invocable_impl<T, Args...>::type {
using type = typename detail::is_invocable_impl<T, Args...>::type;
};
template<typename Ret, typename T, typename... Args>
struct is_invocable_r
: detail::is_invocable_r_impl<
typename detail::is_invocable_impl<T, Args...>::type, Ret, T, Args...>::type
{
using type = typename detail::is_invocable_r_impl<
typename detail::is_invocable_impl<T, Args...>::type, Ret, T, Args...>::type;
};
#ifdef BOOST_CLBL_TRTS_DISABLE_VARIABLE_TEMPLATES
template<typename T, typename... Args>
struct is_invocable_v {
static_assert(std::is_same<T, detail::dummy>::value,
"Variable templates not supported on this compiler.");
};
template<typename Ret, typename T, typename... Args>
struct is_invocable_r_v {
static_assert(std::is_same<T, detail::dummy>::value,
"Variable templates not supported on this compiler.");
};
#else
//->
// only available when variable templates are supported
template<typename T, typename... Args>
//<-
BOOST_CLBL_TRAITS_INLINE_VAR
//->
constexpr bool is_invocable_v = //see below
//<-
detail::is_invocable_impl<detail::traits<T>, Args...>::type::value;
//->
// only available when variable templates are supported
template<typename Ret, typename T, typename... Args>
//<-
BOOST_CLBL_TRAITS_INLINE_VAR
//->
constexpr bool is_invocable_r_v = //see below
//<-
detail::is_invocable_r_impl<
typename detail::is_invocable_impl<T, Args...>::type,
Ret, T, Args...>::type::value;
#endif
}} // namespace boost::callable_traits
//->
/*`
[heading Constraints]
* none
[heading Behavior]
* standalone c++11 implementation of c++17 `std::is_invocable`, `std::is_invocable_r`
[note ref-qualified overloads of `operator()` with different signatures are not handled correctly yet.]
[heading Example Program]
[import ../example/is_invocable.cpp]
[is_invocable]
[endsect]
*/
//]
#endif // #ifndef BOOST_CLBL_TRTS_IS_INVOCABLE_HPP

View File

@@ -1,95 +0,0 @@
/*
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_IS_LVALUE_REFERENCE_MEMBER_HPP
#define BOOST_CLBL_TRTS_IS_LVALUE_REFERENCE_MEMBER_HPP
#include <boost/callable_traits/detail/core.hpp>
namespace boost { namespace callable_traits {
//[ is_lvalue_reference_member_hpp
/*`[section:ref_is_lvalue_reference_member is_lvalue_reference_member]
[heading Header]
``#include <boost/callable_traits/is_lvalue_reference_member.hpp>``
[heading Definition]
*/
// inherits from either std::true_type or std::false_type
template<typename T>
struct is_lvalue_reference_member;
//<-
template<typename T>
struct is_lvalue_reference_member
: detail::traits<detail::shallow_decay<T>>::is_lvalue_reference_member {
using type = typename detail::traits<
detail::shallow_decay<T>>::is_lvalue_reference_member;
};
#ifdef BOOST_CLBL_TRTS_DISABLE_VARIABLE_TEMPLATES
template<typename T>
struct is_lvalue_reference_member_v {
static_assert(std::is_same<T, detail::dummy>::value,
"Variable templates not supported on this compiler.");
};
#else
//->
// only available when variable templates are supported
template<typename T>
//<-
BOOST_CLBL_TRAITS_INLINE_VAR
//->
constexpr bool is_lvalue_reference_member_v = //see below
//<-
detail::traits<detail::shallow_decay<T>>::is_lvalue_reference_member::value;
#endif
}} // namespace boost::callable_traits
//->
/*`
[heading Constraints]
* none
[heading Behavior]
* `is_lvalue_reference_member<T>::value` is `true` when either:
* `T` is a function type with a '&' member qualifier
* `T` is a pointer to a member function with a '&' member qualifiers
* `T` is a function object with a non-overloaded `operator()`, where the `operator()` has a '&' member qualifier
* On compilers that support variable templates, `is_lvalue_reference_member_v<T>` is equivalent to `is_lvalue_reference_member<T>::value`.
[heading Input/Output Examples]
[table
[[`T`] [`is_lvalue_reference_member_v<T>`]]
[[`int() &`] [`true`]]
[[`int(foo::* const)() const &`] [`true`]]
[[`int() const`] [`false`]]
[[`int() volatile`] [`false`]]
[[`int(foo::*)() const`] [`false`]]
[[`int() const`] [`false`]]
[[`int() volatile`] [`false`]]
[[`int() &&`] [`false`]]
[[`int(*)()`] [`false`]]
[[`int`] [`false`]]
[[`int foo::*`] [`false`]]
[[`const int foo::*`] [`false`]]
]
[heading Example Program]
[import ../example/is_lvalue_reference_member.cpp]
[is_lvalue_reference_member]
[endsect]
*/
//]
#endif // #ifndef BOOST_CLBL_TRTS_IS_LVALUE_REFERENCE_MEMBER_HPP

View File

@@ -1,95 +0,0 @@
/*
@file is_noexcept
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_IS_NOEXCEPT_HPP
#define BOOST_CLBL_TRTS_IS_NOEXCEPT_HPP
#include <boost/callable_traits/detail/core.hpp>
namespace boost { namespace callable_traits {
//[ is_noexcept_hpp
/*`[section:ref_is_noexcept is_noexcept]
[heading Header]
``#include <boost/callable_traits/is_noexcept.hpp>``
[heading Definition]
*/
// inherits from either std::true_type or std::false_type
template<typename T>
struct is_noexcept;
//<-
template<typename T>
struct is_noexcept : detail::traits<detail::shallow_decay<T>>::is_noexcept {
using type = typename detail::traits<
detail::shallow_decay<T>>::is_noexcept;
};
#ifdef BOOST_CLBL_TRTS_DISABLE_VARIABLE_TEMPLATES
template<typename T>
struct is_noexcept_v {
static_assert(std::is_same<T, detail::dummy>::value,
"Variable templates not supported on this compiler.");
};
#else
//->
// only available when variable templates are supported
template<typename T>
//<-
BOOST_CLBL_TRAITS_INLINE_VAR
//->
constexpr bool is_noexcept_v = //see below
//<-
detail::traits<detail::shallow_decay<T>>::is_noexcept::value;
#endif
}} // namespace boost::callable_traits
//->
/*`
[heading Constraints]
* none
*
[heading Behavior]
* `is_noexcept<T>::value` is `true` when either:
* `T` is a function type, function pointer type, function reference type, or member function pointer type where the function has a `noexcept` specifier
* `T` is a function object with a non-overloaded `operator()`, where the `operator()` has a `noexcept` specifier
* On compilers that support variable templates, `is_noexcept_v<T>` is equivalent to `is_noexcept<T>::value`.
[heading Input/Output Examples]
[table
[[`T`] [`is_noexcept_v<T>`]]
[[`int() const noexcept`] [`true`]]
[[`int(* const &)() noexcept`] [`true`]]
[[`int(&)() noexcept`] [`true`]]
[[`int(foo::*)() noexcept`] [`true`]]
[[`int() const`] [`false`]]
[[`int() volatile`] [`false`]]
[[`int(foo::*)() const`] [`false`]]
[[`int() const`] [`false`]]
[[`int() volatile`] [`false`]]
[[`int() &`] [`false`]]
[[`int(*)()`] [`false`]]
[[`int`] [`false`]]
[[`int foo::*`] [`false`]]
[[`const int foo::*`] [`false`]]
]
[heading Example Program]
[import ../example/is_noexcept.cpp]
[is_noexcept]
[endsect]
*/
//]
#endif // #ifndef BOOST_CLBL_TRTS_IS_NOEXCEPT_HPP

View File

@@ -1,98 +0,0 @@
/*
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_IS_REFERENCE_MEMBER_HPP
#define BOOST_CLBL_TRTS_IS_REFERENCE_MEMBER_HPP
#include <boost/callable_traits/detail/core.hpp>
namespace boost { namespace callable_traits {
//[ is_reference_member_hpp
/*`[section:ref_is_reference_member is_reference_member]
[heading Header]
``#include <boost/callable_traits/is_reference_member.hpp>``
[heading Definition]
*/
// inherits from either std::true_type or std::false_type
template<typename T>
struct is_reference_member;
//<-
template<typename T>
struct is_reference_member : detail::traits<
detail::shallow_decay<T>>::is_reference_member {
using type = typename detail::traits<
detail::shallow_decay<T>>::is_reference_member;
};
#ifdef BOOST_CLBL_TRTS_DISABLE_VARIABLE_TEMPLATES
template<typename T>
struct is_reference_member_v {
static_assert(std::is_same<T, detail::dummy>::value,
"Variable templates not supported on this compiler.");
};
#else
//->
// only available when variable templates are supported
template<typename T>
//<-
BOOST_CLBL_TRAITS_INLINE_VAR
//->
constexpr bool is_reference_member_v = //see below
//<-
detail::traits<detail::shallow_decay<T>>::is_reference_member::value;
#endif
}} // namespace boost::callable_traits
//->
/*`
[heading Constraints]
* none
[heading Behavior]
* `is_reference_member<T>::value` is `true` when either:
* `T` is a function type with a '&' or '&&' member qualifier
* `T` is a pointer to a member function with a '&' or '&&' member qualifiers
* `T` is a function object with a non-overloaded `operator()`, where the `operator()` has a '&' or '&&' member qualifier
* On compilers that support variable templates, `is_reference_member_v<T>` is equivalent to `is_reference_member<T>::value`.
[heading Input/Output Examples]
[table
[[`T`] [`is_reference_member_v<T>`]]
[[`int() &`] [`true`]]
[[`int() const &&`] [`true`]]
[[`int(foo::* const)() &&`] [`true`]]
[[`int(foo::*)(...) volatile &`] [`true`]]
[[`int() const`] [`false`]]
[[`int() volatile`] [`false`]]
[[`int(foo::*)() const`] [`false`]]
[[`int() const`] [`false`]]
[[`int() volatile`] [`false`]]
[[`int(*)()`] [`false`]]
[[`int`] [`false`]]
[[`int foo::*`] [`false`]]
[[`const int foo::*`] [`false`]]
]
[heading Example Program]
[import ../example/is_reference_member.cpp]
[is_reference_member]
[endsect]
*/
//]
#endif // #ifndef BOOST_CLBL_TRTS_IS_REFERENCE_MEMBER_HPP

View File

@@ -1,97 +0,0 @@
/*
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_IS_RVALUE_REFERENCE_MEMBER_HPP
#define BOOST_CLBL_TRTS_IS_RVALUE_REFERENCE_MEMBER_HPP
#include <boost/callable_traits/detail/core.hpp>
namespace boost { namespace callable_traits {
//[ is_rvalue_reference_member_hpp
/*`[section:ref_is_rvalue_reference_member is_rvalue_reference_member]
[heading Header]
``#include <boost/callable_traits/is_rvalue_reference_member.hpp>``
[heading Definition]
*/
// inherits from either std::true_type or std::false_type
template<typename T>
struct is_rvalue_reference_member;
//<-
template<typename T>
struct is_rvalue_reference_member : detail::traits<
detail::shallow_decay<T>>::is_rvalue_reference_member {
using type = typename detail::traits<
detail::shallow_decay<T>>::is_rvalue_reference_member;
};
#ifdef BOOST_CLBL_TRTS_DISABLE_VARIABLE_TEMPLATES
template<typename T>
struct is_rvalue_reference_member_v {
static_assert(std::is_same<T, detail::dummy>::value,
"Variable templates not supported on this compiler.");
};
#else
//->
// only available when variable templates are supported
template<typename T>
//<-
BOOST_CLBL_TRAITS_INLINE_VAR
//->
constexpr bool is_rvalue_reference_member_v = //see below
//<-
detail::traits<detail::shallow_decay<T>>::is_rvalue_reference_member::value;
#endif
}} // namespace boost::callable_traits
//->
/*`
[heading Constraints]
* none
[heading Behavior]
* `is_rvalue_reference_member<T>::value` is `true` when either:
* `T` is a function type with a '&&' member qualifier
* `T` is a pointer to a member function with a '&&' member qualifiers
* `T` is a function object with a non-overloaded `operator()`, where the `operator()` has a '&&' member qualifier
* On compilers that support variable templates, `is_rvalue_reference_member_v<T>` is equivalent to `is_rvalue_reference_member<T>::value`.
[heading Input/Output Examples]
[table
[[`T`] [`is_rvalue_reference_member_v<T>`]]
[[`int() const &&`] [`true`]]
[[`int(foo::*)() &&`] [`true`]]
[[`int() const`] [`false`]]
[[`int() volatile`] [`false`]]
[[`int(foo::* volatile)() const`] [`false`]]
[[`int() const`] [`false`]]
[[`int() volatile`] [`false`]]
[[`int() &`] [`false`]]
[[`int(*)()`] [`false`]]
[[`int`] [`false`]]
[[`int foo::*`] [`false`]]
[[`const int foo::*`] [`false`]]
]
[heading Example Program]
[import ../example/is_rvalue_reference_member.cpp]
[is_rvalue_reference_member]
[endsect]
*/
//]
#endif // #ifndef BOOST_CLBL_TRTS_IS_RVALUE_REFERENCE_MEMBER_HPP

View File

@@ -1,98 +0,0 @@
/*
@file is_transaction_safe
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE_HPP
#define BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE_HPP
#include <boost/callable_traits/detail/core.hpp>
namespace boost { namespace callable_traits {
//[ is_transaction_safe_hpp
/*`[section:ref_is_transaction_safe is_transaction_safe]
[heading Header]
``#include <boost/callable_traits/is_transaction_safe.hpp>``
[heading Definition]
*/
// inherits from either std::true_type or std::false_type
template<typename T>
struct is_transaction_safe;
//<-
template<typename T>
struct is_transaction_safe : detail::traits<
detail::shallow_decay<T>>::is_transaction_safe {
using type = typename detail::traits<
detail::shallow_decay<T>>::is_transaction_safe;
};
#ifdef BOOST_CLBL_TRTS_DISABLE_VARIABLE_TEMPLATES
template<typename T>
struct is_transaction_safe_v {
static_assert(std::is_same<T, detail::dummy>::value,
"Variable templates not supported on this compiler.");
};
#else
//->
// only available when variable templates are supported
template<typename T>
//<-
BOOST_CLBL_TRAITS_INLINE_VAR
//->
constexpr bool is_transaction_safe_v = //see below
//<-
detail::traits<detail::shallow_decay<T>>::is_transaction_safe::value;
#endif
}} // namespace boost::callable_traits
//->
/*`
[heading Constraints]
* none
*
[heading Behavior]
* `is_transaction_safe<T>::value` is `true` when either:
* `T` is a function type, function pointer type, function reference type, or member function pointer type where the function has a `transaction_safe` specifier
* `T` is a function object with a non-overloaded `operator()`, where the `operator()` has a `transaction_safe` specifier
* On compilers that support variable templates, `is_transaction_safe_v<T>` is equivalent to `is_transaction_safe<T>::value`.
[heading Input/Output Examples]
[table
[[`T`] [`is_transaction_safe_v<T>`]]
[[`int() const transaction_safe`] [`true`]]
[[`int(*)() transaction_safe`] [`true`]]
[[`int(&)() transaction_safe`] [`true`]]
[[`int(foo::* const)() transaction_safe`] [`true`]]
[[`int() const`] [`false`]]
[[`int() volatile`] [`false`]]
[[`int(foo::*)() const`] [`false`]]
[[`int() const`] [`false`]]
[[`int() volatile`] [`false`]]
[[`int() &`] [`false`]]
[[`int(*)()`] [`false`]]
[[`int`] [`false`]]
[[`int foo::*`] [`false`]]
[[`const int foo::*`] [`false`]]
]
[heading Example Program]
[import ../example/is_transaction_safe.cpp]
[is_transaction_safe]
[endsect]
*/
//]
#endif // #ifndef BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE_HPP

View File

@@ -1,100 +0,0 @@
/*
*
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_IS_VOLATILE_MEMBER_HPP
#define BOOST_CLBL_TRTS_IS_VOLATILE_MEMBER_HPP
#include <boost/callable_traits/detail/core.hpp>
namespace boost { namespace callable_traits {
//[ is_volatile_member_hpp
/*`[section:ref_is_volatile_member is_volatile_member]
[heading Header]
``#include <boost/callable_traits/is_volatile_member.hpp>``
[heading Definition]
*/
// inherits from either std::true_type or std::false_type
template<typename T>
struct is_volatile_member;
//<-
template<typename T>
struct is_volatile_member : detail::traits<
detail::shallow_decay<T>>::is_volatile_member {
using type = typename detail::traits<
detail::shallow_decay<T>>::is_volatile_member;
};
#ifdef BOOST_CLBL_TRTS_DISABLE_VARIABLE_TEMPLATES
template<typename T>
struct is_volatile_member_v {
static_assert(std::is_same<T, detail::dummy>::value,
"Variable templates not supported on this compiler.");
};
#else
//->
// only available when variable templates are supported
template<typename T>
//<-
BOOST_CLBL_TRAITS_INLINE_VAR
//->
constexpr bool is_volatile_member_v = //see below
//<-
detail::traits<detail::shallow_decay<T>>::is_volatile_member::value;
#endif
}} // namespace boost::callable_traits
//->
/*`
[heading Constraints]
* none
[heading Behavior]
* `is_volatile_member<T>::value` is `true` when either:
* `T` is a function type with a `volatile` member qualifier
* `T` is a pointer to a member function with a `volatile` member qualifier
* `T` is a function object with a non-overloaded `operator()`, where the `operator()` has a `volatile` member qualifier
* On compilers that support variable templates, `is_volatile_member_v<T>` is equivalent to `is_volatile_member<T>::value`.
[heading Input/Output Examples]
[table
[[`T`] [`is_volatile_member_v<T>`]]
[[`int() volatile`] [`true`]]
[[`int() const volatile`] [`true`]]
[[`int() volatile &&`] [`true`]]
[[`int(foo::*)() volatile`] [`true`]]
[[`int(foo::* const)() volatile`] [`true`]]
[[`int(foo::*)() const volatile`] [`true`]]
[[`int(foo::*)() const volatile &&`][`true`]]
[[`int()`] [`false`]]
[[`int() const`] [`false`]]
[[`int() &&`] [`false`]]
[[`int(*)()`] [`false`]]
[[`int`] [`false`]]
[[`int foo::*`] [`false`]]
[[`volatile int foo::*`] [`false`]]
]
[heading Example Program]
[import ../example/is_volatile_member.cpp]
[is_volatile_member]
[endsect]
*/
//]
#endif // #ifndef BOOST_CLBL_TRTS_IS_VOLATILE_MEMBER_HPP

View File

@@ -1,81 +0,0 @@
/*
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_QUALIFIED_class_of_HPP
#define BOOST_CLBL_TRTS_QUALIFIED_class_of_HPP
#include <boost/callable_traits/detail/core.hpp>
namespace boost { namespace callable_traits {
//[ qualified_class_of_hpp
/*`
[section:ref_qualified_class_of qualified_class_of]
[heading Header]
``#include <boost/callable_traits/qualified_class_of.hpp>``
[heading Definition]
*/
template<typename T>
using qualified_class_of_t = //see below
//<-
detail::try_but_fail_if_invalid<
typename detail::traits<detail::shallow_decay<T>>::invoke_type,
type_is_not_a_member_pointer>;
namespace detail {
template<typename T, typename = std::false_type>
struct qualified_class_of_impl {};
template<typename T>
struct qualified_class_of_impl <T, typename std::is_same<
qualified_class_of_t<T>, detail::dummy>::type>
{
using type = qualified_class_of_t<T>;
};
}
//->
template<typename T>
struct qualified_class_of : detail::qualified_class_of_impl<T> {};
//<-
}} // namespace boost::callable_traits
//->
/*`
[heading Constraints]
* `T` must be a member pointer
[heading Behavior]
* A substitution failure occurs if the constraints are violated.
* If `T` is a member function pointer, the aliased type is the parent class of the member, qualified according to the member qualifiers on `T`. If `T` does not have a member reference qualifier, then the aliased type will be an lvalue reference.
* If `T` is a member data pointer, the aliased type is equivalent to `ct::class_of<T> const &`.
[heading Input/Output Examples]
[table
[[`T`] [`qualified_class_of_t<T>`]]
[[`void(foo::*)()`] [`foo &`]]
[[`void(foo::* volatile)() const`] [`foo const &`]]
[[`void(foo::*)() &&`] [`foo &&`]]
[[`void(foo::*&)() volatile &&`] [`foo volatile &&`]]
[[`int foo::*`] [`foo const &`]]
[[`const int foo::*`] [`foo const &`]]
]
[heading Example Program]
[import ../example/qualified_class_of.cpp]
[qualified_class_of]
[endsect]
*/
//]
#endif // #ifndef BOOST_CLBL_TRTS_QUALIFIED_class_of_HPP

View File

@@ -1,85 +0,0 @@
/*
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_REMOVE_MEMBER_CONST_HPP
#define BOOST_CLBL_TRTS_REMOVE_MEMBER_CONST_HPP
#include <boost/callable_traits/detail/core.hpp>
namespace boost { namespace callable_traits {
//[ remove_member_const_hpp
/*`
[section:ref_remove_member_const remove_member_const]
[heading Header]
``#include <boost/callable_traits/remove_member_const.hpp>``
[heading Definition]
*/
template<typename T>
using remove_member_const_t = //see below
//<-
detail::try_but_fail_if_invalid<
typename detail::traits<T>::remove_member_const,
member_qualifiers_are_illegal_for_this_type>;
namespace detail {
template<typename T, typename = std::false_type>
struct remove_member_const_impl {};
template<typename T>
struct remove_member_const_impl <T, typename std::is_same<
remove_member_const_t<T>, detail::dummy>::type>
{
using type = remove_member_const_t<T>;
};
}
//->
template<typename T>
struct remove_member_const : detail::remove_member_const_impl<T> {};
//<-
}} // namespace boost::callable_traits
//->
/*`
[heading Constraints]
* `T` must be a function type or a member function pointer type
* If `T` is a pointer, it may not be cv/ref qualified
[heading Behavior]
* A substitution failure occurs if the constraints are violated.
* Removes the member `const` qualifier from `T`, if present.
[heading Input/Output Examples]
[table
[[`T`] [`remove_member_const_t<T>`]]
[[`int() const`] [`int()`]]
[[`int(foo::*)() const`] [`int(foo::*)()`]]
[[`int(foo::*)() const &`] [`int(foo::*)() &`]]
[[`int(foo::*)() const &&`] [`int(foo::*)() &&`]]
[[`int(foo::*)() const`] [`int(foo::*)()`]]
[[`int(foo::*)() const volatile`] [`int(foo::*)() volatile`]]
[[`int`] [(substitution failure)]]
[[`int (&)()`] [(substitution failure)]]
[[`int (*)()`] [(substitution failure)]]
[[`int foo::*`] [(substitution failure)]]
[[`int (foo::* const)()`] [(substitution failure)]]
]
[heading Example Program]
[import ../example/remove_member_const.cpp]
[remove_member_const]
[endsect]
*/
//]
#endif // #ifndef BOOST_CLBL_TRTS_REMOVE_MEMBER_CONST_HPP

View File

@@ -1,87 +0,0 @@
/*
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_REMOVE_MEMBER_CV_HPP
#define BOOST_CLBL_TRTS_REMOVE_MEMBER_CV_HPP
#include <boost/callable_traits/detail/core.hpp>
namespace boost { namespace callable_traits {
//[ remove_member_cv_hpp
/*`
[section:ref_remove_member_cv remove_member_cv]
[heading Header]
``#include <boost/callable_traits/remove_member_cv.hpp>``
[heading Definition]
*/
template<typename T>
using remove_member_cv_t = //see below
//<-
detail::try_but_fail_if_invalid<
typename detail::traits<T>::remove_member_cv,
member_qualifiers_are_illegal_for_this_type>;
namespace detail {
template<typename T, typename = std::false_type>
struct remove_member_cv_impl {};
template<typename T>
struct remove_member_cv_impl <T, typename std::is_same<
remove_member_cv_t<T>, detail::dummy>::type>
{
using type = remove_member_cv_t<T>;
};
}
//->
template<typename T>
struct remove_member_cv : detail::remove_member_cv_impl<T> {};
//<-
}} // namespace boost::callable_traits
//->
/*`
[heading Constraints]
* `T` must be a function type or a member function pointer type
* If `T` is a pointer, it may not be cv/ref qualified
[heading Behavior]
* A substitution failure occurs if the constraints are violated.
* Removes member `const` and/or `volatile` qualifiers from `T`, if present.
[heading Input/Output Examples]
[table
[[`T`] [`remove_member_cv_t<T>`]]
[[`int() const volatile`] [`int()`]]
[[`int(foo::*)() const volatile`] [`int(foo::*)()`]]
[[`int(foo::*)() volatile`] [`int(foo::*)()`]]
[[`int(foo::*)() const`] [`int(foo::*)()`]]
[[`int(foo::*)() const &`] [`int(foo::*)() &`]]
[[`int(foo::*)() const &&`] [`int(foo::*)() &&`]]
[[`int(foo::*)() const`] [`int(foo::*)()`]]
[[`int`] [(substitution failure)]]
[[`int (&)()`] [(substitution failure)]]
[[`int (*)()`] [(substitution failure)]]
[[`int foo::*`] [(substitution failure)]]
[[`int (foo::* const)()`] [(substitution failure)]]
]
[heading Example Program]
[import ../example/remove_member_cv.cpp]
[remove_member_cv]
[endsect]
*/
//]
#endif // #ifndef BOOST_CLBL_TRTS_REMOVE_MEMBER_CV_HPP

View File

@@ -1,85 +0,0 @@
/*
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_REMOVE_MEMBER_REFERENCE_HPP
#define BOOST_CLBL_TRTS_REMOVE_MEMBER_REFERENCE_HPP
#include <boost/callable_traits/detail/core.hpp>
namespace boost { namespace callable_traits {
//[ remove_member_reference_hpp
/*`
[section:ref_remove_member_reference remove_member_reference]
[heading Header]
``#include <boost/callable_traits/remove_member_reference.hpp>``
[heading Definition]
*/
template<typename T>
using remove_member_reference_t = //see below
//<-
detail::try_but_fail_if_invalid<
typename detail::traits<T>::remove_member_reference,
member_qualifiers_are_illegal_for_this_type>;
namespace detail {
template<typename T, typename = std::false_type>
struct remove_member_reference_impl {};
template<typename T>
struct remove_member_reference_impl <T, typename std::is_same<
remove_member_reference_t<T>, detail::dummy>::type>
{
using type = remove_member_reference_t<T>;
};
}
//->
template<typename T>
struct remove_member_reference
: detail::remove_member_reference_impl<T> {};
//<-
}} // namespace boost::callable_traits
//->
/*`
[heading Constraints]
* `T` must be a function type or a member function pointer type
* If `T` is a pointer, it may not be cv/ref qualified
[heading Behavior]
* A substitution failure occuers if the constraints are violated.
* Removes member `&` or `&&` qualifiers from `T`, if present.
[heading Input/Output Examples]
[table
[[`T`] [`remove_member_const_t<T>`]]
[[`int() &`] [`int()`]]
[[`int(foo::*)() &`] [`int(foo::*)()`]]
[[`int(foo::*)() const &`] [`int(foo::*)() const`]]
[[`int(foo::*)() const &&`] [`int(foo::*)() const`]]
[[`int(foo::*)()`] [`int(foo::*)()`]]
[[`int`] [(substitution failure)]]
[[`int (&)()`] [(substitution failure)]]
[[`int (*)()`] [(substitution failure)]]
[[`int foo::*`] [(substitution failure)]]
[[`int (foo::* const)()`] [(substitution failure)]]
]
[heading Example Program]
[import ../example/remove_member_reference.cpp]
[remove_member_reference]
[endsect]
*/
//]
#endif // #ifndef BOOST_CLBL_TRTS_REMOVE_MEMBER_REFERENCE_HPP

View File

@@ -1,85 +0,0 @@
/*
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_REMOVE_MEMBER_VOLATILE_HPP
#define BOOST_CLBL_TRTS_REMOVE_MEMBER_VOLATILE_HPP
#include <boost/callable_traits/detail/core.hpp>
namespace boost { namespace callable_traits {
//[ remove_member_volatile_hpp
/*`
[section:ref_remove_member_volatile remove_member_volatile]
[heading Header]
``#include <boost/callable_traits/remove_member_volatile.hpp>``
[heading Definition]
*/
template<typename T>
using remove_member_volatile_t = //see below
//<-
detail::try_but_fail_if_invalid<
typename detail::traits<T>::remove_member_volatile,
member_qualifiers_are_illegal_for_this_type>;
namespace detail {
template<typename T, typename = std::false_type>
struct remove_member_volatile_impl {};
template<typename T>
struct remove_member_volatile_impl <T, typename std::is_same<
remove_member_volatile_t<T>, detail::dummy>::type>
{
using type = remove_member_volatile_t<T>;
};
}
//->
template<typename T>
struct remove_member_volatile : detail::remove_member_volatile_impl<T> {};
//<-
}} // namespace boost::callable_traits
//->
/*`
[heading Constraints]
* `T` must be a function type or a member function pointer type
* If `T` is a pointer, it may not be cv/ref qualified
[heading Behavior]
* A substitution failure occurs if the constraints are violated.
* Removes the member `volatile` qualifier from `T`, if present.
[heading Input/Output Examples]
[table
[[`T`] [`remove_member_volatile_t<T>`]]
[[`int() volatile`] [`int()`]]
[[`int(foo::*)() volatile`] [`int(foo::*)()`]]
[[`int(foo::*)() volatile &`] [`int(foo::*)() &`]]
[[`int(foo::*)() volatile &&`] [`int(foo::*)() &&`]]
[[`int(foo::*)() volatile`] [`int(foo::*)()`]]
[[`int(foo::*)() const volatile`] [`int(foo::*)() const`]]
[[`int`] [(substitution failure)]]
[[`int (&)()`] [(substitution failure)]]
[[`int (*)()`] [(substitution failure)]]
[[`int foo::*`] [(substitution failure)]]
[[`int (foo::* const)()`] [(substitution failure)]]
]
[heading Example Program]
[import ../example/remove_member_volatile.cpp]
[remove_member_volatile]
[endsect]
*/
//]
#endif // #ifndef BOOST_CLBL_TRTS_REMOVE_MEMBER_VOLATILE_HPP

View File

@@ -1,93 +0,0 @@
/*
@file remove_noexcept
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_REMOVE_NOEXCEPT_HPP
#define BOOST_CLBL_TRTS_REMOVE_NOEXCEPT_HPP
#include <boost/callable_traits/detail/core.hpp>
namespace boost { namespace callable_traits {
BOOST_CLBL_TRTS_DEFINE_SFINAE_ERROR_ORIGIN(remove_noexcept)
BOOST_CLBL_TRTS_SFINAE_MSG(remove_noexcept, cannot_remove_noexcept_from_this_type)
//[ remove_noexcept_hpp
/*`
[section:ref_remove_noexcept remove_noexcept]
[heading Header]
``#include <boost/callable_traits/remove_noexcept.hpp>``
[heading Definition]
*/
template<typename T>
using remove_noexcept_t = //see below
//<-
detail::try_but_fail_if_invalid<
typename detail::traits<T>::remove_noexcept,
cannot_remove_noexcept_from_this_type>;
namespace detail {
template<typename T, typename = std::false_type>
struct remove_noexcept_impl {};
template<typename T>
struct remove_noexcept_impl <T, typename std::is_same<
remove_noexcept_t<T>, detail::dummy>::type>
{
using type = remove_noexcept_t<T>;
};
}
//->
template<typename T>
struct remove_noexcept : detail::remove_noexcept_impl<T> {};
//<-
}} // namespace boost::callable_traits
//->
/*`
[heading Constraints]
* `T` must be one of the following:
* function type
* function pointer type
* function reference type
* member function pointer type
* If `T` is a pointer, it may not be cv/ref qualified
[heading Behavior]
* A substitution failure occurs if the constraints are violated.
* Removes the `noexcept` specifier from `T`, if present.
[heading Input/Output Examples]
[table
[[`T`] [`remove_noexcept_t<T>`]]
[[`int() const noexcept`] [`int() const`]]
[[`int(*)() noexcept`] [`int(*)()`]]
[[`int(&)() noexcept`] [`int(&)()`]]
[[`int(foo::*)() noexcept`] [`int(foo::*)()`]]
[[`int() const`] [`int() const`]]
[[`int(*)()`] [`int(*)()`]]
[[`int(&)()`] [`int(&)()`]]
[[`int`] [(substitution failure)]]
[[`int foo::*`] [(substitution failure)]]
[[`int (foo::* const)()`] [(substitution failure)]]
]
[heading Example Program]
[import ../example/remove_noexcept.cpp]
[remove_noexcept]
[endsect]
*/
//]
#endif // #ifndef BOOST_CLBL_TRTS_REMOVE_NOEXCEPT_HPP

View File

@@ -1,93 +0,0 @@
/*
@file remove_transaction_safe
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_REMOVE_TRANSACTION_SAFE_HPP
#define BOOST_CLBL_TRTS_REMOVE_TRANSACTION_SAFE_HPP
#include <boost/callable_traits/detail/core.hpp>
namespace boost { namespace callable_traits {
BOOST_CLBL_TRTS_DEFINE_SFINAE_ERROR_ORIGIN(remove_transaction_safe)
BOOST_CLBL_TRTS_SFINAE_MSG(remove_transaction_safe, cannot_remove_transaction_safe_from_this_type)
//[ remove_transaction_safe_hpp
/*`
[section:ref_remove_transaction_safe remove_transaction_safe]
[heading Header]
``#include <boost/callable_traits/remove_transaction_safe.hpp>``
[heading Definition]
*/
template<typename T>
using remove_transaction_safe_t = //see below
//<-
detail::try_but_fail_if_invalid<
typename detail::traits<T>::remove_transaction_safe,
cannot_remove_transaction_safe_from_this_type>;
namespace detail {
template<typename T, typename = std::false_type>
struct remove_transaction_safe_impl {};
template<typename T>
struct remove_transaction_safe_impl <T, typename std::is_same<
remove_transaction_safe_t<T>, detail::dummy>::type>
{
using type = remove_transaction_safe_t<T>;
};
}
//->
template<typename T>
struct remove_transaction_safe : detail::remove_transaction_safe_impl<T> {};
//<-
}} // namespace boost::callable_traits
//->
/*`
[heading Constraints]
* `T` must be one of the following:
* function type
* function pointer type
* function reference type
* member function pointer type
* If `T` is a pointer, it may not be cv/ref qualified
[heading Behavior]
* A substitution failure occurs if the constraints are violated.
* Removes the member `transaction_safe` specifier from `T`, if present.
[heading Input/Output Examples]
[table
[[`T`] [`remove_transaction_safe_t<T>`]]
[[`int() const transaction_safe`] [`int() const`]]
[[`int(*)() transaction_safe`] [`int(*)()`]]
[[`int(&)() transaction_safe`] [`int(&)()`]]
[[`int(foo::*)() transaction_safe`] [`int(foo::*)()`]]
[[`int() const`] [`int() const`]]
[[`int(*)()`] [`int(*)()`]]
[[`int(&)()`] [`int(&)()`]]
[[`int`] [(substitution failure)]]
[[`int foo::*`] [(substitution failure)]]
[[`int (foo::* const)()`] [(substitution failure)]]
]
[heading Example Program]
[import ../example/remove_transaction_safe.cpp]
[remove_transaction_safe]
[endsect]
*/
//]
#endif // #ifndef BOOST_CLBL_TRTS_REMOVE_TRANSACTION_SAFE_HPP

View File

@@ -1,91 +0,0 @@
/*
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_REMOVE_VARARGS_HPP
#define BOOST_CLBL_TRTS_REMOVE_VARARGS_HPP
#include <boost/callable_traits/detail/core.hpp>
namespace boost { namespace callable_traits {
//[ remove_varargs_hpp
/*`
[section:ref_remove_varargs remove_varargs]
[heading Header]
``#include <boost/callable_traits/remove_varargs.hpp>``
[heading Definition]
*/
template<typename T>
using remove_varargs_t = //see below
//<-
detail::try_but_fail_if_invalid<
typename detail::traits<T>::remove_varargs,
varargs_are_illegal_for_this_type>;
namespace detail {
template<typename T, typename = std::false_type>
struct remove_varargs_impl {};
template<typename T>
struct remove_varargs_impl <T, typename std::is_same<
remove_varargs_t<T>, detail::dummy>::type>
{
using type = remove_varargs_t<T>;
};
}
//->
template<typename T>
struct remove_varargs : detail::remove_varargs_impl<T> {};
//<-
}} // namespace boost::callable_traits
//->
/*`
[heading Constraints]
* `T` must be one of the following:
* function type
* function pointer type
* function reference type
* member function pointer type
* If `T` is a pointer, it may not be cv/ref qualified
[heading Behavior]
* A substitution failure occurs if the constraints are violated.
* Removes C-style variadics (`...`) from the signature of `T`, if present.
[heading Input/Output Examples]
[table
[[`T`] [`remove_varargs_t<T>`]]
[[`int(...)`] [`int()`]]
[[`int(int, ...)`] [`int(int)`]]
[[`int (&)(...)`] [`int(&)()`]]
[[`int (*)()`] [`int(*)()`]]
[[`int(foo::*)(...)`] [`int(foo::*)()`]]
[[`int(foo::*)(...) &`] [`int(foo::*)() &`]]
[[`int(foo::*)(...) &&`] [`int(foo::*)() &&`]]
[[`int(foo::*)(...) const`] [`int(foo::*)() const`]]
[[`int(foo::*)(...) transaction_safe`] [`int(foo::*)() transaction_safe`]]
[[`int`] [(substitution failure)]]
[[`int foo::*`] [(substitution failure)]]
[[`int (* const)()`] [(substitution failure)]]
]
[heading Example Program]
[import ../example/remove_varargs.cpp]
[remove_varargs]
[endsect]
*/
//]
#endif // #ifndef BOOST_CLBL_TRTS_REMOVE_VARARGS_HPP

View File

@@ -1,90 +0,0 @@
/*
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_RESULT_OF_HPP
#define BOOST_CLBL_TRTS_RESULT_OF_HPP
#include <boost/callable_traits/detail/core.hpp>
namespace boost { namespace callable_traits {
BOOST_CLBL_TRTS_DEFINE_SFINAE_ERROR_ORIGIN(return_type)
BOOST_CLBL_TRTS_SFINAE_MSG(return_type, unable_to_determine_return_type)
//[ return_type_hpp
/*`
[section:ref_return_type return_type]
[heading Header]
``#include <boost/callable_traits/return_type.hpp>``
[heading Definition]
*/
template<typename T>
using return_type_t = //see below
//<-
detail::try_but_fail_if_invalid<
typename detail::traits<detail::shallow_decay<T>>::return_type,
unable_to_determine_return_type>;
namespace detail {
template<typename T, typename = std::false_type>
struct return_type_impl {};
template<typename T>
struct return_type_impl <T, typename std::is_same<
return_type_t<T>, detail::dummy>::type>
{
using type = return_type_t<T>;
};
}
//->
template<typename T>
struct return_type : detail::return_type_impl<T> {};
//<-
}} // namespace boost::callable_traits
//->
/*`
[heading Constraints]
* `T` must be one of the following:
* function
* function pointer
* function reference
* member function pointer
* member data pointer
* user-defined type with a non-overloaded `operator()`
* type of a non-generic lambda
[heading Behavior]
* When the constraints are violated, a substitution failure occurs.
* The aliased type is the return type of `T`.
[heading Input/Output Examples]
[table
[[`T`] [`return_type_t<T, std::tuple>`]]
[[`void()`] [`void`]]
[[`float(*)()`] [`float`]]
[[`const char*(&)()`] [`const char *`]]
[[`int(foo::*)() const`] [`int`]]
[[`int`] [(substitution failure)]]
[[`int (*const)()`] [(substitution failure)]]
]
[heading Example Program]
[import ../example/return_type.cpp]
[return_type]
[endsect]
*/
//]
#endif // #ifndef BOOST_CLBL_TRTS_RESULT_OF_HPP

View File

@@ -16,20 +16,17 @@
#pragma once
#include "stratosphere/ipc_templating.hpp"
#include "stratosphere/version_check.hpp"
#include "stratosphere/scope_guard.hpp"
#include "stratosphere/iwaitable.hpp"
#include "stratosphere/iserviceobject.hpp"
#include "stratosphere/iserver.hpp"
#include "stratosphere/ipcsession.hpp"
#include "stratosphere/servicesession.hpp"
#include "stratosphere/serviceserver.hpp"
#include "stratosphere/managedportserver.hpp"
#include "stratosphere/existingportserver.hpp"
#include "stratosphere/ievent.hpp"
#include "stratosphere/systemevent.hpp"
#include "stratosphere/hossynch.hpp"
#include "stratosphere/iwaitable.hpp"
#include "stratosphere/event.hpp"
#include "stratosphere/waitablemanager.hpp"
#include "stratosphere/multithreadedwaitablemanager.hpp"
#include "stratosphere/waitable_manager.hpp"
#include "stratosphere/ipc.hpp"
#include "stratosphere/mitm.hpp"
#include "stratosphere/services.hpp"

View File

@@ -1,79 +0,0 @@
/*
* Copyright (c) 2018 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 <switch.h>
#include <algorithm>
#include <memory>
#include <type_traits>
#include "iserviceobject.hpp"
#define DOMAIN_ID_MAX 0x1000
class IServiceObject;
class DomainOwner {
private:
std::array<std::shared_ptr<IServiceObject>, DOMAIN_ID_MAX> domain_objects;
public:
/* Shared ptrs should auto delete here. */
virtual ~DomainOwner() = default;
std::shared_ptr<IServiceObject> get_domain_object(unsigned int i) {
if (i < DOMAIN_ID_MAX) {
return domain_objects[i];
}
return nullptr;
}
Result reserve_object(std::shared_ptr<IServiceObject> object, unsigned int *out_i) {
auto object_it = std::find(domain_objects.begin() + 4, domain_objects.end(), nullptr);
if (object_it == domain_objects.end()) {
return 0x1900B;
}
*out_i = std::distance(domain_objects.begin(), object_it);
*object_it = object;
object->set_owner(this);
return 0;
}
Result set_object(std::shared_ptr<IServiceObject> object, unsigned int i) {
if (domain_objects[i] == nullptr) {
domain_objects[i] = object;
object->set_owner(this);
return 0;
}
return 0x1900B;
}
unsigned int get_object_id(std::shared_ptr<IServiceObject> object) {
auto object_it = std::find(domain_objects.begin(), domain_objects.end(), object);
return std::distance(domain_objects.begin(), object_it);
}
void delete_object(unsigned int i) {
domain_objects[i].reset();
}
void delete_object(std::shared_ptr<IServiceObject> object) {
auto object_it = std::find(domain_objects.begin(), domain_objects.end(), object);
if (object_it != domain_objects.end()) {
object_it->reset();
}
}
};

View File

@@ -0,0 +1,127 @@
/*
* Copyright (c) 2018 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 <switch.h>
#include <algorithm>
#include <vector>
#include "iwaitable.hpp"
class IEvent : public IWaitable {
public:
/* Information members. */
Handle r_h;
Handle w_h;
bool autoclear;
public:
IEvent(bool a = false) : r_h(INVALID_HANDLE), w_h(INVALID_HANDLE), autoclear(a) { }
IEvent(Handle r, bool a = false) : r_h(r), w_h(INVALID_HANDLE), autoclear(a) { }
IEvent(Handle r, Handle w, bool a = false) : r_h(r), w_h(w), autoclear(a) { }
~IEvent() {
if (r_h != INVALID_HANDLE) {
svcCloseHandle(r_h);
}
if (w_h != INVALID_HANDLE) {
svcCloseHandle(w_h);
}
}
/* Make it non-copyable */
IEvent() = delete;
IEvent(const IEvent &) = delete;
IEvent& operator=(const IEvent&) = delete;
bool IsAutoClear() {
return this->autoclear;
}
void Clear() {
std::scoped_lock<HosMutex> lock(this->sig_lock);
this->is_signaled = false;
if (this->r_h != INVALID_HANDLE) {
svcResetSignal(this->r_h);
}
}
void Signal() {
std::scoped_lock<HosMutex> lock(this->sig_lock);
if (this->w_h == INVALID_HANDLE && this->r_h != INVALID_HANDLE) {
/* We can't signal an event if we only have a read handle. */
std::abort();
}
if (this->w_h == INVALID_HANDLE && this->is_signaled) {
return;
}
this->is_signaled = true;
if (this->w_h != INVALID_HANDLE) {
svcSignalEvent(this->w_h);
} else {
this->NotifyManagerSignaled();
}
}
virtual Result HandleSignaled(u64 timeout) = 0;
/* IWaitable */
virtual Handle GetHandle() override {
return this->r_h;
}
};
template<class F>
class HosEvent : public IEvent {
private:
F callback;
public:
HosEvent(F f, bool a = false) : IEvent(a), callback(std::move(f)) { }
HosEvent(Handle r, F f, bool a = false) : IEvent(r, a), callback(std::move(f)) { }
HosEvent(Handle r, Handle w, F f, bool a = false) : IEvent(r, w, a), callback(std::move(f)) { }
virtual Result HandleSignaled(u64 timeout) override {
if (this->IsAutoClear()) {
this->Clear();
}
return this->callback(timeout);
}
};
template <class F>
static IEvent *CreateHosEvent(F f, bool autoclear = false) {
return new HosEvent<F>(INVALID_HANDLE, INVALID_HANDLE, std::move(f), autoclear);
}
template <class F>
static IEvent *CreateSystemEvent(F f, bool autoclear = false) {
Handle w_h, r_h;
if (R_FAILED(svcCreateEvent(&w_h, &r_h))) {
std::abort();
}
return new HosEvent<F>(r_h, w_h, std::move(f), autoclear);
}
template <bool a = false>
static IEvent *CreateWriteOnlySystemEvent() {
return CreateSystemEvent([](u64 timeout) { std::abort(); return 0; }, a);
}

View File

@@ -0,0 +1,49 @@
/*
* Copyright (c) 2018 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
enum FirmwareVersion : u32 {
FirmwareVersion_Min = 0,
FirmwareVersion_100 = FirmwareVersion_Min,
FirmwareVersion_200 = 1,
FirmwareVersion_300 = 2,
FirmwareVersion_400 = 3,
FirmwareVersion_500 = 4,
FirmwareVersion_600 = 5,
FirmwareVersion_Current = FirmwareVersion_600,
FirmwareVersion_Max = 32,
};
static inline FirmwareVersion GetRuntimeFirmwareVersion() {
FirmwareVersion fw = FirmwareVersion_Min;
if (kernelAbove200()) {
fw = FirmwareVersion_200;
}
if (kernelAbove300()) {
fw = FirmwareVersion_300;
}
if (kernelAbove400()) {
fw = FirmwareVersion_400;
}
if (kernelAbove500()) {
fw = FirmwareVersion_500;
}
if (kernelAbove600()) {
fw = FirmwareVersion_600;
}
return fw;
}

View File

@@ -16,6 +16,7 @@
#pragma once
#include <switch.h>
#include <mutex>
class HosMutex {
private:
@@ -40,6 +41,18 @@ class HosMutex {
return mutexTryLock(GetMutex());
}
void Lock() {
lock();
}
void Unlock() {
unlock();
}
bool TryLock() {
return try_lock();
}
friend class HosCondVar;
};
@@ -65,6 +78,18 @@ class HosRecursiveMutex {
bool try_lock() {
return rmutexTryLock(GetMutex());
}
void Lock() {
lock();
}
void Unlock() {
unlock();
}
bool TryLock() {
return try_lock();
}
};
class HosCondVar {

Some files were not shown because too many files have changed in this diff Show More