Compare commits

...

57 Commits
0.7.3 ... 0.7.5

Author SHA1 Message Date
Michael Scire
164fb96da0 Update changelog.md for 0.7.5 2018-11-11 20:14:20 -08:00
Michael Scire
31c1338dba Bump version number to 0.7.5 2018-11-11 20:04:18 -08:00
Michael Scire
7d729e1836 creport: Add another code region locating improvement. 2018-11-11 20:00:04 -08:00
Michael Scire
36530a5501 creport: Improve code region list (as N did in 6.1.0) 2018-11-11 19:52:19 -08:00
hexkyz
1aba87ef76 Update README.md 2018-11-12 01:56:33 +00:00
hexkyz
b19e50e720 fusee: Implement DRAM training:
- Based on reverse engineered code and Peter De Schrijver's patches;
- Complemented with CTCaer's minerva_tc project.
2018-11-12 01:55:16 +00:00
SciresM
a520481168 Merge pull request #261 from HylianMedia/master
Update Changelog for 0.7.4
2018-11-09 18:14:17 -08:00
Hylian
8daa2da97c Update Changelog for 0.7.4 2018-11-09 11:26:04 -06:00
Michael Scire
bb29a2458f Bump version to 0.7.4 2018-11-08 16:36:22 -08:00
Michael Scire
ce1a6a68bf fs.mitm/loader: Fix crashes when launching too many processes. 2018-11-08 16:02:04 -08:00
Michael Scire
cf510ad9bf pm: Only register privileged processes with FS as needed 2018-11-08 05:28:52 -08:00
Michael Scire
9898a01d3b Add current branch to make dist zip name 2018-11-08 01:27:36 -08:00
Michael Scire
54a22797a7 Make libstratosphere a submodule 2018-11-08 01:24:40 -08:00
Michael Scire
5ef01edab5 Delete libstratosphere in prep for submodule 2018-11-08 01:12:30 -08:00
Michael Scire
3b8bb325e8 pm: Use non-system event for process tracking. 2018-11-07 23:43:59 -08:00
Michael Scire
6538554485 libstratosphere: add ReadOnlySystemEvent helper 2018-11-07 23:25:16 -08:00
Michael Scire
9b1a2451b0 libstratosphere: Add thread primitive, WaitableManager->RequestStop() 2018-11-07 23:25:11 -08:00
Michael Scire
e65bee0d6a libstratosphere: Implement message queues 2018-11-07 23:25:00 -08:00
Michael Scire
8426a4dc77 libstrat: Use iterators when looping deferred waitables 2018-11-07 22:59:30 -08:00
Michael Scire
147f3c690a libstrat: Significantly cleanup waitable manager result handling. 2018-11-07 22:40:19 -08:00
Michael Scire
bac81f4ccc libstrat: fix potential oob deref in WaitableManager (closes #256) 2018-11-07 19:10:04 -08:00
Michael Scire
2894989eb7 libstrat: improve waitable manager cancelsync semantics 2018-11-07 12:42:06 -08:00
Michael Scire
952ee4227d libstrat: update curthreadhandle for libnx 1.5.0 2018-11-05 22:56:04 -08:00
Michael Scire
9142e90a04 libstratosphere: Use intraprocess event signaling for new waitable management 2018-11-05 18:35:21 -08:00
Michael Scire
3ed239296a libstrat: Allow nullptr buffers if 0 size. (closes #255) 2018-11-04 21:52:53 -08:00
Michael Scire
78a47dba6d fs.mitm: Cache IStorageInterfaces, store meta on SD instead of memory. 2018-11-04 13:56:07 -08:00
Michael Scire
5d0aabaa44 fs.mitm: Fix romfs detection on SD 2018-11-04 12:48:14 -08:00
Michael Scire
e786bc7e9a fs.mitm: Only create storage interface when needed. 2018-11-04 12:45:29 -08:00
Michael Scire
158f7224a7 set.mitm: fixup NPDM json. 2018-10-31 02:07:35 -07:00
SciresM
865ca76772 Merge pull request #215 from npdmfixup/npdmfixup
Use new npdm-json format
2018-10-31 18:03:32 +09:00
SciresM
b8f93562c0 Merge branch 'master' into npdmfixup 2018-10-31 18:02:07 +09:00
Michael Scire
ef5c7d6bab Fix make dist zip to launch set_mitm. (Thanks @bakugo). 2018-10-30 16:39:20 -07:00
Michael Scire
be044e691c libstrat: delete old ipc templating. 2018-10-30 15:57:15 -07:00
TuxSH
536b89efae Add boost as submodule 2018-10-30 23:49:26 +01:00
Michael Scire
44175058f6 libstrat: mark ServiceObjectHolder functions const 2018-10-31 05:04:00 +09:00
Michael Scire
7309c7f358 atmosphere: improve makefile dependencies 2018-10-31 05:04:00 +09:00
Michael Scire
6336089b63 libstrat: remove unused struct in serializer 2018-10-31 05:04:00 +09:00
Michael Scire
6ef34d80a0 libstrat: automatically detect+format rawdata structs correctly. 2018-10-31 05:04:00 +09:00
Michael Scire
2f7224edce fs.mitm: increase thread count back to 5. 2018-10-31 05:04:00 +09:00
Michael Scire
c49cfbd6af loader: update for libstratosphere refactor 2018-10-31 05:04:00 +09:00
Michael Scire
8b71378920 atmosphere: add set.mitm to make dist target 2018-10-31 05:04:00 +09:00
Michael Scire
bbffbd654f set.mitm: Split out from fs.mitm 2018-10-31 05:04:00 +09:00
Michael Scire
4cdd9aa8f1 libstratosphere: Fix uninitialized memory bug. 2018-10-31 05:04:00 +09:00
Michael Scire
23a85a7c24 fs.mitm: split out set.mitm 2018-10-31 05:04:00 +09:00
Michael Scire
3dc679215b fs.mitm: Remove debugging options 2018-10-31 05:04:00 +09:00
Michael Scire
aef7d36300 fs.mitm: update for libstratosphere refactor 2018-10-31 05:04:00 +09:00
Michael Scire
887b4e0275 pm: update for libstratosphere refactor 2018-10-31 05:04:00 +09:00
Michael Scire
9a8c70ed68 sm: Update for libstratosphere refactor 2018-10-31 05:04:00 +09:00
Michael Scire
058f735031 libstratosphere: refactor everything 2018-10-31 05:04:00 +09:00
misson20000
5c147e5188 loader: add SetExternalContentSource extension 2018-10-29 07:11:16 +09:00
misson20000
18f51e9b2e loader: add NpdmUtils function for invalidating the cache for a specific title 2018-10-29 07:11:16 +09:00
misson20000
376feb63bd loader: make ShouldOverrideContents take a tid argument 2018-10-29 07:11:16 +09:00
Michael Scire
a502d31cd1 Add Question Issue Template 2018-10-25 13:52:55 -07:00
Michael Scire
afbf57c222 Add Feature Request Issue Template 2018-10-25 13:47:13 -07:00
Michael Scire
b62329bd5b Add bug report issue template 2018-10-25 13:42:39 -07:00
Hylian
de688ee17a Update changelog.md 2018-10-25 06:58:29 +09:00
roblabla
0938057d67 Use new npdm-json format 2018-09-29 02:37:25 +00:00
189 changed files with 15029 additions and 11618 deletions

25
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View 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?

View 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
View 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
View 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

View File

@@ -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

View File

@@ -29,7 +29,7 @@ In no particular order, we credit the following for their invaluable contributio
* __ChaN__ for the [FatFs](http://elm-chan.org/fsw/ff/00index_e.html) module.
* __Marcus Geelnard__ for the [bcl-1.2.0](https://sourceforge.net/projects/bcl/files/bcl/bcl-1.2.0) library.
* __naehrwert__ and __st4rk__ for the original [hekate](https://github.com/nwert/hekate) project and its hwinit code base.
* __CTCaer__ for the continued [hekate](https://github.com/CTCaer/hekate) project's fork.
* __CTCaer__ for the continued [hekate](https://github.com/CTCaer/hekate) project's fork and the [minerva_tc](https://github.com/CTCaer/minerva_tc) project.
* __Riley__ for suggesting "Atmosphere" as a Horizon OS reimplementation+customization project name.
* __hedgeberg__ for research and hardware testing.
* __lioncash__ for code cleanup and general improvements.

View File

@@ -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

View File

@@ -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 5
#endif

1
common/include/boost Submodule

Submodule common/include/boost added at fc6429e463

View File

@@ -1,14 +1,49 @@
# Changelog
## 0.7.5
+ DRAM training was added to fusee-secondary, courtesy @hexkyz.
+ This greatly improves the speed of memory accesses during boot, resulting in a boot time that is ~200-400% faster.
+ creport has had its code region detection improved.
+ Instead of only checking one of the crashing thread's PC/LR for code region presence, creport now checks both + every address in the stacktrace. This is also now done for every thread.
+ This matches the improvement Nintendo added to official creport in 6.1.0.
+ The code region detection heuristic was further improved by checking whether an address points to .rodata or .rwdata, instead of just .text.
+ This means that a crash appears in a loaded NRO (or otherwise discontiguous) code region, creport will be able to detect all active code regions, and not just that one.
## 0.7.4
+ [libstratosphere](https://github.com/Atmosphere-NX/libstratosphere) has been completely refactored/rewritten, and split into its own, separate submodule.
+ While this is mostly "under the hood" for end-users, the refactor is faster (improving both boot-time and runtime performance), more accurate (many of the internal IPC structures are now bug-for-bug compatible with Nintendo's implementations), and significantly more stable (it fixes a large number of bugs present in the old library).
+ The refactored API is significantly cleaner and easier to write system module code for, which should improve/speed up development of stratosphere.
+ Developers looking to write their own custom system modules for the Switch can now easily include libstratosphere as a submodule in their projects.
+ Loader was extended to add a new generic way to redirect content (ExternalContentSources), courtesy @misson20000:
+ A new command was added to ldr:shel, taking in a tid to redirect and returning a session handle.
+ When the requested TID is loading, Loader will query the handle as though it were an IFileSystem.
+ This allows clients to generically define their own filesystems, and override content with them in loader.
+ fs.mitm has gotten several optimizations that should improve its performance and stability:
+ RomFS redirection now only occurs when there is content to redirect, even if the title is being mitm'd elsewhere.
+ A cache is now maintained of the active data storage, if any, for all opened title IDs. This means if two processes both try to open the same archive, fs.mitm won't duplicate any of its work.
+ RomFS metadata is now cached to the SD card on build instead of being persisted in memory -- this greatly reduces memory footprint and allows fs.mitm to redirect more titles simultaneously than before.
+ A number of bugs were fixed, including:
+ A resource leak was fixed in process creation. This fixes crashes that occur when a large number (>32) games have been launched since the last reboot.
+ fs.mitm no longer errors when receiving a zero-sized buffer. This fixes crashes in some games, including The Messenger.
+ Multi-threaded server semantics should no longer cause deadlocks in certain circumstances. This fixes crashes in some games, including NES Classics.
+ PM now only gives full FS permissions to the active KIPs. This fixes a potential crash where new processes might be unable to be registered with FS.
+ The `make dist` target now includes the branch in the generated zip name.
+ General system stability improvements to enhance the user's experience.
## 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:

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -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;

View File

@@ -26,6 +26,7 @@
#include "loader.h"
#include "chainloader.h"
#include "stage2.h"
#include "mtc.h"
#include "nxboot.h"
#include "console.h"
#include "fs_utils.h"
@@ -52,6 +53,9 @@ static void setup_env(void) {
if (nxfs_mount_all() < 0) {
fatal_error("Failed to mount at least one parition: %s\n", strerror(errno));
}
/* Train DRAM. */
train_dram();
}
static void cleanup_env(void) {

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,759 @@
/*
* Copyright (c) 2015, NVIDIA CORPORATION. All rights reserved.
* Copyright (c) 2018 CTCaer <ctcaer@gmail.com>
* 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/>.
*/
#ifndef FUSEE_MTC_H_
#define FUSEE_MTC_H_
#include <stdint.h>
#include <stdbool.h>
#include "emc.h"
#include "mc.h"
#define MTC_TABLES_MAX_ENTRIES 10
#define MAX_PLL_CFGS 14
#define DVFS_FGCG_HIGH_SPEED_THRESHOLD 1000
#define IOBRICK_DCC_THRESHOLD 2400
#define DVFS_FGCG_MID_SPEED_THRESHOLD 600
#define TEGRA21_MAX_TABLE_ID_LEN 50
#define TEGRA_EMC_ISO_USE_FREQ_MAX_NUM 12
#define PLL_C_DIRECT_FLOOR 333500000
#define EMC_STATUS_UPDATE_TIMEOUT 1000
#define TEGRA_EMC_DEFAULT_CLK_LATENCY_US 2000
#define TEGRA_EMC_MODE_REG_17 0x00110000
#define TEGRA_EMC_MRW_DEV_SHIFT 30
#define TEGRA_EMC_MRW_DEV1 2
#define TEGRA_EMC_MRW_DEV2 1
#define EMC_CLK_EMC_2X_CLK_SRC_SHIFT 29
#define EMC_CLK_EMC_2X_CLK_SRC_MASK \
(0x7 << EMC_CLK_EMC_2X_CLK_SRC_SHIFT)
#define EMC_CLK_EMC_2X_CLK_DIVISOR_SHIFT 0
#define EMC_CLK_EMC_2X_CLK_DIVISOR_MASK \
(0xff << EMC_CLK_EMC_2X_CLK_DIVISOR_SHIFT)
enum {
REG_MC,
REG_EMC,
REG_EMC0,
REG_EMC1,
};
#define BURST_REGS_PER_CH_LIST \
{ \
DEFINE_REG(REG_EMC0, EMC_MRW10), \
DEFINE_REG(REG_EMC1, EMC_MRW10), \
DEFINE_REG(REG_EMC0, EMC_MRW11), \
DEFINE_REG(REG_EMC1, EMC_MRW11), \
DEFINE_REG(REG_EMC0, EMC_MRW12), \
DEFINE_REG(REG_EMC1, EMC_MRW12), \
DEFINE_REG(REG_EMC0, EMC_MRW13), \
DEFINE_REG(REG_EMC1, EMC_MRW13), \
}
#define BURST_REGS_LIST \
{ \
DEFINE_REG(REG_EMC, EMC_RC), \
DEFINE_REG(REG_EMC, EMC_RFC), \
DEFINE_REG(REG_EMC, EMC_RFCPB), \
DEFINE_REG(REG_EMC, EMC_REFCTRL2), \
DEFINE_REG(REG_EMC, EMC_RFC_SLR), \
DEFINE_REG(REG_EMC, EMC_RAS), \
DEFINE_REG(REG_EMC, EMC_RP), \
DEFINE_REG(REG_EMC, EMC_R2W), \
DEFINE_REG(REG_EMC, EMC_W2R), \
DEFINE_REG(REG_EMC, EMC_R2P), \
DEFINE_REG(REG_EMC, EMC_W2P), \
DEFINE_REG(REG_EMC, EMC_R2R), \
DEFINE_REG(REG_EMC, EMC_TPPD), \
DEFINE_REG(REG_EMC, EMC_CCDMW), \
DEFINE_REG(REG_EMC, EMC_RD_RCD), \
DEFINE_REG(REG_EMC, EMC_WR_RCD), \
DEFINE_REG(REG_EMC, EMC_RRD), \
DEFINE_REG(REG_EMC, EMC_REXT), \
DEFINE_REG(REG_EMC, EMC_WEXT), \
DEFINE_REG(REG_EMC, EMC_WDV_CHK), \
DEFINE_REG(REG_EMC, EMC_WDV), \
DEFINE_REG(REG_EMC, EMC_WSV), \
DEFINE_REG(REG_EMC, EMC_WEV), \
DEFINE_REG(REG_EMC, EMC_WDV_MASK), \
DEFINE_REG(REG_EMC, EMC_WS_DURATION), \
DEFINE_REG(REG_EMC, EMC_WE_DURATION), \
DEFINE_REG(REG_EMC, EMC_QUSE), \
DEFINE_REG(REG_EMC, EMC_QUSE_WIDTH), \
DEFINE_REG(REG_EMC, EMC_IBDLY), \
DEFINE_REG(REG_EMC, EMC_OBDLY), \
DEFINE_REG(REG_EMC, EMC_EINPUT), \
DEFINE_REG(REG_EMC, EMC_MRW6), \
DEFINE_REG(REG_EMC, EMC_EINPUT_DURATION), \
DEFINE_REG(REG_EMC, EMC_PUTERM_EXTRA), \
DEFINE_REG(REG_EMC, EMC_PUTERM_WIDTH), \
DEFINE_REG(REG_EMC, EMC_QRST), \
DEFINE_REG(REG_EMC, EMC_QSAFE), \
DEFINE_REG(REG_EMC, EMC_RDV), \
DEFINE_REG(REG_EMC, EMC_RDV_MASK), \
DEFINE_REG(REG_EMC, EMC_RDV_EARLY), \
DEFINE_REG(REG_EMC, EMC_RDV_EARLY_MASK), \
DEFINE_REG(REG_EMC, EMC_REFRESH), \
DEFINE_REG(REG_EMC, EMC_BURST_REFRESH_NUM), \
DEFINE_REG(REG_EMC, EMC_PRE_REFRESH_REQ_CNT), \
DEFINE_REG(REG_EMC, EMC_PDEX2WR), \
DEFINE_REG(REG_EMC, EMC_PDEX2RD), \
DEFINE_REG(REG_EMC, EMC_PCHG2PDEN), \
DEFINE_REG(REG_EMC, EMC_ACT2PDEN), \
DEFINE_REG(REG_EMC, EMC_AR2PDEN), \
DEFINE_REG(REG_EMC, EMC_RW2PDEN), \
DEFINE_REG(REG_EMC, EMC_CKE2PDEN), \
DEFINE_REG(REG_EMC, EMC_PDEX2CKE), \
DEFINE_REG(REG_EMC, EMC_PDEX2MRR), \
DEFINE_REG(REG_EMC, EMC_TXSR), \
DEFINE_REG(REG_EMC, EMC_TXSRDLL), \
DEFINE_REG(REG_EMC, EMC_TCKE), \
DEFINE_REG(REG_EMC, EMC_TCKESR), \
DEFINE_REG(REG_EMC, EMC_TPD), \
DEFINE_REG(REG_EMC, EMC_TFAW), \
DEFINE_REG(REG_EMC, EMC_TRPAB), \
DEFINE_REG(REG_EMC, EMC_TCLKSTABLE), \
DEFINE_REG(REG_EMC, EMC_TCLKSTOP), \
DEFINE_REG(REG_EMC, EMC_MRW7), \
DEFINE_REG(REG_EMC, EMC_TREFBW), \
DEFINE_REG(REG_EMC, EMC_ODT_WRITE), \
DEFINE_REG(REG_EMC, EMC_FBIO_CFG5), \
DEFINE_REG(REG_EMC, EMC_FBIO_CFG7), \
DEFINE_REG(REG_EMC, EMC_CFG_DIG_DLL), \
DEFINE_REG(REG_EMC, EMC_CFG_DIG_DLL_PERIOD), \
DEFINE_REG(REG_EMC, EMC_PMACRO_IB_RXRT), \
DEFINE_REG(REG_EMC, EMC_CFG_PIPE_1), \
DEFINE_REG(REG_EMC, EMC_CFG_PIPE_2), \
DEFINE_REG(REG_EMC, EMC_PMACRO_QUSE_DDLL_RANK0_4), \
DEFINE_REG(REG_EMC, EMC_PMACRO_QUSE_DDLL_RANK0_5), \
DEFINE_REG(REG_EMC, EMC_PMACRO_QUSE_DDLL_RANK1_4), \
DEFINE_REG(REG_EMC, EMC_PMACRO_QUSE_DDLL_RANK1_5), \
DEFINE_REG(REG_EMC, EMC_MRW8), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_4), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_5), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_0), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_1), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_2), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_3), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_4), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_5), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_0), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_1), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_2), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_3), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_4), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_5), \
DEFINE_REG(REG_EMC, EMC_PMACRO_DDLL_LONG_CMD_0), \
DEFINE_REG(REG_EMC, EMC_PMACRO_DDLL_LONG_CMD_1), \
DEFINE_REG(REG_EMC, EMC_PMACRO_DDLL_LONG_CMD_2), \
DEFINE_REG(REG_EMC, EMC_PMACRO_DDLL_LONG_CMD_3), \
DEFINE_REG(REG_EMC, EMC_PMACRO_DDLL_LONG_CMD_4), \
DEFINE_REG(REG_EMC, EMC_PMACRO_DDLL_SHORT_CMD_0), \
DEFINE_REG(REG_EMC, EMC_PMACRO_DDLL_SHORT_CMD_1), \
DEFINE_REG(REG_EMC, EMC_PMACRO_DDLL_SHORT_CMD_2), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE0_3), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE1_3), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE2_3), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE3_3), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE4_3), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE5_3), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE6_3), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE7_3), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD0_3), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD1_3), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD2_3), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD3_3), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE0_3), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE1_3), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE2_3), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE3_3), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE4_3), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE5_3), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE6_3), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE7_3), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD0_0), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD0_1), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD0_2), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD0_3), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD1_0), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD1_1), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD1_2), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD1_3), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD2_0), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD2_1), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD2_2), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD2_3), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD3_0), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD3_1), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD3_2), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD3_3), \
DEFINE_REG(REG_EMC, EMC_TXDSRVTTGEN), \
DEFINE_REG(REG_EMC, EMC_FDPD_CTRL_DQ), \
DEFINE_REG(REG_EMC, EMC_FDPD_CTRL_CMD), \
DEFINE_REG(REG_EMC, EMC_FBIO_SPARE), \
DEFINE_REG(REG_EMC, EMC_ZCAL_INTERVAL), \
DEFINE_REG(REG_EMC, EMC_ZCAL_WAIT_CNT), \
DEFINE_REG(REG_EMC, EMC_MRS_WAIT_CNT), \
DEFINE_REG(REG_EMC, EMC_MRS_WAIT_CNT2), \
DEFINE_REG(REG_EMC, EMC_AUTO_CAL_CHANNEL), \
DEFINE_REG(REG_EMC, EMC_DLL_CFG_0), \
DEFINE_REG(REG_EMC, EMC_DLL_CFG_1), \
DEFINE_REG(REG_EMC, EMC_PMACRO_AUTOCAL_CFG_COMMON), \
DEFINE_REG(REG_EMC, EMC_PMACRO_ZCTRL), \
DEFINE_REG(REG_EMC, EMC_CFG), \
DEFINE_REG(REG_EMC, EMC_CFG_PIPE), \
DEFINE_REG(REG_EMC, EMC_DYN_SELF_REF_CONTROL), \
DEFINE_REG(REG_EMC, EMC_QPOP), \
DEFINE_REG(REG_EMC, EMC_DQS_BRLSHFT_0), \
DEFINE_REG(REG_EMC, EMC_DQS_BRLSHFT_1), \
DEFINE_REG(REG_EMC, EMC_CMD_BRLSHFT_2), \
DEFINE_REG(REG_EMC, EMC_CMD_BRLSHFT_3), \
DEFINE_REG(REG_EMC, EMC_PMACRO_PAD_CFG_CTRL), \
DEFINE_REG(REG_EMC, EMC_PMACRO_DATA_PAD_RX_CTRL), \
DEFINE_REG(REG_EMC, EMC_PMACRO_CMD_PAD_RX_CTRL), \
DEFINE_REG(REG_EMC, EMC_PMACRO_DATA_RX_TERM_MODE), \
DEFINE_REG(REG_EMC, EMC_PMACRO_CMD_RX_TERM_MODE), \
DEFINE_REG(REG_EMC, EMC_PMACRO_CMD_PAD_TX_CTRL), \
DEFINE_REG(REG_EMC, EMC_PMACRO_DATA_PAD_TX_CTRL), \
DEFINE_REG(REG_EMC, EMC_PMACRO_COMMON_PAD_TX_CTRL), \
DEFINE_REG(REG_EMC, EMC_PMACRO_VTTGEN_CTRL_0), \
DEFINE_REG(REG_EMC, EMC_PMACRO_VTTGEN_CTRL_1), \
DEFINE_REG(REG_EMC, EMC_PMACRO_VTTGEN_CTRL_2), \
DEFINE_REG(REG_EMC, EMC_PMACRO_BRICK_CTRL_RFU1), \
DEFINE_REG(REG_EMC, EMC_PMACRO_CMD_BRICK_CTRL_FDPD), \
DEFINE_REG(REG_EMC, EMC_PMACRO_BRICK_CTRL_RFU2), \
DEFINE_REG(REG_EMC, EMC_PMACRO_DATA_BRICK_CTRL_FDPD), \
DEFINE_REG(REG_EMC, EMC_PMACRO_BG_BIAS_CTRL_0), \
DEFINE_REG(REG_EMC, EMC_CFG_3), \
DEFINE_REG(REG_EMC, EMC_PMACRO_TX_PWRD_0), \
DEFINE_REG(REG_EMC, EMC_PMACRO_TX_PWRD_1), \
DEFINE_REG(REG_EMC, EMC_PMACRO_TX_PWRD_2), \
DEFINE_REG(REG_EMC, EMC_PMACRO_TX_PWRD_3), \
DEFINE_REG(REG_EMC, EMC_PMACRO_TX_PWRD_4), \
DEFINE_REG(REG_EMC, EMC_PMACRO_TX_PWRD_5), \
DEFINE_REG(REG_EMC, EMC_CONFIG_SAMPLE_DELAY), \
DEFINE_REG(REG_EMC, EMC_PMACRO_TX_SEL_CLK_SRC_0), \
DEFINE_REG(REG_EMC, EMC_PMACRO_TX_SEL_CLK_SRC_1), \
DEFINE_REG(REG_EMC, EMC_PMACRO_TX_SEL_CLK_SRC_2), \
DEFINE_REG(REG_EMC, EMC_PMACRO_TX_SEL_CLK_SRC_3), \
DEFINE_REG(REG_EMC, EMC_PMACRO_TX_SEL_CLK_SRC_4), \
DEFINE_REG(REG_EMC, EMC_PMACRO_TX_SEL_CLK_SRC_5), \
DEFINE_REG(REG_EMC, EMC_PMACRO_DDLL_BYPASS), \
DEFINE_REG(REG_EMC, EMC_PMACRO_DDLL_PWRD_0), \
DEFINE_REG(REG_EMC, EMC_PMACRO_DDLL_PWRD_1), \
DEFINE_REG(REG_EMC, EMC_PMACRO_DDLL_PWRD_2), \
DEFINE_REG(REG_EMC, EMC_PMACRO_CMD_CTRL_0), \
DEFINE_REG(REG_EMC, EMC_PMACRO_CMD_CTRL_1), \
DEFINE_REG(REG_EMC, EMC_PMACRO_CMD_CTRL_2), \
DEFINE_REG(REG_EMC, EMC_TR_TIMING_0), \
DEFINE_REG(REG_EMC, EMC_TR_DVFS), \
DEFINE_REG(REG_EMC, EMC_TR_CTRL_1), \
DEFINE_REG(REG_EMC, EMC_TR_RDV), \
DEFINE_REG(REG_EMC, EMC_TR_QPOP), \
DEFINE_REG(REG_EMC, EMC_TR_RDV_MASK), \
DEFINE_REG(REG_EMC, EMC_MRW14), \
DEFINE_REG(REG_EMC, EMC_TR_QSAFE), \
DEFINE_REG(REG_EMC, EMC_TR_QRST), \
DEFINE_REG(REG_EMC, EMC_TRAINING_CTRL), \
DEFINE_REG(REG_EMC, EMC_TRAINING_SETTLE), \
DEFINE_REG(REG_EMC, EMC_TRAINING_VREF_SETTLE), \
DEFINE_REG(REG_EMC, EMC_TRAINING_CA_FINE_CTRL), \
DEFINE_REG(REG_EMC, EMC_TRAINING_CA_CTRL_MISC), \
DEFINE_REG(REG_EMC, EMC_TRAINING_CA_CTRL_MISC1), \
DEFINE_REG(REG_EMC, EMC_TRAINING_CA_VREF_CTRL), \
DEFINE_REG(REG_EMC, EMC_TRAINING_QUSE_CORS_CTRL), \
DEFINE_REG(REG_EMC, EMC_TRAINING_QUSE_FINE_CTRL), \
DEFINE_REG(REG_EMC, EMC_TRAINING_QUSE_CTRL_MISC), \
DEFINE_REG(REG_EMC, EMC_TRAINING_QUSE_VREF_CTRL), \
DEFINE_REG(REG_EMC, EMC_TRAINING_READ_FINE_CTRL), \
DEFINE_REG(REG_EMC, EMC_TRAINING_READ_CTRL_MISC), \
DEFINE_REG(REG_EMC, EMC_TRAINING_READ_VREF_CTRL), \
DEFINE_REG(REG_EMC, EMC_TRAINING_WRITE_FINE_CTRL), \
DEFINE_REG(REG_EMC, EMC_TRAINING_WRITE_CTRL_MISC), \
DEFINE_REG(REG_EMC, EMC_TRAINING_WRITE_VREF_CTRL), \
DEFINE_REG(REG_EMC, EMC_TRAINING_MPC), \
DEFINE_REG(REG_EMC, EMC_MRW15), \
}
#define TRIM_REGS_PER_CH_LIST \
{ \
DEFINE_REG(REG_EMC0, EMC_CMD_BRLSHFT_0), \
DEFINE_REG(REG_EMC1, EMC_CMD_BRLSHFT_1), \
DEFINE_REG(REG_EMC0, EMC_DATA_BRLSHFT_0), \
DEFINE_REG(REG_EMC1, EMC_DATA_BRLSHFT_0), \
DEFINE_REG(REG_EMC0, EMC_DATA_BRLSHFT_1), \
DEFINE_REG(REG_EMC1, EMC_DATA_BRLSHFT_1), \
DEFINE_REG(REG_EMC0, EMC_QUSE_BRLSHFT_0), \
DEFINE_REG(REG_EMC1, EMC_QUSE_BRLSHFT_1), \
DEFINE_REG(REG_EMC0, EMC_QUSE_BRLSHFT_2), \
DEFINE_REG(REG_EMC1, EMC_QUSE_BRLSHFT_3), \
}
#define TRIM_REGS_LIST \
{ \
DEFINE_REG(REG_EMC, EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_0), \
DEFINE_REG(REG_EMC, EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_1), \
DEFINE_REG(REG_EMC, EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_2), \
DEFINE_REG(REG_EMC, EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_3), \
DEFINE_REG(REG_EMC, EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_0), \
DEFINE_REG(REG_EMC, EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_1), \
DEFINE_REG(REG_EMC, EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_2), \
DEFINE_REG(REG_EMC, EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_3), \
DEFINE_REG(REG_EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE0_0), \
DEFINE_REG(REG_EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE0_1), \
DEFINE_REG(REG_EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE0_2), \
DEFINE_REG(REG_EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE1_0), \
DEFINE_REG(REG_EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE1_1), \
DEFINE_REG(REG_EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE1_2), \
DEFINE_REG(REG_EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE2_0), \
DEFINE_REG(REG_EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE2_1), \
DEFINE_REG(REG_EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE2_2), \
DEFINE_REG(REG_EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE3_0), \
DEFINE_REG(REG_EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE3_1), \
DEFINE_REG(REG_EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE3_2), \
DEFINE_REG(REG_EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE4_0), \
DEFINE_REG(REG_EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE4_1), \
DEFINE_REG(REG_EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE4_2), \
DEFINE_REG(REG_EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE5_0), \
DEFINE_REG(REG_EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE5_1), \
DEFINE_REG(REG_EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE5_2), \
DEFINE_REG(REG_EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE6_0), \
DEFINE_REG(REG_EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE6_1), \
DEFINE_REG(REG_EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE6_2), \
DEFINE_REG(REG_EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE7_0), \
DEFINE_REG(REG_EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE7_1), \
DEFINE_REG(REG_EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE7_2), \
DEFINE_REG(REG_EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE0_0), \
DEFINE_REG(REG_EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE0_1), \
DEFINE_REG(REG_EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE0_2), \
DEFINE_REG(REG_EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE1_0), \
DEFINE_REG(REG_EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE1_1), \
DEFINE_REG(REG_EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE1_2), \
DEFINE_REG(REG_EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE2_0), \
DEFINE_REG(REG_EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE2_1), \
DEFINE_REG(REG_EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE2_2), \
DEFINE_REG(REG_EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE3_0), \
DEFINE_REG(REG_EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE3_1), \
DEFINE_REG(REG_EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE3_2), \
DEFINE_REG(REG_EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE4_0), \
DEFINE_REG(REG_EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE4_1), \
DEFINE_REG(REG_EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE4_2), \
DEFINE_REG(REG_EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE5_0), \
DEFINE_REG(REG_EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE5_1), \
DEFINE_REG(REG_EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE5_2), \
DEFINE_REG(REG_EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE6_0), \
DEFINE_REG(REG_EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE6_1), \
DEFINE_REG(REG_EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE6_2), \
DEFINE_REG(REG_EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE7_0), \
DEFINE_REG(REG_EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE7_1), \
DEFINE_REG(REG_EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE7_2), \
DEFINE_REG(REG_EMC, EMC_PMACRO_IB_VREF_DQS_0), \
DEFINE_REG(REG_EMC, EMC_PMACRO_IB_VREF_DQS_1), \
DEFINE_REG(REG_EMC, EMC_PMACRO_IB_VREF_DQ_0), \
DEFINE_REG(REG_EMC, EMC_PMACRO_IB_VREF_DQ_1), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_2), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_3), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_4), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_5), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_0), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_1), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_2), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_3), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE0_0), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE0_1), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE0_2), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE1_0), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE1_1), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE1_2), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE2_0), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE2_1), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE2_2), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE3_0), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE3_1), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE3_2), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE4_0), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE4_1), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE4_2), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE5_0), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE5_1), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE5_2), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE6_0), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE6_1), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE6_2), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE7_0), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE7_1), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE7_2), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD0_0), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD0_1), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD0_2), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD1_0), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD1_1), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD1_2), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD2_0), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD2_1), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD2_2), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD3_0), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD3_1), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD3_2), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE0_0), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE0_1), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE0_2), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE1_0), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE1_1), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE1_2), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE2_0), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE2_1), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE2_2), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE3_0), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE3_1), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE3_2), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE4_0), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE4_1), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE4_2), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE5_0), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE5_1), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE5_2), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE6_0), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE6_1), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE6_2), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE7_0), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE7_1), \
DEFINE_REG(REG_EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE7_2), \
DEFINE_REG(REG_EMC, EMC_PMACRO_QUSE_DDLL_RANK0_0), \
DEFINE_REG(REG_EMC, EMC_PMACRO_QUSE_DDLL_RANK0_1), \
DEFINE_REG(REG_EMC, EMC_PMACRO_QUSE_DDLL_RANK0_2), \
DEFINE_REG(REG_EMC, EMC_PMACRO_QUSE_DDLL_RANK0_3), \
DEFINE_REG(REG_EMC, EMC_PMACRO_QUSE_DDLL_RANK1_0), \
DEFINE_REG(REG_EMC, EMC_PMACRO_QUSE_DDLL_RANK1_1), \
DEFINE_REG(REG_EMC, EMC_PMACRO_QUSE_DDLL_RANK1_2), \
DEFINE_REG(REG_EMC, EMC_PMACRO_QUSE_DDLL_RANK1_3), \
}
#define VREF_REGS_PER_CH_LIST \
{ \
DEFINE_REG(REG_EMC0, EMC_TRAINING_OPT_DQS_IB_VREF_RANK0), \
DEFINE_REG(REG_EMC1, EMC_TRAINING_OPT_DQS_IB_VREF_RANK0), \
DEFINE_REG(REG_EMC0, EMC_TRAINING_OPT_DQS_IB_VREF_RANK1), \
DEFINE_REG(REG_EMC1, EMC_TRAINING_OPT_DQS_IB_VREF_RANK1), \
}
#define TRAINING_MOD_REGS_PER_CH_LIST \
{ \
DEFINE_REG(REG_EMC0, EMC_TRAINING_RW_OFFSET_IB_BYTE0), \
DEFINE_REG(REG_EMC1, EMC_TRAINING_RW_OFFSET_IB_BYTE0), \
DEFINE_REG(REG_EMC0, EMC_TRAINING_RW_OFFSET_IB_BYTE1), \
DEFINE_REG(REG_EMC1, EMC_TRAINING_RW_OFFSET_IB_BYTE1), \
DEFINE_REG(REG_EMC0, EMC_TRAINING_RW_OFFSET_IB_BYTE2), \
DEFINE_REG(REG_EMC1, EMC_TRAINING_RW_OFFSET_IB_BYTE2), \
DEFINE_REG(REG_EMC0, EMC_TRAINING_RW_OFFSET_IB_BYTE3), \
DEFINE_REG(REG_EMC1, EMC_TRAINING_RW_OFFSET_IB_BYTE3), \
DEFINE_REG(REG_EMC0, EMC_TRAINING_RW_OFFSET_IB_MISC), \
DEFINE_REG(REG_EMC1, EMC_TRAINING_RW_OFFSET_IB_MISC), \
DEFINE_REG(REG_EMC0, EMC_TRAINING_RW_OFFSET_OB_BYTE0), \
DEFINE_REG(REG_EMC1, EMC_TRAINING_RW_OFFSET_OB_BYTE0), \
DEFINE_REG(REG_EMC0, EMC_TRAINING_RW_OFFSET_OB_BYTE1), \
DEFINE_REG(REG_EMC1, EMC_TRAINING_RW_OFFSET_OB_BYTE1), \
DEFINE_REG(REG_EMC0, EMC_TRAINING_RW_OFFSET_OB_BYTE2), \
DEFINE_REG(REG_EMC1, EMC_TRAINING_RW_OFFSET_OB_BYTE2), \
DEFINE_REG(REG_EMC0, EMC_TRAINING_RW_OFFSET_OB_BYTE3), \
DEFINE_REG(REG_EMC1, EMC_TRAINING_RW_OFFSET_OB_BYTE3), \
DEFINE_REG(REG_EMC0, EMC_TRAINING_RW_OFFSET_OB_MISC), \
DEFINE_REG(REG_EMC1, EMC_TRAINING_RW_OFFSET_OB_MISC), \
}
#define BURST_MC_REGS_LIST \
{ \
DEFINE_REG(REG_MC, MC_EMEM_ARB_CFG), \
DEFINE_REG(REG_MC, MC_EMEM_ARB_OUTSTANDING_REQ), \
DEFINE_REG(REG_MC, MC_EMEM_ARB_REFPB_HP_CTRL), \
DEFINE_REG(REG_MC, MC_EMEM_ARB_REFPB_BANK_CTRL), \
DEFINE_REG(REG_MC, MC_EMEM_ARB_TIMING_RCD), \
DEFINE_REG(REG_MC, MC_EMEM_ARB_TIMING_RP), \
DEFINE_REG(REG_MC, MC_EMEM_ARB_TIMING_RC), \
DEFINE_REG(REG_MC, MC_EMEM_ARB_TIMING_RAS), \
DEFINE_REG(REG_MC, MC_EMEM_ARB_TIMING_FAW), \
DEFINE_REG(REG_MC, MC_EMEM_ARB_TIMING_RRD), \
DEFINE_REG(REG_MC, MC_EMEM_ARB_TIMING_RAP2PRE), \
DEFINE_REG(REG_MC, MC_EMEM_ARB_TIMING_WAP2PRE), \
DEFINE_REG(REG_MC, MC_EMEM_ARB_TIMING_R2R), \
DEFINE_REG(REG_MC, MC_EMEM_ARB_TIMING_W2W), \
DEFINE_REG(REG_MC, MC_EMEM_ARB_TIMING_R2W), \
DEFINE_REG(REG_MC, MC_EMEM_ARB_TIMING_CCDMW), \
DEFINE_REG(REG_MC, MC_EMEM_ARB_TIMING_W2R), \
DEFINE_REG(REG_MC, MC_EMEM_ARB_TIMING_RFCPB), \
DEFINE_REG(REG_MC, MC_EMEM_ARB_DA_TURNS), \
DEFINE_REG(REG_MC, MC_EMEM_ARB_DA_COVERS), \
DEFINE_REG(REG_MC, MC_EMEM_ARB_MISC0), \
DEFINE_REG(REG_MC, MC_EMEM_ARB_MISC1), \
DEFINE_REG(REG_MC, MC_EMEM_ARB_MISC2), \
DEFINE_REG(REG_MC, MC_EMEM_ARB_RING1_THROTTLE), \
DEFINE_REG(REG_MC, MC_EMEM_ARB_DHYST_CTRL), \
DEFINE_REG(REG_MC, MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_0), \
DEFINE_REG(REG_MC, MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_1), \
DEFINE_REG(REG_MC, MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_2), \
DEFINE_REG(REG_MC, MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_3), \
DEFINE_REG(REG_MC, MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_4), \
DEFINE_REG(REG_MC, MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_5), \
DEFINE_REG(REG_MC, MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_6), \
DEFINE_REG(REG_MC, MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_7), \
}
#define BURST_UP_DOWN_REGS_LIST \
{ \
DEFINE_REG(REG_MC, MC_MLL_MPCORER_PTSA_RATE), \
DEFINE_REG(REG_MC, MC_FTOP_PTSA_RATE), \
DEFINE_REG(REG_MC, MC_PTSA_GRANT_DECREMENT), \
DEFINE_REG(REG_MC, MC_LATENCY_ALLOWANCE_XUSB_0), \
DEFINE_REG(REG_MC, MC_LATENCY_ALLOWANCE_XUSB_1), \
DEFINE_REG(REG_MC, MC_LATENCY_ALLOWANCE_TSEC_0), \
DEFINE_REG(REG_MC, MC_LATENCY_ALLOWANCE_SDMMCA_0), \
DEFINE_REG(REG_MC, MC_LATENCY_ALLOWANCE_SDMMCAA_0), \
DEFINE_REG(REG_MC, MC_LATENCY_ALLOWANCE_SDMMC_0), \
DEFINE_REG(REG_MC, MC_LATENCY_ALLOWANCE_SDMMCAB_0), \
DEFINE_REG(REG_MC, MC_LATENCY_ALLOWANCE_PPCS_0), \
DEFINE_REG(REG_MC, MC_LATENCY_ALLOWANCE_PPCS_1), \
DEFINE_REG(REG_MC, MC_LATENCY_ALLOWANCE_MPCORE_0), \
DEFINE_REG(REG_MC, MC_LATENCY_ALLOWANCE_HC_0), \
DEFINE_REG(REG_MC, MC_LATENCY_ALLOWANCE_HC_1), \
DEFINE_REG(REG_MC, MC_LATENCY_ALLOWANCE_AVPC_0), \
DEFINE_REG(REG_MC, MC_LATENCY_ALLOWANCE_GPU_0), \
DEFINE_REG(REG_MC, MC_LATENCY_ALLOWANCE_GPU2_0), \
DEFINE_REG(REG_MC, MC_LATENCY_ALLOWANCE_NVENC_0), \
DEFINE_REG(REG_MC, MC_LATENCY_ALLOWANCE_NVDEC_0), \
DEFINE_REG(REG_MC, MC_LATENCY_ALLOWANCE_VIC_0), \
DEFINE_REG(REG_MC, MC_LATENCY_ALLOWANCE_VI2_0), \
DEFINE_REG(REG_MC, MC_LATENCY_ALLOWANCE_ISP2_0), \
DEFINE_REG(REG_MC, MC_LATENCY_ALLOWANCE_ISP2_1), \
}
#define DEFINE_REG(type, reg) reg##_INDEX
enum BURST_REGS_LIST;
enum TRIM_REGS_LIST;
enum BURST_MC_REGS_LIST;
enum BURST_UP_DOWN_REGS_LIST;
#undef DEFINE_REG
#define DEFINE_REG(type, reg) type##_##reg##_INDEX
enum BURST_REGS_PER_CH_LIST;
enum TRIM_REGS_PER_CH_LIST;
enum VREF_REGS_PER_CH_LIST;
enum TRAINING_MOD_REGS_PER_CH_LIST;
#undef DEFINE_REG
typedef struct {
uint32_t rev;
char dvfs_ver[60];
uint32_t rate;
uint32_t min_volt;
uint32_t gpu_min_volt;
char clock_src[32];
uint32_t clk_src_emc;
uint32_t needs_training;
uint32_t training_pattern;
uint32_t trained;
uint32_t periodic_training;
uint32_t trained_dram_clktree_c0d0u0;
uint32_t trained_dram_clktree_c0d0u1;
uint32_t trained_dram_clktree_c0d1u0;
uint32_t trained_dram_clktree_c0d1u1;
uint32_t trained_dram_clktree_c1d0u0;
uint32_t trained_dram_clktree_c1d0u1;
uint32_t trained_dram_clktree_c1d1u0;
uint32_t trained_dram_clktree_c1d1u1;
uint32_t current_dram_clktree_c0d0u0;
uint32_t current_dram_clktree_c0d0u1;
uint32_t current_dram_clktree_c0d1u0;
uint32_t current_dram_clktree_c0d1u1;
uint32_t current_dram_clktree_c1d0u0;
uint32_t current_dram_clktree_c1d0u1;
uint32_t current_dram_clktree_c1d1u0;
uint32_t current_dram_clktree_c1d1u1;
uint32_t run_clocks;
uint32_t tree_margin;
uint32_t num_burst;
uint32_t num_burst_per_ch;
uint32_t num_trim;
uint32_t num_trim_per_ch;
uint32_t num_mc_regs;
uint32_t num_up_down;
uint32_t vref_num;
uint32_t training_mod_num;
uint32_t dram_timing_num;
uint32_t ptfv_list[12];
uint32_t burst_regs[221];
uint32_t burst_reg_per_ch[8];
uint32_t shadow_regs_ca_train[221];
uint32_t shadow_regs_quse_train[221];
uint32_t shadow_regs_rdwr_train[221];
uint32_t trim_regs[138];
uint32_t trim_perch_regs[10];
uint32_t vref_perch_regs[4];
uint32_t dram_timings[5];
uint32_t training_mod_regs[20];
uint32_t save_restore_mod_regs[12];
uint32_t burst_mc_regs[33];
uint32_t la_scale_regs[24];
uint32_t min_mrs_wait;
uint32_t emc_mrw;
uint32_t emc_mrw2;
uint32_t emc_mrw3;
uint32_t emc_mrw4;
uint32_t emc_mrw9;
uint32_t emc_mrs;
uint32_t emc_emrs;
uint32_t emc_emrs2;
uint32_t emc_auto_cal_config;
uint32_t emc_auto_cal_config2;
uint32_t emc_auto_cal_config3;
uint32_t emc_auto_cal_config4;
uint32_t emc_auto_cal_config5;
uint32_t emc_auto_cal_config6;
uint32_t emc_auto_cal_config7;
uint32_t emc_auto_cal_config8;
uint32_t emc_cfg_2;
uint32_t emc_sel_dpd_ctrl;
uint32_t emc_fdpd_ctrl_cmd_no_ramp;
uint32_t dll_clk_src;
uint32_t clk_out_enb_x_0_clk_enb_emc_dll;
uint32_t latency;
} tegra_emc_timing_t;
typedef struct {
uint32_t osc_freq;
uint32_t out_freq;
uint32_t feedback_div;
uint32_t input_div;
uint32_t post_div;
} pll_cfg_t;
typedef enum {
OP_SWITCH = 0,
OP_TRAIN = 1,
OP_TRAIN_SWITCH = 2
} TrainMode;
typedef enum {
TEGRA_EMC_SRC_PLLM,
TEGRA_EMC_SRC_PLLC,
TEGRA_EMC_SRC_PLLP,
TEGRA_EMC_SRC_CLKM,
TEGRA_EMC_SRC_PLLM_UD,
TEGRA_EMC_SRC_PLLMB_UD,
TEGRA_EMC_SRC_PLLMB,
TEGRA_EMC_SRC_PLLP_UD,
TEGRA_EMC_SRC_COUNT,
} EmcSource;
enum {
DRAM_TYPE_DDR3 = 0,
DRAM_TYPE_LPDDR4 = 1,
DRAM_TYPE_LPDDR2 = 2,
DRAM_TYPE_DDR2 = 3,
};
enum {
DLL_CHANGE_NONE = 0,
DLL_CHANGE_ON,
DLL_CHANGE_OFF,
};
enum {
DLL_OFF,
DLL_ON
};
enum {
AUTO_PD = 0,
MAN_SR = 2
};
enum {
ASSEMBLY = 0,
ACTIVE
};
enum {
T_RP = 0,
T_FC_LPDDR4,
T_RFC,
T_PDEX,
RL
};
enum {
ONE_RANK = 1,
TWO_RANK = 2
};
enum {
SINGLE_CHANNEL = 0,
DUAL_CHANNEL
};
enum {
DRAM_DEV_SEL_ALL = 0,
DRAM_DEV_SEL_0 = (2 << 30),
DRAM_DEV_SEL_1 = (1 << 30),
};
enum {
EMC_CFG5_QUSE_MODE_NORMAL = 0,
EMC_CFG5_QUSE_MODE_ALWAYS_ON,
EMC_CFG5_QUSE_MODE_INTERNAL_LPBK,
EMC_CFG5_QUSE_MODE_PULSE_INTERN,
EMC_CFG5_QUSE_MODE_PULSE_EXTERN,
EMC_CFG5_QUSE_MODE_DIRECT_QUSE,
};
enum {
DVFS_SEQUENCE = 1,
WRITE_TRAINING_SEQUENCE = 2,
PERIODIC_TRAINING_SEQUENCE = 3,
DVFS_PT1 = 10,
DVFS_UPDATE = 11,
TRAINING_PT1 = 12,
TRAINING_UPDATE = 13,
PERIODIC_TRAINING_UPDATE = 14
};
enum {
TEGRA_DRAM_OVER_TEMP_NONE = 0,
TEGRA_DRAM_OVER_TEMP_REFRESH_X2,
TEGRA_DRAM_OVER_TEMP_REFRESH_X4,
TEGRA_DRAM_OVER_TEMP_THROTTLE,
TEGRA_DRAM_OVER_TEMP_MAX,
};
/* Train all possible DRAM sequences. */
void train_dram();
#endif

