Compare commits
49 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bb29a2458f | ||
|
|
ce1a6a68bf | ||
|
|
cf510ad9bf | ||
|
|
9898a01d3b | ||
|
|
54a22797a7 | ||
|
|
5ef01edab5 | ||
|
|
3b8bb325e8 | ||
|
|
6538554485 | ||
|
|
9b1a2451b0 | ||
|
|
e65bee0d6a | ||
|
|
8426a4dc77 | ||
|
|
147f3c690a | ||
|
|
bac81f4ccc | ||
|
|
2894989eb7 | ||
|
|
952ee4227d | ||
|
|
9142e90a04 | ||
|
|
3ed239296a | ||
|
|
78a47dba6d | ||
|
|
5d0aabaa44 | ||
|
|
e786bc7e9a | ||
|
|
158f7224a7 | ||
|
|
865ca76772 | ||
|
|
b8f93562c0 | ||
|
|
ef5c7d6bab | ||
|
|
be044e691c | ||
|
|
536b89efae | ||
|
|
44175058f6 | ||
|
|
7309c7f358 | ||
|
|
6336089b63 | ||
|
|
6ef34d80a0 | ||
|
|
2f7224edce | ||
|
|
c49cfbd6af | ||
|
|
8b71378920 | ||
|
|
bbffbd654f | ||
|
|
4cdd9aa8f1 | ||
|
|
23a85a7c24 | ||
|
|
3dc679215b | ||
|
|
aef7d36300 | ||
|
|
887b4e0275 | ||
|
|
9a8c70ed68 | ||
|
|
058f735031 | ||
|
|
5c147e5188 | ||
|
|
18f51e9b2e | ||
|
|
376feb63bd | ||
|
|
a502d31cd1 | ||
|
|
afbf57c222 | ||
|
|
b62329bd5b | ||
|
|
de688ee17a | ||
|
|
0938057d67 |
25
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
25
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
---
|
||||
name: Bug Report
|
||||
about: Something doesn't work correctly in Atmosphère.
|
||||
|
||||
---
|
||||
|
||||
## Bug Report
|
||||
|
||||
### What's the issue you encountered?
|
||||
|
||||
### How can the issue be reproduced?
|
||||
|
||||
### Crash report?
|
||||
|
||||
(If a crash report was created under /atmosphere/crash_reports/, please upload it to
|
||||
[gist](https://gist.github.com/) and paste the link here.)
|
||||
|
||||
### Environment?
|
||||
|
||||
- What bootloader (fusee, hekate, etc) was Atmosphère launched by:
|
||||
- Official release or unofficial build:
|
||||
- Do you have additional kips you're loading:
|
||||
- Additional info about your environment:
|
||||
|
||||
### Additional context?
|
||||
12
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
12
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
---
|
||||
name: Feature Request
|
||||
about: You want to suggest a new feature for Atmosphère.
|
||||
|
||||
---
|
||||
|
||||
## Feature Request
|
||||
|
||||
### What feature are you suggesting?
|
||||
|
||||
### Why would this feature be useful?
|
||||
|
||||
12
.github/ISSUE_TEMPLATE/question.md
vendored
Normal file
12
.github/ISSUE_TEMPLATE/question.md
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
---
|
||||
name: Question
|
||||
about: Please ask questions in the ReSwitched discord, instead of making issues.
|
||||
|
||||
---
|
||||
|
||||
We would like to use GitHub to keep track of problems/feature requests.
|
||||
|
||||
If you have a question, please join the ReSwitched discord for help.
|
||||
|
||||
- Discord link: https://discordapp.com/invite/DThbZ7z
|
||||
|
||||
6
.gitmodules
vendored
Normal file
6
.gitmodules
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
[submodule "common/include/boost"]
|
||||
path = common/include/boost
|
||||
url = https://github.com/Atmosphere-NX/ext-boost.git
|
||||
[submodule "stratosphere/libstratosphere"]
|
||||
path = stratosphere/libstratosphere
|
||||
url = https://github.com/Atmosphere-NX/libstratosphere.git
|
||||
26
Makefile
26
Makefile
@@ -1,21 +1,30 @@
|
||||
TOPTARGETS := all clean dist
|
||||
AMSREV := $(shell git rev-parse --short HEAD)
|
||||
AMSBRANCH := $(shell git symbolic-ref --short HEAD)
|
||||
AMSREV := $(AMSBRANCH)-$(shell git rev-parse --short HEAD)
|
||||
|
||||
ifneq (, $(strip $(shell git status --porcelain 2>/dev/null)))
|
||||
AMSREV := $(AMSREV)-dirty
|
||||
endif
|
||||
|
||||
all: fusee creport
|
||||
fusee:
|
||||
$(MAKE) -C $@ all
|
||||
all: fusee stratosphere exosphere thermosphere
|
||||
|
||||
creport:
|
||||
$(MAKE) -C stratosphere/creport all
|
||||
thermosphere:
|
||||
$(MAKE) -C thermosphere all
|
||||
|
||||
exosphere: thermosphere
|
||||
$(MAKE) -C exosphere all
|
||||
|
||||
stratosphere: exosphere
|
||||
$(MAKE) -C stratosphere all
|
||||
|
||||
fusee: exosphere stratosphere
|
||||
$(MAKE) -C $@ all
|
||||
|
||||
clean:
|
||||
$(MAKE) -C fusee clean
|
||||
rm -rf out
|
||||
|
||||
dist: fusee creport
|
||||
dist: all
|
||||
$(eval MAJORVER = $(shell grep '\ATMOSPHERE_RELEASE_VERSION_MAJOR\b' common/include/atmosphere/version.h \
|
||||
| tr -s [:blank:] \
|
||||
| cut -d' ' -f3))
|
||||
@@ -31,10 +40,13 @@ dist: fusee creport
|
||||
mkdir atmosphere-$(AMSVER)
|
||||
mkdir atmosphere-$(AMSVER)/atmosphere
|
||||
mkdir -p atmosphere-$(AMSVER)/atmosphere/titles/0100000000000036
|
||||
mkdir -p atmosphere-$(AMSVER)/atmosphere/titles/0100000000000032
|
||||
cp fusee/fusee-secondary/fusee-secondary.bin atmosphere-$(AMSVER)/fusee-secondary.bin
|
||||
cp common/defaults/BCT.ini atmosphere-$(AMSVER)/BCT.ini
|
||||
cp common/defaults/loader.ini atmosphere-$(AMSVER)/atmosphere/loader.ini
|
||||
cp stratosphere/creport/creport.nsp atmosphere-$(AMSVER)/atmosphere/titles/0100000000000036/exefs.nsp
|
||||
cp stratosphere/set_mitm/set_mitm.nsp atmosphere-$(AMSVER)/atmosphere/titles/0100000000000032/exefs.nsp
|
||||
touch atmosphere-$(AMSVER)/atmosphere/titles/0100000000000032/boot2.flag
|
||||
cd atmosphere-$(AMSVER); zip -r ../atmosphere-$(AMSVER).zip ./*; cd ../;
|
||||
rm -r atmosphere-$(AMSVER)
|
||||
mkdir out
|
||||
|
||||
@@ -14,18 +14,17 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <switch.h>
|
||||
#include <atomic>
|
||||
#include <vector>
|
||||
#ifndef ATMOSPHERE_H
|
||||
#define ATMOSPHERE_H
|
||||
|
||||
class WaitableManagerBase {
|
||||
std::atomic<u64> cur_priority = 0;
|
||||
public:
|
||||
WaitableManagerBase() = default;
|
||||
virtual ~WaitableManagerBase() = default;
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
u64 get_priority() {
|
||||
return std::atomic_fetch_add(&cur_priority, (u64)1);
|
||||
}
|
||||
};
|
||||
#include "atmosphere/version.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -19,6 +19,6 @@
|
||||
|
||||
#define ATMOSPHERE_RELEASE_VERSION_MAJOR 0
|
||||
#define ATMOSPHERE_RELEASE_VERSION_MINOR 7
|
||||
#define ATMOSPHERE_RELEASE_VERSION_MICRO 3
|
||||
#define ATMOSPHERE_RELEASE_VERSION_MICRO 4
|
||||
|
||||
#endif
|
||||
1
common/include/boost
Submodule
1
common/include/boost
Submodule
Submodule common/include/boost added at fc6429e463
@@ -1,14 +1,21 @@
|
||||
# Changelog
|
||||
## 0.7.3
|
||||
+ Loader and fs.mitm now try to reload loader.ini before reading it. This allows for changing the override button combination/HBL title id at runtime.
|
||||
+ Added a MitM between set:sys and qlaunch, used to override the system version string displayed in system settings.
|
||||
+ The displayed system version will now display `<Actual version> (AMS <x>.<y>.<z>)`.
|
||||
+ General system stability improvements to enhance the user's experience.
|
||||
## 0.7.2
|
||||
+ Fixed a bug in fs.mitm's LayeredFS read implementation that caused some games to crash when trying to read files.
|
||||
+ Fixed a bug affecting 1.0.0 that caused games to crash with fatal error 2001-0106 on boot.
|
||||
+ Improved filenames output by the make dist target.
|
||||
+ General system stability improvements to enhance the user's experience.
|
||||
|
||||
## 0.7.1
|
||||
+ Fixed a bug preventing consoles on 4.0.0-4.1.0 from going to sleep and waking back up.
|
||||
+ Fixed a bug preventing consoles on < 4.0.0 from booting without specific KIPs on the SD card.
|
||||
+ An API was added to Atmosphère's Service Manager for deferring acquisition of all handles for specific services until after early initialization is completed.
|
||||
+ General system stability improvements to enhance the user's experience.
|
||||
|
||||
## 0.7.0
|
||||
+ First official release of Atmosphère.
|
||||
+ Supports the following featureset:
|
||||
|
||||
@@ -522,6 +522,10 @@ void package2_patch_kernel(void *_kernel, size_t size, bool is_sd_kernel) {
|
||||
fatal_error("kernel_patcher: unable to identify kernel!\n");
|
||||
}
|
||||
|
||||
if (kernel_info == NULL && is_sd_kernel) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Apply hooks. */
|
||||
uint8_t *kernel = (uint8_t *)_kernel;
|
||||
size_t free_space_offset = kernel_info->free_code_space_offset;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
KIPS := loader pm sm boot fs_mitm creport
|
||||
KIPS := loader pm sm boot fs_mitm set_mitm creport
|
||||
|
||||
#TODO: boot2 ?
|
||||
|
||||
|
||||
@@ -1,119 +1,170 @@
|
||||
{
|
||||
"name" : "boot",
|
||||
"title_id" : "0x0100000000000005",
|
||||
"main_thread_stack_size" : "0x1000",
|
||||
"main_thread_priority" : 27,
|
||||
"default_cpu_id" : 3,
|
||||
"process_category" : 1,
|
||||
"kernel_capabilities" : {
|
||||
"handle_table_size" : 128,
|
||||
"syscalls" : {
|
||||
"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",
|
||||
"svcCreateInterruptEvent" : "0x53",
|
||||
"svcQueryIoMapping" : "0x55",
|
||||
"svcCreateDeviceAddressSpace" : "0x56",
|
||||
"svcAttachDeviceAddressSpace" : "0x57",
|
||||
"svcDetachDeviceAddressSpace" : "0x58",
|
||||
"svcMapDeviceAddressSpaceAligned" : "0x5A",
|
||||
"svcUnmapDeviceAddressSpace" : "0x5C",
|
||||
"svcFlushProcessDataCache" : "0x5F"
|
||||
"name": "boot",
|
||||
"title_id": "0x0100000000000005",
|
||||
"main_thread_stack_size": "0x1000",
|
||||
"main_thread_priority": 27,
|
||||
"default_cpu_id": 3,
|
||||
"process_category": 1,
|
||||
"kernel_capabilities": [
|
||||
{
|
||||
"type": "handle_table_size",
|
||||
"value": 128
|
||||
},
|
||||
"map" : {
|
||||
"address" : "0x50003000",
|
||||
"size" : "0x1000",
|
||||
"is_ro" : false,
|
||||
"is_io" : true
|
||||
{
|
||||
"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",
|
||||
"svcCreateInterruptEvent": "0x53",
|
||||
"svcQueryIoMapping": "0x55",
|
||||
"svcCreateDeviceAddressSpace": "0x56",
|
||||
"svcAttachDeviceAddressSpace": "0x57",
|
||||
"svcDetachDeviceAddressSpace": "0x58",
|
||||
"svcMapDeviceAddressSpaceAligned": "0x5A",
|
||||
"svcUnmapDeviceAddressSpace": "0x5C",
|
||||
"svcFlushProcessDataCache": "0x5F"
|
||||
}
|
||||
},
|
||||
"map" : {
|
||||
"address" : "0x54200000",
|
||||
"size" : "0x3000",
|
||||
"is_ro" : false,
|
||||
"is_io" : true
|
||||
{
|
||||
"type": "map",
|
||||
"value": {
|
||||
"address": "0x50003000",
|
||||
"size": "0x1000",
|
||||
"is_ro": false,
|
||||
"is_io": true
|
||||
}
|
||||
},
|
||||
"map" : {
|
||||
"address" : "0x54300000",
|
||||
"size" : "0x1000",
|
||||
"is_ro" : false,
|
||||
"is_io" : true
|
||||
{
|
||||
"type": "map",
|
||||
"value": {
|
||||
"address": "0x54200000",
|
||||
"size": "0x3000",
|
||||
"is_ro": false,
|
||||
"is_io": true
|
||||
}
|
||||
},
|
||||
"map" : {
|
||||
"address" : "0x60006000",
|
||||
"size" : "0x1000",
|
||||
"is_ro" : false,
|
||||
"is_io" : true
|
||||
{
|
||||
"type": "map",
|
||||
"value": {
|
||||
"address": "0x54300000",
|
||||
"size": "0x1000",
|
||||
"is_ro": false,
|
||||
"is_io": true
|
||||
}
|
||||
},
|
||||
"map" : {
|
||||
"address" : "0x6000D000",
|
||||
"size" : "0x1000",
|
||||
"is_ro" : false,
|
||||
"is_io" : true
|
||||
{
|
||||
"type": "map",
|
||||
"value": {
|
||||
"address": "0x60006000",
|
||||
"size": "0x1000",
|
||||
"is_ro": false,
|
||||
"is_io": true
|
||||
}
|
||||
},
|
||||
"map" : {
|
||||
"address" : "0x70000000",
|
||||
"size" : "0x4000",
|
||||
"is_ro" : false,
|
||||
"is_io" : true
|
||||
{
|
||||
"type": "map",
|
||||
"value": {
|
||||
"address": "0x6000D000",
|
||||
"size": "0x1000",
|
||||
"is_ro": false,
|
||||
"is_io": true
|
||||
}
|
||||
},
|
||||
"map" : {
|
||||
"address" : "0x7000C000",
|
||||
"size" : "0x2000",
|
||||
"is_ro" : false,
|
||||
"is_io" : true
|
||||
{
|
||||
"type": "map",
|
||||
"value": {
|
||||
"address": "0x70000000",
|
||||
"size": "0x4000",
|
||||
"is_ro": false,
|
||||
"is_io": true
|
||||
}
|
||||
},
|
||||
"map" : {
|
||||
"address" : "0x7000E000",
|
||||
"size" : "0x4000",
|
||||
"is_ro" : false,
|
||||
"is_io" : true
|
||||
{
|
||||
"type": "map",
|
||||
"value": {
|
||||
"address": "0x7000C000",
|
||||
"size": "0x2000",
|
||||
"is_ro": false,
|
||||
"is_io": true
|
||||
}
|
||||
},
|
||||
"map" : {
|
||||
"address" : "0x700E3000",
|
||||
"size" : "0x1000",
|
||||
"is_ro" : false,
|
||||
"is_io" : true
|
||||
{
|
||||
"type": "map",
|
||||
"value": {
|
||||
"address": "0x7000E000",
|
||||
"size": "0x4000",
|
||||
"is_ro": false,
|
||||
"is_io": true
|
||||
}
|
||||
},
|
||||
"irq_pair" : [70, 116],
|
||||
"irq_pair" : [124, 152],
|
||||
"irq_pair" : [85, 95]
|
||||
}
|
||||
}
|
||||
{
|
||||
"type": "map",
|
||||
"value": {
|
||||
"address": "0x700E3000",
|
||||
"size": "0x1000",
|
||||
"is_ro": false,
|
||||
"is_io": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "irq_pair",
|
||||
"value": [
|
||||
70,
|
||||
116
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "irq_pair",
|
||||
"value": [
|
||||
124,
|
||||
152
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "irq_pair",
|
||||
"value": [
|
||||
85,
|
||||
95
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,116 +1,164 @@
|
||||
{
|
||||
"name" : "boot",
|
||||
"title_id" : "0x0100000000000005",
|
||||
"main_thread_stack_size" : "0x1000",
|
||||
"main_thread_priority" : 27,
|
||||
"default_cpu_id" : 3,
|
||||
"process_category" : 1,
|
||||
"kernel_capabilities" : {
|
||||
"handle_table_size" : 128,
|
||||
"syscalls" : {
|
||||
"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",
|
||||
"svcReadWriteRegister" : "0x4E",
|
||||
"svcCreateInterruptEvent" : "0x53",
|
||||
"svcQueryIoMapping" : "0x55",
|
||||
"svcCreateDeviceAddressSpace" : "0x56",
|
||||
"svcAttachDeviceAddressSpace" : "0x57",
|
||||
"svcDetachDeviceAddressSpace" : "0x58",
|
||||
"svcMapDeviceAddressSpaceAligned" : "0x5A",
|
||||
"svcUnmapDeviceAddressSpace" : "0x5C",
|
||||
"svcFlushProcessDataCache" : "0x5F"
|
||||
"name": "boot",
|
||||
"title_id": "0x0100000000000005",
|
||||
"main_thread_stack_size": "0x1000",
|
||||
"main_thread_priority": 27,
|
||||
"default_cpu_id": 3,
|
||||
"process_category": 1,
|
||||
"kernel_capabilities": [
|
||||
{
|
||||
"type": "handle_table_size",
|
||||
"value": 128
|
||||
},
|
||||
"map" : {
|
||||
"address" : "0x50003000",
|
||||
"size" : "0x1000",
|
||||
"is_ro" : false,
|
||||
"is_io" : true
|
||||
{
|
||||
"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",
|
||||
"svcReadWriteRegister": "0x4E",
|
||||
"svcCreateInterruptEvent": "0x53",
|
||||
"svcQueryIoMapping": "0x55",
|
||||
"svcCreateDeviceAddressSpace": "0x56",
|
||||
"svcAttachDeviceAddressSpace": "0x57",
|
||||
"svcDetachDeviceAddressSpace": "0x58",
|
||||
"svcMapDeviceAddressSpaceAligned": "0x5A",
|
||||
"svcUnmapDeviceAddressSpace": "0x5C",
|
||||
"svcFlushProcessDataCache": "0x5F"
|
||||
}
|
||||
},
|
||||
"map" : {
|
||||
"address" : "0x54200000",
|
||||
"size" : "0x3000",
|
||||
"is_ro" : false,
|
||||
"is_io" : true
|
||||
{
|
||||
"type": "map",
|
||||
"value": {
|
||||
"address": "0x50003000",
|
||||
"size": "0x1000",
|
||||
"is_ro": false,
|
||||
"is_io": true
|
||||
}
|
||||
},
|
||||
"map" : {
|
||||
"address" : "0x54300000",
|
||||
"size" : "0x1000",
|
||||
"is_ro" : false,
|
||||
"is_io" : true
|
||||
{
|
||||
"type": "map",
|
||||
"value": {
|
||||
"address": "0x54200000",
|
||||
"size": "0x3000",
|
||||
"is_ro": false,
|
||||
"is_io": true
|
||||
}
|
||||
},
|
||||
"map" : {
|
||||
"address" : "0x60006000",
|
||||
"size" : "0x1000",
|
||||
"is_ro" : false,
|
||||
"is_io" : true
|
||||
{
|
||||
"type": "map",
|
||||
"value": {
|
||||
"address": "0x54300000",
|
||||
"size": "0x1000",
|
||||
"is_ro": false,
|
||||
"is_io": true
|
||||
}
|
||||
},
|
||||
"map" : {
|
||||
"address" : "0x6000D000",
|
||||
"size" : "0x1000",
|
||||
"is_ro" : false,
|
||||
"is_io" : true
|
||||
{
|
||||
"type": "map",
|
||||
"value": {
|
||||
"address": "0x60006000",
|
||||
"size": "0x1000",
|
||||
"is_ro": false,
|
||||
"is_io": true
|
||||
}
|
||||
},
|
||||
"map" : {
|
||||
"address" : "0x70000000",
|
||||
"size" : "0x4000",
|
||||
"is_ro" : false,
|
||||
"is_io" : true
|
||||
{
|
||||
"type": "map",
|
||||
"value": {
|
||||
"address": "0x6000D000",
|
||||
"size": "0x1000",
|
||||
"is_ro": false,
|
||||
"is_io": true
|
||||
}
|
||||
},
|
||||
"map" : {
|
||||
"address" : "0x7000C000",
|
||||
"size" : "0x2000",
|
||||
"is_ro" : false,
|
||||
"is_io" : true
|
||||
{
|
||||
"type": "map",
|
||||
"value": {
|
||||
"address": "0x70000000",
|
||||
"size": "0x4000",
|
||||
"is_ro": false,
|
||||
"is_io": true
|
||||
}
|
||||
},
|
||||
"map" : {
|
||||
"address" : "0x700E3000",
|
||||
"size" : "0x1000",
|
||||
"is_ro" : false,
|
||||
"is_io" : true
|
||||
{
|
||||
"type": "map",
|
||||
"value": {
|
||||
"address": "0x7000C000",
|
||||
"size": "0x2000",
|
||||
"is_ro": false,
|
||||
"is_io": true
|
||||
}
|
||||
},
|
||||
"irq_pair" : [70, 116],
|
||||
"irq_pair" : [124, 152],
|
||||
"irq_pair" : [85, 95]
|
||||
}
|
||||
}
|
||||
{
|
||||
"type": "map",
|
||||
"value": {
|
||||
"address": "0x700E3000",
|
||||
"size": "0x1000",
|
||||
"is_ro": false,
|
||||
"is_io": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "irq_pair",
|
||||
"value": [
|
||||
70,
|
||||
116
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "irq_pair",
|
||||
"value": [
|
||||
124,
|
||||
152
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "irq_pair",
|
||||
"value": [
|
||||
85,
|
||||
95
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <malloc.h>
|
||||
|
||||
#include <switch.h>
|
||||
#include <atmosphere.h>
|
||||
#include <stratosphere.hpp>
|
||||
|
||||
#define CAR_BASE 0x60006000
|
||||
@@ -84,7 +85,7 @@ void __appInit(void) {
|
||||
|
||||
fsdevMountSdmc();
|
||||
|
||||
CheckAtmosphereVersion();
|
||||
CheckAtmosphereVersion(CURRENT_ATMOSPHERE_VERSION);
|
||||
}
|
||||
|
||||
void __appExit(void) {
|
||||
|
||||
@@ -1,96 +1,110 @@
|
||||
{
|
||||
"name": "creport",
|
||||
"title_id": "0x0100000000000036",
|
||||
"title_id_range_min": "0x0100000000000036",
|
||||
"title_id_range_max": "0x0100000000000036",
|
||||
"main_thread_stack_size": "0x00004000",
|
||||
"main_thread_priority": 44,
|
||||
"default_cpu_id": 3,
|
||||
"process_category": 0,
|
||||
"is_retail": true,
|
||||
"pool_partition": 2,
|
||||
"is_64_bit": true,
|
||||
"address_space_type": 3,
|
||||
"filesystem_access": {
|
||||
"permissions": "0xFFFFFFFFFFFFFFFF"
|
||||
},
|
||||
"service_access": {
|
||||
"csrng": false,
|
||||
"erpt:c": false,
|
||||
"fatal:u": false,
|
||||
"ns:dev": false,
|
||||
"fsp-srv": false,
|
||||
"time:s": true
|
||||
},
|
||||
"kernel_capabilities": {
|
||||
"kernel_flags": {
|
||||
"highest_thread_priority": 63,
|
||||
"lowest_thread_priority": 24,
|
||||
"lowest_cpu_id": 3,
|
||||
"highest_cpu_id": 3
|
||||
},
|
||||
"syscalls": {
|
||||
"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",
|
||||
"svcDebugActiveProcess": "0x60",
|
||||
"svcGetDebugEvent": "0x63",
|
||||
"svcGetThreadList": "0x66",
|
||||
"svcGetDebugThreadContext": "0x67",
|
||||
"svcQueryDebugProcessMemory": "0x69",
|
||||
"svcReadDebugProcessMemory": "0x6a",
|
||||
"svcGetDebugThreadParam": "0x6d"
|
||||
},
|
||||
"min_kernel_version": "0x0060",
|
||||
"debug_flags": {
|
||||
"allow_debug": false,
|
||||
"force_debug": true
|
||||
}
|
||||
}
|
||||
"name": "creport",
|
||||
"title_id": "0x0100000000000036",
|
||||
"title_id_range_min": "0x0100000000000036",
|
||||
"title_id_range_max": "0x0100000000000036",
|
||||
"main_thread_stack_size": "0x00004000",
|
||||
"main_thread_priority": 44,
|
||||
"default_cpu_id": 3,
|
||||
"process_category": 0,
|
||||
"is_retail": true,
|
||||
"pool_partition": 2,
|
||||
"is_64_bit": true,
|
||||
"address_space_type": 3,
|
||||
"filesystem_access": {
|
||||
"permissions": "0xFFFFFFFFFFFFFFFF"
|
||||
},
|
||||
"service_host": [
|
||||
"time:s"
|
||||
],
|
||||
"service_access": [
|
||||
"csrng",
|
||||
"erpt:c",
|
||||
"fatal:u",
|
||||
"ns:dev",
|
||||
"fsp-srv"
|
||||
],
|
||||
"kernel_capabilities": [
|
||||
{
|
||||
"type": "kernel_flags",
|
||||
"value": {
|
||||
"highest_thread_priority": 63,
|
||||
"lowest_thread_priority": 24,
|
||||
"lowest_cpu_id": 3,
|
||||
"highest_cpu_id": 3
|
||||
}
|
||||
},
|
||||
{
|
||||
"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",
|
||||
"svcDebugActiveProcess": "0x60",
|
||||
"svcGetDebugEvent": "0x63",
|
||||
"svcGetThreadList": "0x66",
|
||||
"svcGetDebugThreadContext": "0x67",
|
||||
"svcQueryDebugProcessMemory": "0x69",
|
||||
"svcReadDebugProcessMemory": "0x6a",
|
||||
"svcGetDebugThreadParam": "0x6d"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "min_kernel_version",
|
||||
"value": "0x0060"
|
||||
},
|
||||
{
|
||||
"type": "debug_flags",
|
||||
"value": {
|
||||
"allow_debug": false,
|
||||
"force_debug": true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,70 +1,77 @@
|
||||
{
|
||||
"name" : "fs.mitm",
|
||||
"title_id" : "0x010041544D530000",
|
||||
"main_thread_stack_size" : "0x20000",
|
||||
"main_thread_priority": 43,
|
||||
"default_cpu_id": 3,
|
||||
"process_category" : 1,
|
||||
"kernel_capabilities" : {
|
||||
"handle_table_size" : 512,
|
||||
"syscalls": {
|
||||
"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"
|
||||
}
|
||||
}
|
||||
"name": "fs.mitm",
|
||||
"title_id": "0x010041544D530000",
|
||||
"main_thread_stack_size": "0x20000",
|
||||
"main_thread_priority": 43,
|
||||
"default_cpu_id": 3,
|
||||
"process_category": 1,
|
||||
"kernel_capabilities": [
|
||||
{
|
||||
"type": "handle_table_size",
|
||||
"value": 512
|
||||
},
|
||||
{
|
||||
"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",
|
||||
"svcReadWriteRegister": "0x4E",
|
||||
"svcQueryIoMapping": "0x55",
|
||||
"svcCreateDeviceAddressSpace": "0x56",
|
||||
"svcAttachDeviceAddressSpace": "0x57",
|
||||
"svcDetachDeviceAddressSpace": "0x58",
|
||||
"svcMapDeviceAddressSpaceAligned": "0x5a",
|
||||
"svcUnmapDeviceAddressSpace": "0x5c",
|
||||
"svcGetSystemInfo": "0x6f"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -24,7 +24,5 @@ void Reboot() {
|
||||
}
|
||||
|
||||
void Log(const void *data, int size) {
|
||||
(void)(data);
|
||||
(void)(size);
|
||||
/* ... */
|
||||
}
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -46,6 +46,11 @@ LayeredRomFS::LayeredRomFS(std::shared_ptr<RomInterfaceStorage> s_r, std::shared
|
||||
|
||||
|
||||
Result LayeredRomFS::Read(void *buffer, size_t size, u64 offset) {
|
||||
/* Size zero reads should always succeed. */
|
||||
if (size == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Validate size. */
|
||||
u64 virt_size = (*this->p_source_infos)[this->p_source_infos->size() - 1].virtual_offset + (*this->p_source_infos)[this->p_source_infos->size() - 1].size;
|
||||
if (offset >= virt_size) {
|
||||
@@ -83,6 +88,22 @@ Result LayeredRomFS::Read(void *buffer, size_t size, u64 offset) {
|
||||
cur_read_size = cur_source->size - (offset - cur_source->virtual_offset);
|
||||
}
|
||||
switch (cur_source->type) {
|
||||
case RomFSDataSource::MetaData:
|
||||
{
|
||||
FsFile file;
|
||||
if (R_FAILED((rc = Utils::OpenSdFileForAtmosphere(this->title_id, ROMFS_METADATA_FILE_PATH, FS_OPEN_READ, &file)))) {
|
||||
fatalSimple(rc);
|
||||
}
|
||||
size_t out_read;
|
||||
if (R_FAILED((rc = fsFileRead(&file, (offset - cur_source->virtual_offset), (void *)((uintptr_t)buffer + read_so_far), cur_read_size, &out_read)))) {
|
||||
fatalSimple(rc);
|
||||
}
|
||||
if (out_read != cur_read_size) {
|
||||
Reboot();
|
||||
}
|
||||
fsFileClose(&file);
|
||||
}
|
||||
break;
|
||||
case RomFSDataSource::LooseFile:
|
||||
{
|
||||
FsFile 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;
|
||||
};
|
||||
|
||||
@@ -20,20 +20,13 @@
|
||||
#include <malloc.h>
|
||||
|
||||
#include <switch.h>
|
||||
#include <atmosphere.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"
|
||||
|
||||
#include "setsys_mitm_service.hpp"
|
||||
|
||||
extern "C" {
|
||||
extern u32 __start__;
|
||||
|
||||
@@ -69,56 +62,33 @@ 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));
|
||||
}
|
||||
CheckAtmosphereVersion();
|
||||
|
||||
CheckAtmosphereVersion(CURRENT_ATMOSPHERE_VERSION);
|
||||
}
|
||||
|
||||
void __appExit(void) {
|
||||
/* Cleanup services. */
|
||||
fsExit();
|
||||
smMitMExit();
|
||||
smExit();
|
||||
}
|
||||
|
||||
void CreateSettingsMitMServer(void *arg) {
|
||||
MultiThreadedWaitableManager *server_manager = (MultiThreadedWaitableManager *)arg;
|
||||
|
||||
Result rc;
|
||||
if (R_FAILED((rc = setsysInitialize()))) {
|
||||
fatalSimple(rc);
|
||||
}
|
||||
|
||||
ISession<MitMQueryService<SetSysMitMService>> *setsys_query_srv = NULL;
|
||||
MitMServer<SetSysMitMService> *setsys_srv = new MitMServer<SetSysMitMService>(&setsys_query_srv, "set:sys", 60);
|
||||
server_manager->add_waitable(setsys_srv);
|
||||
server_manager->add_waitable(setsys_query_srv);
|
||||
|
||||
svcExitThread();
|
||||
}
|
||||
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};
|
||||
Thread set_mitm_setup_thread = {0};
|
||||
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. */
|
||||
}
|
||||
@@ -134,24 +104,13 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
/* TODO: What's a good timeout value to use here? */
|
||||
MultiThreadedWaitableManager *server_manager = new MultiThreadedWaitableManager(5, U64_MAX, 0x20000);
|
||||
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);
|
||||
|
||||
/* Create set:sys mitm server, delayed until set:sys is available. */
|
||||
if (R_FAILED(threadCreate(&set_mitm_setup_thread, &CreateSettingsMitMServer, server_manager, 0x4000, 0x15, 0))) {
|
||||
/* TODO: Panic. */
|
||||
}
|
||||
if (R_FAILED(threadStart(&set_mitm_setup_thread))) {
|
||||
/* TODO: Panic. */
|
||||
}
|
||||
|
||||
AddMitmServerToManager<FsMitmService>(server_manager, "fsp-srv", 61);
|
||||
|
||||
/* Loop forever, servicing our services. */
|
||||
server_manager->process();
|
||||
server_manager->Process();
|
||||
|
||||
delete server_manager;
|
||||
|
||||
|
||||
@@ -399,23 +399,14 @@ void RomFSBuildContext::Build(std::vector<RomFSSourceInfo> *out_infos) {
|
||||
header->file_hash_table_ofs = header->dir_table_ofs + header->dir_table_size;
|
||||
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))) {
|
||||
FsFile f;
|
||||
fsFsCreateFile(&sd_fs, "/METADATALOG.bin", this->dir_hash_table_size + this->dir_table_size + this->file_hash_table_size + this->file_table_size + sizeof(*header), 0);
|
||||
if (R_SUCCEEDED(fsFsOpenFile(&sd_fs, "/METADATALOG.bin", FS_OPEN_READ | FS_OPEN_WRITE, &f))) {
|
||||
fsFileSetSize(&f, this->dir_hash_table_size + this->dir_table_size + this->file_hash_table_size + this->file_table_size + sizeof(*header));
|
||||
fsFileWrite(&f, 0, header, sizeof(*header));
|
||||
fsFileWrite(&f, sizeof(*header), metadata, this->dir_hash_table_size + this->dir_table_size + this->file_hash_table_size + this->file_table_size);
|
||||
fsFileClose(&f);
|
||||
}
|
||||
fsFsClose(&sd_fs);
|
||||
}
|
||||
}
|
||||
*/
|
||||
const size_t metadata_size = this->dir_hash_table_size + this->dir_table_size + this->file_hash_table_size + this->file_table_size;
|
||||
|
||||
/* Try to save metadata to the SD card, to save on memory space. */
|
||||
if (R_SUCCEEDED(Utils::SaveSdFileForAtmosphere(this->title_id, ROMFS_METADATA_FILE_PATH, metadata, metadata_size))) {
|
||||
out_infos->emplace_back(header->dir_hash_table_ofs, metadata_size, RomFSDataSource::MetaData);
|
||||
delete metadata;
|
||||
} else {
|
||||
out_infos->emplace_back(header->dir_hash_table_ofs, metadata_size, metadata, RomFSDataSource::Memory);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -25,11 +25,14 @@
|
||||
#define ROMFS_ENTRY_EMPTY 0xFFFFFFFF
|
||||
#define ROMFS_FILEPARTITION_OFS 0x200
|
||||
|
||||
#define ROMFS_METADATA_FILE_PATH "romfs_metadata.bin"
|
||||
|
||||
/* Types for RomFS Meta construction. */
|
||||
enum class RomFSDataSource {
|
||||
BaseRomFS,
|
||||
FileRomFS,
|
||||
LooseFile,
|
||||
MetaData,
|
||||
Memory,
|
||||
};
|
||||
|
||||
@@ -49,6 +52,10 @@ struct RomFSMemorySourceInfo {
|
||||
const u8 *data;
|
||||
};
|
||||
|
||||
struct RomFSMetaDataSourceInfo {
|
||||
|
||||
};
|
||||
|
||||
struct RomFSSourceInfo {
|
||||
u64 virtual_offset;
|
||||
u64 size;
|
||||
@@ -57,6 +64,7 @@ struct RomFSSourceInfo {
|
||||
RomFSFileSourceInfo file_source_info;
|
||||
RomFSLooseSourceInfo loose_source_info;
|
||||
RomFSMemorySourceInfo memory_source_info;
|
||||
RomFSMemorySourceInfo metadata_source_info;
|
||||
};
|
||||
RomFSDataSource type;
|
||||
|
||||
@@ -69,6 +77,7 @@ struct RomFSSourceInfo {
|
||||
this->file_source_info.offset = offset;
|
||||
break;
|
||||
case RomFSDataSource::LooseFile:
|
||||
case RomFSDataSource::MetaData:
|
||||
case RomFSDataSource::Memory:
|
||||
default:
|
||||
fatalSimple(0xF601);
|
||||
@@ -83,6 +92,20 @@ struct RomFSSourceInfo {
|
||||
case RomFSDataSource::Memory:
|
||||
this->memory_source_info.data = (decltype(this->memory_source_info.data))arg;
|
||||
break;
|
||||
case RomFSDataSource::MetaData:
|
||||
case RomFSDataSource::BaseRomFS:
|
||||
case RomFSDataSource::FileRomFS:
|
||||
default:
|
||||
fatalSimple(0xF601);
|
||||
}
|
||||
}
|
||||
|
||||
RomFSSourceInfo(u64 v_o, u64 s, RomFSDataSource t) : virtual_offset(v_o), size(s), type(t) {
|
||||
switch (this->type) {
|
||||
case RomFSDataSource::MetaData:
|
||||
break;
|
||||
case RomFSDataSource::LooseFile:
|
||||
case RomFSDataSource::Memory:
|
||||
case RomFSDataSource::BaseRomFS:
|
||||
case RomFSDataSource::FileRomFS:
|
||||
default:
|
||||
@@ -94,6 +117,7 @@ struct RomFSSourceInfo {
|
||||
switch (this->type) {
|
||||
case RomFSDataSource::BaseRomFS:
|
||||
case RomFSDataSource::FileRomFS:
|
||||
case RomFSDataSource::MetaData:
|
||||
break;
|
||||
case RomFSDataSource::LooseFile:
|
||||
delete this->loose_source_info.path;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -14,150 +14,194 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
|
||||
#include <switch.h>
|
||||
#include <stratosphere.hpp>
|
||||
#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);
|
||||
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;
|
||||
}
|
||||
}
|
||||
static HosMutex g_StorageCacheLock;
|
||||
static std::unordered_map<u64, std::weak_ptr<IStorageInterface>> g_StorageCache;
|
||||
|
||||
static bool StorageCacheGetEntry(u64 title_id, std::shared_ptr<IStorageInterface> *out) {
|
||||
std::scoped_lock<HosMutex> lock(g_StorageCacheLock);
|
||||
if (g_StorageCache.find(title_id) == g_StorageCache.end()) {
|
||||
return false;
|
||||
}
|
||||
return rc;
|
||||
|
||||
auto intf = g_StorageCache[title_id].lock();
|
||||
if (intf != nullptr) {
|
||||
*out = intf;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
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;
|
||||
static void StorageCacheSetEntry(u64 title_id, std::shared_ptr<IStorageInterface> *ptr) {
|
||||
std::scoped_lock<HosMutex> lock(g_StorageCacheLock);
|
||||
|
||||
u64 *tls = (u64 *)armGetTls();
|
||||
std::array<u64, 0x100/sizeof(u64)> backup_tls;
|
||||
std::copy(tls, tls + backup_tls.size(), backup_tls.begin());
|
||||
/* Ensure we always use the cached copy if present. */
|
||||
if (g_StorageCache.find(title_id) != g_StorageCache.end()) {
|
||||
auto intf = g_StorageCache[title_id].lock();
|
||||
if (intf != nullptr) {
|
||||
*ptr = intf;
|
||||
}
|
||||
}
|
||||
|
||||
Result rc = (Result)resp->result;
|
||||
switch (static_cast<FspSrvCmd>(cmd_id)) {
|
||||
case FspSrvCmd::SetCurrentProcess:
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
this->has_initialized = true;
|
||||
g_StorageCache[title_id] = *ptr;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
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;
|
||||
if (this->romfs_storage != nullptr) {
|
||||
if (this->get_owner() != NULL) {
|
||||
Result rc = 0;
|
||||
|
||||
bool has_cache = StorageCacheGetEntry(this->title_id, &storage);
|
||||
|
||||
ON_SCOPE_EXIT {
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
if (!has_cache) {
|
||||
StorageCacheSetEntry(this->title_id, &storage);
|
||||
}
|
||||
|
||||
out_storage.SetValue(std::move(storage));
|
||||
if (out_storage.IsDomain()) {
|
||||
out_storage.ChangeObjectId(out_domain_id);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
if (has_cache) {
|
||||
if (out_storage.IsDomain()) {
|
||||
FsStorage s = {0};
|
||||
rc = fsOpenDataStorageByCurrentProcessFwd(this->forward_service, &s);
|
||||
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);
|
||||
if (R_FAILED(rc)) {
|
||||
storage.reset();
|
||||
}
|
||||
} else {
|
||||
FsStorage data_storage;
|
||||
FsFile data_file;
|
||||
|
||||
rc = fsOpenDataStorageByCurrentProcessFwd(this->forward_service, &data_storage);
|
||||
rc = fsOpenDataStorageByCurrentProcessFwd(this->forward_service.get(), &data_storage);
|
||||
|
||||
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));
|
||||
if (Utils::HasSdRomfsContent(this->title_id)) {
|
||||
/* 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))) {
|
||||
storage = std::make_shared<IStorageInterface>(new LayeredRomFS(std::make_shared<RomInterfaceStorage>(data_storage), std::make_shared<RomFileStorage>(data_file), this->title_id));
|
||||
} else {
|
||||
storage = std::make_shared<IStorageInterface>(new LayeredRomFS(std::make_shared<RomInterfaceStorage>(data_storage), nullptr, this->title_id));
|
||||
}
|
||||
if (out_storage.IsDomain()) {
|
||||
out_domain_id = data_storage.s.object_id;
|
||||
}
|
||||
} else {
|
||||
out_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);
|
||||
} else {
|
||||
out_domain_id = data_storage.s.object_id;
|
||||
/* If we don't have anything to modify, there's no sense in maintaining a copy of the metadata tables. */
|
||||
fsStorageClose(&data_storage);
|
||||
rc = RESULT_FORWARD_TO_SESSION;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
Result rc = 0;
|
||||
|
||||
rc = fsOpenDataStorageByDataIdFwd(this->forward_service, 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)));
|
||||
} else {
|
||||
out_session = new IPCSession<IStorageInterface>(std::make_shared<IStorageInterface>(new LayeredRomFS(std::make_shared<RomInterfaceStorage>(data_storage), nullptr, data_id)));
|
||||
bool has_cache = StorageCacheGetEntry(data_id, &storage);
|
||||
|
||||
ON_SCOPE_EXIT {
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
if (!has_cache) {
|
||||
StorageCacheSetEntry(data_id, &storage);
|
||||
}
|
||||
|
||||
out_storage.SetValue(std::move(storage));
|
||||
if (out_storage.IsDomain()) {
|
||||
out_storage.ChangeObjectId(out_domain_id);
|
||||
}
|
||||
}
|
||||
if (this->get_owner() == NULL) {
|
||||
FsMitMWorker::AddWaitable(out_session);
|
||||
};
|
||||
|
||||
if (has_cache) {
|
||||
if (out_storage.IsDomain()) {
|
||||
FsStorage s = {0};
|
||||
rc = fsOpenDataStorageByDataIdFwd(this->forward_service.get(), storage_id, data_id, &s);
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
out_domain_id = s.s.object_id;
|
||||
}
|
||||
} else {
|
||||
out_domain_id = data_storage.s.object_id;
|
||||
rc = 0;
|
||||
}
|
||||
if (R_FAILED(rc)) {
|
||||
storage.reset();
|
||||
}
|
||||
} else {
|
||||
rc = fsOpenDataStorageByDataIdFwd(this->forward_service.get(), storage_id, data_id, &data_storage);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
if (Utils::HasSdRomfsContent(data_id)) {
|
||||
/* 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))) {
|
||||
storage = std::make_shared<IStorageInterface>(new LayeredRomFS(std::make_shared<RomInterfaceStorage>(data_storage), std::make_shared<RomFileStorage>(data_file), data_id));
|
||||
} else {
|
||||
storage = std::make_shared<IStorageInterface>(new LayeredRomFS(std::make_shared<RomInterfaceStorage>(data_storage), nullptr, data_id));
|
||||
}
|
||||
if (out_storage.IsDomain()) {
|
||||
out_domain_id = data_storage.s.object_id;
|
||||
}
|
||||
} else {
|
||||
/* If we don't have anything to modify, there's no sense in maintaining a copy of the metadata tables. */
|
||||
fsStorageClose(&data_storage);
|
||||
rc = RESULT_FORWARD_TO_SESSION;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OutSession out_s = OutSession(out_session);
|
||||
out_s.domain_id = out_domain_id;
|
||||
return {rc, out_s};
|
||||
return rc;
|
||||
}
|
||||
@@ -16,52 +16,40 @@
|
||||
|
||||
#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) {
|
||||
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>(),
|
||||
};
|
||||
};
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
#include <algorithm>
|
||||
#include <strings.h>
|
||||
|
||||
#include "sm_mitm.h"
|
||||
#include "debug.hpp"
|
||||
#include "fsmitm_utils.hpp"
|
||||
#include "ini.h"
|
||||
@@ -202,19 +201,66 @@ Result Utils::OpenRomFSDir(FsFileSystem *fs, u64 title_id, const char *path, FsD
|
||||
return fsFsOpenDirectory(fs, safe_path, FS_DIROPEN_DIRECTORY | FS_DIROPEN_FILE, out);
|
||||
}
|
||||
|
||||
Result Utils::HasSdRomfsContent(u64 title_id, bool *out) {
|
||||
Result rc;
|
||||
FsDir dir;
|
||||
if (R_FAILED((rc = Utils::OpenRomFSSdDir(title_id, "", &dir)))) {
|
||||
return rc;
|
||||
bool Utils::HasSdRomfsContent(u64 title_id) {
|
||||
/* Check for romfs.bin. */
|
||||
FsFile data_file;
|
||||
if (R_SUCCEEDED(Utils::OpenSdFileForAtmosphere(title_id, "romfs.bin", FS_OPEN_READ, &data_file))) {
|
||||
fsFileClose(&data_file);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Check for romfs folder with non-zero content. */
|
||||
FsDir dir;
|
||||
if (R_FAILED(Utils::OpenRomFSSdDir(title_id, "", &dir))) {
|
||||
return false;
|
||||
}
|
||||
ON_SCOPE_EXIT {
|
||||
fsDirClose(&dir);
|
||||
};
|
||||
|
||||
FsDirectoryEntry dir_entry;
|
||||
u64 read_entries;
|
||||
if (R_SUCCEEDED((rc = fsDirRead(&dir, 0, &read_entries, 1, &dir_entry)))) {
|
||||
*out = (read_entries == 1);
|
||||
return R_SUCCEEDED(fsDirRead(&dir, 0, &read_entries, 1, &dir_entry)) && read_entries == 1;
|
||||
}
|
||||
|
||||
Result Utils::SaveSdFileForAtmosphere(u64 title_id, const char *fn, void *data, size_t size) {
|
||||
if (!IsSdInitialized()) {
|
||||
return 0xFA202;
|
||||
}
|
||||
fsDirClose(&dir);
|
||||
|
||||
Result rc = 0;
|
||||
|
||||
char path[FS_MAX_PATH];
|
||||
if (*fn == '/') {
|
||||
snprintf(path, sizeof(path), "/atmosphere/titles/%016lx%s", title_id, fn);
|
||||
} else {
|
||||
snprintf(path, sizeof(path), "/atmosphere/titles/%016lx/%s", title_id, fn);
|
||||
}
|
||||
|
||||
/* Unconditionally create. */
|
||||
FsFile f;
|
||||
fsFsCreateFile(&g_sd_filesystem, path, size, 0);
|
||||
|
||||
/* Try to open. */
|
||||
rc = fsFsOpenFile(&g_sd_filesystem, path, FS_OPEN_READ | FS_OPEN_WRITE, &f);
|
||||
if (R_FAILED(rc)) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Always close, if we opened. */
|
||||
ON_SCOPE_EXIT {
|
||||
fsFileClose(&f);
|
||||
};
|
||||
|
||||
/* Try to make it big enough. */
|
||||
rc = fsFileSetSize(&f, size);
|
||||
if (R_FAILED(rc)) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Try to write the data. */
|
||||
rc = fsFileWrite(&f, 0, data, size);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,18 +21,20 @@
|
||||
class Utils {
|
||||
public:
|
||||
static bool IsSdInitialized();
|
||||
|
||||
static Result OpenSdFile(const char *fn, int flags, FsFile *out);
|
||||
static Result OpenSdFileForAtmosphere(u64 title_id, const char *fn, int flags, FsFile *out);
|
||||
static Result OpenRomFSSdFile(u64 title_id, const char *fn, int flags, FsFile *out);
|
||||
static Result OpenSdDir(const char *path, FsDir *out);
|
||||
static Result OpenSdDirForAtmosphere(u64 title_id, const char *path, FsDir *out);
|
||||
static Result OpenRomFSSdDir(u64 title_id, const char *path, FsDir *out);
|
||||
|
||||
static Result OpenRomFSSdDir(u64 title_id, const char *path, FsDir *out);
|
||||
|
||||
static Result OpenRomFSFile(FsFileSystem *fs, u64 title_id, const char *fn, int flags, FsFile *out);
|
||||
static Result OpenRomFSDir(FsFileSystem *fs, u64 title_id, const char *path, FsDir *out);
|
||||
|
||||
static Result HasSdRomfsContent(u64 title_id, bool *out);
|
||||
static Result SaveSdFileForAtmosphere(u64 title_id, const char *fn, void *data, size_t size);
|
||||
|
||||
static bool HasSdRomfsContent(u64 title_id);
|
||||
|
||||
/* SD card Initialization + MitM detection. */
|
||||
static void InitializeSdThreadFunc(void *args);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
@@ -1,45 +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 <atomic>
|
||||
|
||||
#include <stratosphere.hpp>
|
||||
|
||||
#include "debug.hpp"
|
||||
|
||||
class IMitMServiceObject : public IServiceObject {
|
||||
protected:
|
||||
Service *forward_service;
|
||||
u64 process_id = 0;
|
||||
u64 title_id = 0;
|
||||
public:
|
||||
IMitMServiceObject(Service *s) : forward_service(s) {
|
||||
|
||||
}
|
||||
|
||||
static bool should_mitm(u64 pid, u64 tid) {
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void clone_to(void *o) = 0;
|
||||
protected:
|
||||
virtual ~IMitMServiceObject() = default;
|
||||
virtual Result dispatch(IpcParsedCommand &r, IpcCommand &out_c, u64 cmd_id, u8 *pointer_buffer, size_t pointer_buffer_size) = 0;
|
||||
virtual void postprocess(IpcParsedCommand &r, IpcCommand &out_c, u64 cmd_id, u8 *pointer_buffer, size_t pointer_buffer_size) = 0;
|
||||
virtual Result handle_deferred() = 0;
|
||||
};
|
||||
@@ -1,43 +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 "mitm_query_service.hpp"
|
||||
|
||||
static std::vector<u64> g_known_pids;
|
||||
static std::vector<u64> g_known_tids;
|
||||
static HosMutex g_pid_tid_mutex;
|
||||
|
||||
Result MitMQueryUtils::get_associated_tid_for_pid(u64 pid, u64 *tid) {
|
||||
Result rc = 0xCAFE;
|
||||
std::scoped_lock lk{g_pid_tid_mutex};
|
||||
for (unsigned int i = 0; i < g_known_pids.size(); i++) {
|
||||
if (g_known_pids[i] == pid) {
|
||||
*tid = g_known_tids[i];
|
||||
rc = 0x0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
void MitMQueryUtils::associate_pid_to_tid(u64 pid, u64 tid) {
|
||||
std::scoped_lock lk{g_pid_tid_mutex};
|
||||
g_known_pids.push_back(pid);
|
||||
g_known_tids.push_back(tid);
|
||||
}
|
||||
@@ -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};
|
||||
}
|
||||
};
|
||||
@@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,246 +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.IsDomainRequest) {
|
||||
obj = this->domain->get_domain_object(r.InThisObjectId);
|
||||
if (obj != nullptr && r.InMessageType == DomainMessageType_Close) {
|
||||
if (r.InThisObjectId == this->mitm_domain_id) {
|
||||
Reboot();
|
||||
}
|
||||
this->domain->delete_object(r.InThisObjectId);
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 result;
|
||||
} *o_resp;
|
||||
|
||||
o_resp = (decltype(o_resp)) ipcPrepareHeaderForDomain(&c, sizeof(*o_resp), 0);
|
||||
*(DomainResponseHeader *)((uintptr_t)o_resp - sizeof(DomainResponseHeader)) = {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.IsDomainRequest) {
|
||||
/* We never work with out object ids, so this should be fine. */
|
||||
ipcParseDomainResponse(&cur_out_r, 0);
|
||||
} 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.IsDomainRequest) {
|
||||
/* We never work with out object ids, so this should be fine. */
|
||||
ipcParseDomainResponse(&cur_out_r, 0);
|
||||
} 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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -1,58 +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 "imitmserviceobject.hpp"
|
||||
#include "fsmitm_utils.hpp"
|
||||
|
||||
enum class SetSysCmd {
|
||||
GetFirmwareVersion = 3,
|
||||
GetFirmwareVersion2 = 4,
|
||||
};
|
||||
|
||||
class SetSysMitMService : public IMitMServiceObject {
|
||||
private:
|
||||
public:
|
||||
SetSysMitMService(Service *s) : IMitMServiceObject(s) {
|
||||
/* ... */
|
||||
}
|
||||
|
||||
static bool should_mitm(u64 pid, u64 tid) {
|
||||
/* Only MitM qlaunch, maintenance. */
|
||||
return tid == 0x0100000000001000ULL || tid == 0x0100000000001015ULL;
|
||||
}
|
||||
|
||||
SetSysMitMService *clone() override {
|
||||
auto new_srv = new SetSysMitMService((Service *)&this->forward_service);
|
||||
this->clone_to(new_srv);
|
||||
return new_srv;
|
||||
}
|
||||
|
||||
void clone_to(void *o) override {
|
||||
/* ... */
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
protected:
|
||||
/* Overridden commands. */
|
||||
std::tuple<Result> get_firmware_version(OutPointerWithServerSize<SetSysFirmwareVersion, 0x1> out);
|
||||
std::tuple<Result> get_firmware_version2(OutPointerWithServerSize<SetSysFirmwareVersion, 0x1> out);
|
||||
};
|
||||
@@ -1,190 +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 <switch.h>
|
||||
#include <switch/arm/atomics.h>
|
||||
#include "sm_mitm.h"
|
||||
|
||||
static Handle g_smMitmHandle = INVALID_HANDLE;
|
||||
static u64 g_refCnt;
|
||||
|
||||
Result smMitMInitialize(void) {
|
||||
atomicIncrement64(&g_refCnt);
|
||||
|
||||
if (g_smMitmHandle != INVALID_HANDLE)
|
||||
return 0;
|
||||
|
||||
Result rc = svcConnectToNamedPort(&g_smMitmHandle, "sm:");
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
ipcSendPid(&c);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 cmd_id;
|
||||
u64 zero;
|
||||
u64 reserved[2];
|
||||
} *raw;
|
||||
|
||||
raw = ipcPrepareHeader(&c, sizeof(*raw));
|
||||
|
||||
raw->magic = SFCI_MAGIC;
|
||||
raw->cmd_id = 0;
|
||||
raw->zero = 0;
|
||||
|
||||
rc = ipcDispatch(g_smMitmHandle);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
IpcParsedCommand r;
|
||||
ipcParse(&r);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 result;
|
||||
} *resp = r.Raw;
|
||||
|
||||
rc = resp->result;
|
||||
}
|
||||
}
|
||||
|
||||
if (R_FAILED(rc))
|
||||
smExit();
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void smMitMExit(void) {
|
||||
if (atomicDecrement64(&g_refCnt) == 0) {
|
||||
svcCloseHandle(g_smMitmHandle);
|
||||
g_smMitmHandle = INVALID_HANDLE;
|
||||
}
|
||||
}
|
||||
|
||||
Result smMitMGetService(Service* service_out, const char *name_str)
|
||||
{
|
||||
u64 name = smEncodeName(name_str);
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 cmd_id;
|
||||
u64 service_name;
|
||||
u64 reserved[2];
|
||||
} *raw;
|
||||
|
||||
raw = ipcPrepareHeader(&c, sizeof(*raw));
|
||||
|
||||
raw->magic = SFCI_MAGIC;
|
||||
raw->cmd_id = 1;
|
||||
raw->service_name = name;
|
||||
|
||||
Result rc = ipcDispatch(g_smMitmHandle);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
IpcParsedCommand r;
|
||||
ipcParse(&r);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 result;
|
||||
} *resp = r.Raw;
|
||||
|
||||
rc = resp->result;
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
service_out->type = ServiceType_Normal;
|
||||
service_out->handle = r.Handles[0];
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
Result smMitMInstall(Handle *handle_out, Handle *query_out, const char *name) {
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 cmd_id;
|
||||
u64 service_name;
|
||||
} *raw;
|
||||
|
||||
raw = ipcPrepareHeader(&c, sizeof(*raw));
|
||||
|
||||
raw->magic = SFCI_MAGIC;
|
||||
raw->cmd_id = 65000;
|
||||
raw->service_name = smEncodeName(name);
|
||||
|
||||
Result rc = ipcDispatch(g_smMitmHandle);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
IpcParsedCommand r;
|
||||
ipcParse(&r);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 result;
|
||||
} *resp = r.Raw;
|
||||
|
||||
rc = resp->result;
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
*handle_out = r.Handles[0];
|
||||
*query_out = r.Handles[1];
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result smMitMUninstall(const char *name) {
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 cmd_id;
|
||||
u64 service_name;
|
||||
u64 reserved;
|
||||
} *raw;
|
||||
|
||||
raw = ipcPrepareHeader(&c, sizeof(*raw));
|
||||
|
||||
raw->magic = SFCI_MAGIC;
|
||||
raw->cmd_id = 65001;
|
||||
raw->service_name = smEncodeName(name);
|
||||
|
||||
Result rc = ipcDispatch(g_smMitmHandle);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
IpcParsedCommand r;
|
||||
ipcParse(&r);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 result;
|
||||
} *resp = r.Raw;
|
||||
|
||||
rc = resp->result;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
/**
|
||||
* @file sm_mitm.h
|
||||
* @brief Service manager (sm) IPC wrapper for Atmosphere extensions.
|
||||
* @author SciresM
|
||||
* @copyright libnx Authors
|
||||
*/
|
||||
#pragma once
|
||||
#include <switch.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
Result smMitMInitialize(void);
|
||||
void smMitMExit(void);
|
||||
Result smMitMGetService(Service* service_out, const char *name);
|
||||
Result smMitMInstall(Handle *handle_out, Handle *query_out, const char *name);
|
||||
Result smMitMUninstall(const char *name);
|
||||
|
||||
Result smMitMIsRegistered(const char *name);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
1
stratosphere/libstratosphere
Submodule
1
stratosphere/libstratosphere
Submodule
Submodule stratosphere/libstratosphere added at bcd80ab445
4
stratosphere/libstratosphere/.gitignore
vendored
4
stratosphere/libstratosphere/.gitignore
vendored
@@ -1,4 +0,0 @@
|
||||
debug
|
||||
release
|
||||
lib
|
||||
*.bz2
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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;
|
||||
};
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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;
|
||||
};
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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;
|
||||
};
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user