File diff suppressed because it is too large Load Diff

View File

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

View File

@@ -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
]
}
]
}

View File

@@ -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
]
}
]
}

View File

@@ -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) {

View File

@@ -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
}
}
]
}

View File

@@ -32,15 +32,37 @@ void CodeList::SaveToFile(FILE *f_report) {
}
}
void CodeList::ReadCodeRegionsFromProcess(Handle debug_handle, u64 pc, u64 lr) {
void CodeList::ReadCodeRegionsFromThreadInfo(Handle debug_handle, const ThreadInfo *thread) {
u64 code_base;
/* Guess that either PC or LR will point to a code region. This could be false. */
if (!TryFindCodeRegion(debug_handle, pc, &code_base) && !TryFindCodeRegion(debug_handle, lr, &code_base)) {
return;
/* Try to add the thread's PC. */
if (TryFindCodeRegion(debug_handle, thread->GetPC(), &code_base)) {
AddCodeRegion(debug_handle, code_base);
}
u64 cur_ptr = code_base;
/* Try to add the thread's LR. */
if (TryFindCodeRegion(debug_handle, thread->GetLR(), &code_base)) {
AddCodeRegion(debug_handle, code_base);
}
/* Try to add all the addresses in the thread's stacktrace. */
for (u32 i = 0; i < thread->GetStackTraceSize(); i++) {
if (TryFindCodeRegion(debug_handle, thread->GetStackTrace(i), &code_base)) {
AddCodeRegion(debug_handle, code_base);
}
}
}
void CodeList::AddCodeRegion(u64 debug_handle, u64 code_address) {
/* Check whether we already have this code region. */
for (size_t i = 0; i < this->code_count; i++) {
if (this->code_infos[i].start_address <= code_address && code_address < this->code_infos[i].end_address) {
return;
}
}
/* Add all contiguous code regions. */
u64 cur_ptr = code_address;
while (this->code_count < max_code_count) {
MemoryInfo mi;
u32 pi;
@@ -80,7 +102,25 @@ void CodeList::ReadCodeRegionsFromProcess(Handle debug_handle, u64 pc, u64 lr) {
bool CodeList::TryFindCodeRegion(Handle debug_handle, u64 guess, u64 *address) {
MemoryInfo mi;
u32 pi;
if (R_FAILED(svcQueryDebugProcessMemory(&mi, &pi, debug_handle, guess)) || mi.perm != Perm_Rx) {
if (R_FAILED(svcQueryDebugProcessMemory(&mi, &pi, debug_handle, guess))) {
return false;
}
if (mi.perm == Perm_Rw) {
guess = mi.addr - 4;
if (R_FAILED(svcQueryDebugProcessMemory(&mi, &pi, debug_handle, guess))) {
return false;
}
}
if (mi.perm == Perm_R) {
guess = mi.addr - 4;
if (R_FAILED(svcQueryDebugProcessMemory(&mi, &pi, debug_handle, guess))) {
return false;
}
}
if (mi.perm != Perm_Rx) {
return false;
}

View File

@@ -19,6 +19,7 @@
#include <cstdio>
#include "creport_debug_types.hpp"
#include "creport_thread_info.hpp"
struct CodeInfo {
char name[0x20];
@@ -29,18 +30,19 @@ struct CodeInfo {
class CodeList {
private:
static const size_t max_code_count = 0x10;
static const size_t max_code_count = 0x60;
u32 code_count = 0;
CodeInfo code_infos[max_code_count];
/* For pretty-printing. */
char address_str_buf[0x280];
public:
void ReadCodeRegionsFromProcess(Handle debug_handle, u64 pc, u64 lr);
void ReadCodeRegionsFromThreadInfo(Handle debug_handle, const ThreadInfo *thread);
const char *GetFormattedAddressString(u64 address);
void SaveToFile(FILE *f_report);
private:
bool TryFindCodeRegion(Handle debug_handle, u64 guess, u64 *address);
void AddCodeRegion(u64 debug_handle, u64 code_address);
void GetCodeInfoName(u64 debug_handle, u64 rx_address, u64 ro_address, char *name);
void GetCodeInfoBuildId(u64 debug_handle, u64 ro_address, u8 *build_id);
};

View File

@@ -27,7 +27,7 @@ void CrashReport::BuildReport(u64 pid, bool has_extra_info) {
this->has_extra_info = has_extra_info;
if (OpenProcess(pid)) {
ProcessExceptions();
this->code_list.ReadCodeRegionsFromProcess(this->debug_handle, this->crashed_thread_info.GetPC(), this->crashed_thread_info.GetLR());
this->code_list.ReadCodeRegionsFromThreadInfo(this->debug_handle, &this->crashed_thread_info);
this->thread_list.ReadThreadsFromProcess(this->debug_handle, Is64Bit());
this->crashed_thread_info.SetCodeList(&this->code_list);
this->thread_list.SetCodeList(&this->code_list);
@@ -36,6 +36,11 @@ void CrashReport::BuildReport(u64 pid, bool has_extra_info) {
ProcessDyingMessage();
}
/* Real creport only does this if application, but there's no reason not to do it all the time. */
for (u32 i = 0; i < this->thread_list.GetThreadCount(); i++) {
this->code_list.ReadCodeRegionsFromThreadInfo(this->debug_handle, this->thread_list.GetThreadInfo(i));
}
/* Real creport builds the report here. We do it later. */
Close();
@@ -258,7 +263,7 @@ void CrashReport::SaveReport() {
void CrashReport::SaveToFile(FILE *f_report) {
char buf[0x10] = {0};
fprintf(f_report, "Atmosphère Crash Report (v1.1):\n");
fprintf(f_report, "Atmosphère Crash Report (v1.2):\n");
fprintf(f_report, "Result: 0x%X (2%03d-%04d)\n\n", this->result, R_MODULE(this->result), R_DESCRIPTION(this->result));
/* Process Info. */

View File

@@ -19,7 +19,8 @@
#include <cstdio>
#include "creport_debug_types.hpp"
#include "creport_code_info.hpp"
class CodeList;
class ThreadInfo {
private:
@@ -31,9 +32,11 @@ class ThreadInfo {
u32 stack_trace_size = 0;
CodeList *code_list;
public:
u64 GetPC() { return context.pc.x; }
u64 GetLR() { return context.lr; }
u64 GetId() { return thread_id; }
u64 GetPC() const { return context.pc.x; }
u64 GetLR() const { return context.lr; }
u64 GetId() const { return thread_id; }
u32 GetStackTraceSize() const { return stack_trace_size; }
u64 GetStackTrace(u32 i) const { return stack_trace[i]; }
bool ReadFromProcess(Handle debug_handle, u64 thread_id, bool is_64_bit);
void SaveToFile(FILE *f_report);
@@ -48,7 +51,10 @@ class ThreadList {
static const size_t max_thread_count = 0x60;
u32 thread_count = 0;
ThreadInfo thread_infos[max_thread_count];
public:
public:
u32 GetThreadCount() const { return thread_count; }
const ThreadInfo *GetThreadInfo(u32 i) const { return &thread_infos[i]; }
void SaveToFile(FILE *f_report);
void DumpBinary(FILE *f_bin, u64 crashed_id);
void ReadThreadsFromProcess(Handle debug_handle, bool is_64_bit);

View File

@@ -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"
}
}
]
}

View File

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

View File

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

View File

@@ -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;

View File

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

View File

@@ -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;

View File

@@ -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);
}

View File

@@ -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;

View File

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

View File

@@ -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;
}

View File

@@ -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>(),
};
};

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -1,53 +0,0 @@
/*
* Copyright (c) 2018 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <mutex>
#include <switch.h>
#include <stratosphere.hpp>
#include "fsmitm_worker.hpp"
static SystemEvent *g_new_waitable_event = NULL;
static HosMutex g_new_waitable_mutex;
static HosSemaphore g_sema_new_waitable_finish;
static std::unique_ptr<WaitableManager> g_worker_waiter;
Result FsMitMWorker::AddWaitableCallback(void *arg, Handle *handles, size_t num_handles, u64 timeout) {
(void)arg;
svcClearEvent(handles[0]);
g_sema_new_waitable_finish.Signal();
return 0;
}
void FsMitMWorker::AddWaitable(IWaitable *waitable) {
g_worker_waiter->add_waitable(waitable);
std::scoped_lock lk{g_new_waitable_mutex};
g_new_waitable_event->signal_event();
g_sema_new_waitable_finish.Wait();
}
void FsMitMWorker::Main(void *arg) {
/* Initialize waitable event. */
g_new_waitable_event = new SystemEvent(NULL, &FsMitMWorker::AddWaitableCallback);
/* Make a new waitable manager. */
g_worker_waiter = std::make_unique<WaitableManager>(U64_MAX);
g_worker_waiter->add_waitable(g_new_waitable_event);
/* Service processes. */
g_worker_waiter->process();
}

View File

@@ -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;
};

View File

@@ -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);
}

View File

@@ -1,75 +0,0 @@
/*
* Copyright (c) 2018 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <switch.h>
#include <stratosphere/iserviceobject.hpp>
#include "debug.hpp"
enum MitMQueryServiceCommand {
MQS_Cmd_ShouldMitm = 65000,
MQS_Cmd_AssociatePidTid = 65001
};
namespace MitMQueryUtils {
Result get_associated_tid_for_pid(u64 pid, u64 *tid);
void associate_pid_to_tid(u64 pid, u64 tid);
}
template <typename T>
class MitMQueryService : public IServiceObject {
public:
MitMQueryService<T> *clone() override {
return new MitMQueryService<T>();
}
Result dispatch(IpcParsedCommand &r, IpcCommand &out_c, u64 cmd_id, u8 *pointer_buffer, size_t pointer_buffer_size) override {
Log(armGetTls(), 0x100);
switch (cmd_id) {
case MQS_Cmd_ShouldMitm:
return WrapIpcCommandImpl<&MitMQueryService::should_mitm>(this, r, out_c, pointer_buffer, pointer_buffer_size);
case MQS_Cmd_AssociatePidTid:
return WrapIpcCommandImpl<&MitMQueryService::associate_pid_tid>(this, r, out_c, pointer_buffer, pointer_buffer_size);
default:
return 0xF601;
}
if (cmd_id == 65000) {
} else {
return 0xF601;
}
}
Result handle_deferred() override {
/* This service is never deferrable. */
return 0;
}
protected:
std::tuple<Result, u64> should_mitm(u64 pid) {
u64 should_mitm = 0;
u64 tid = 0;
if (R_SUCCEEDED(MitMQueryUtils::get_associated_tid_for_pid(pid, &tid))) {
should_mitm = T::should_mitm(pid, tid);
}
return {0, should_mitm};
}
std::tuple<Result> associate_pid_tid(u64 pid, u64 tid) {
MitMQueryUtils::associate_pid_to_tid(pid, tid);
return {0x0};
}
};

View File

@@ -1,69 +0,0 @@
/*
* Copyright (c) 2018 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <switch.h>
#include <stratosphere.hpp>
#include "mitm_query_service.hpp"
#include "sm_mitm.h"
#include "mitm_session.hpp"
#include "debug.hpp"
template <typename T>
class MitMSession;
template <typename T>
class MitMServer final : public IServer<T> {
static_assert(std::is_base_of<IServiceObject, T>::value, "Service Objects must derive from IServiceObject");
private:
char mitm_name[9];
public:
MitMServer(ISession<MitMQueryService<T>> **out_query_session, const char *service_name, unsigned int max_s, bool s_d = false) : IServer<T>(service_name, max_s, s_d) {
Handle tmp_hnd;
Handle out_query_h;
Result rc;
if (R_SUCCEEDED((rc = smGetServiceOriginal(&tmp_hnd, smEncodeName(service_name))))) {
svcCloseHandle(tmp_hnd);
} else {
fatalSimple(rc);
}
strncpy(mitm_name, service_name, 8);
mitm_name[8] = '\x00';
if (R_FAILED((rc = smMitMInstall(&this->port_handle, &out_query_h, mitm_name)))) {
fatalSimple(rc);
}
*out_query_session = new ServiceSession<MitMQueryService<T>>(NULL, out_query_h, 0);
}
virtual ~MitMServer() {
if (this->port_handle) {
if (R_FAILED(smMitMUninstall(this->mitm_name))) {
/* TODO: Panic. */
}
/* svcCloseHandle(port_handle); was called by ~IServer. */
}
}
ISession<T> *get_new_session(Handle session_h) override {
return new MitMSession<T>(this, session_h, 0, mitm_name);
}
};

View File

@@ -1,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]);
}
}
}
};

View File

@@ -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);
};

View File

@@ -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;
}

View File

@@ -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

View File

@@ -1,4 +0,0 @@
debug
release
lib
*.bz2

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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