Compare commits
64 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
164fb96da0 | ||
|
|
31c1338dba | ||
|
|
7d729e1836 | ||
|
|
36530a5501 | ||
|
|
1aba87ef76 | ||
|
|
b19e50e720 | ||
|
|
a520481168 | ||
|
|
8daa2da97c | ||
|
|
bb29a2458f | ||
|
|
ce1a6a68bf | ||
|
|
cf510ad9bf | ||
|
|
9898a01d3b | ||
|
|
54a22797a7 | ||
|
|
5ef01edab5 | ||
|
|
3b8bb325e8 | ||
|
|
6538554485 | ||
|
|
9b1a2451b0 | ||
|
|
e65bee0d6a | ||
|
|
8426a4dc77 | ||
|
|
147f3c690a | ||
|
|
bac81f4ccc | ||
|
|
2894989eb7 | ||
|
|
952ee4227d | ||
|
|
9142e90a04 | ||
|
|
3ed239296a | ||
|
|
78a47dba6d | ||
|
|
5d0aabaa44 | ||
|
|
e786bc7e9a | ||
|
|
158f7224a7 | ||
|
|
865ca76772 | ||
|
|
b8f93562c0 | ||
|
|
ef5c7d6bab | ||
|
|
be044e691c | ||
|
|
536b89efae | ||
|
|
44175058f6 | ||
|
|
7309c7f358 | ||
|
|
6336089b63 | ||
|
|
6ef34d80a0 | ||
|
|
2f7224edce | ||
|
|
c49cfbd6af | ||
|
|
8b71378920 | ||
|
|
bbffbd654f | ||
|
|
4cdd9aa8f1 | ||
|
|
23a85a7c24 | ||
|
|
3dc679215b | ||
|
|
aef7d36300 | ||
|
|
887b4e0275 | ||
|
|
9a8c70ed68 | ||
|
|
058f735031 | ||
|
|
5c147e5188 | ||
|
|
18f51e9b2e | ||
|
|
376feb63bd | ||
|
|
a502d31cd1 | ||
|
|
afbf57c222 | ||
|
|
b62329bd5b | ||
|
|
de688ee17a | ||
|
|
a6cfbae1ff | ||
|
|
c0fe4f7af7 | ||
|
|
5b219e6f58 | ||
|
|
d55a9d168e | ||
|
|
e1d884960d | ||
|
|
db97dd8d75 | ||
|
|
f96e1d5074 | ||
|
|
0938057d67 |
25
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
25
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
---
|
||||||
|
name: Bug Report
|
||||||
|
about: Something doesn't work correctly in Atmosphère.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Bug Report
|
||||||
|
|
||||||
|
### What's the issue you encountered?
|
||||||
|
|
||||||
|
### How can the issue be reproduced?
|
||||||
|
|
||||||
|
### Crash report?
|
||||||
|
|
||||||
|
(If a crash report was created under /atmosphere/crash_reports/, please upload it to
|
||||||
|
[gist](https://gist.github.com/) and paste the link here.)
|
||||||
|
|
||||||
|
### Environment?
|
||||||
|
|
||||||
|
- What bootloader (fusee, hekate, etc) was Atmosphère launched by:
|
||||||
|
- Official release or unofficial build:
|
||||||
|
- Do you have additional kips you're loading:
|
||||||
|
- Additional info about your environment:
|
||||||
|
|
||||||
|
### Additional context?
|
||||||
12
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
12
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
---
|
||||||
|
name: Feature Request
|
||||||
|
about: You want to suggest a new feature for Atmosphère.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Feature Request
|
||||||
|
|
||||||
|
### What feature are you suggesting?
|
||||||
|
|
||||||
|
### Why would this feature be useful?
|
||||||
|
|
||||||
12
.github/ISSUE_TEMPLATE/question.md
vendored
Normal file
12
.github/ISSUE_TEMPLATE/question.md
vendored
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
---
|
||||||
|
name: Question
|
||||||
|
about: Please ask questions in the ReSwitched discord, instead of making issues.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
We would like to use GitHub to keep track of problems/feature requests.
|
||||||
|
|
||||||
|
If you have a question, please join the ReSwitched discord for help.
|
||||||
|
|
||||||
|
- Discord link: https://discordapp.com/invite/DThbZ7z
|
||||||
|
|
||||||
6
.gitmodules
vendored
Normal file
6
.gitmodules
vendored
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
[submodule "common/include/boost"]
|
||||||
|
path = common/include/boost
|
||||||
|
url = https://github.com/Atmosphere-NX/ext-boost.git
|
||||||
|
[submodule "stratosphere/libstratosphere"]
|
||||||
|
path = stratosphere/libstratosphere
|
||||||
|
url = https://github.com/Atmosphere-NX/libstratosphere.git
|
||||||
26
Makefile
26
Makefile
@@ -1,21 +1,30 @@
|
|||||||
TOPTARGETS := all clean dist
|
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)))
|
ifneq (, $(strip $(shell git status --porcelain 2>/dev/null)))
|
||||||
AMSREV := $(AMSREV)-dirty
|
AMSREV := $(AMSREV)-dirty
|
||||||
endif
|
endif
|
||||||
|
|
||||||
all: fusee creport
|
all: fusee stratosphere exosphere thermosphere
|
||||||
fusee:
|
|
||||||
$(MAKE) -C $@ all
|
|
||||||
|
|
||||||
creport:
|
thermosphere:
|
||||||
$(MAKE) -C stratosphere/creport all
|
$(MAKE) -C thermosphere all
|
||||||
|
|
||||||
|
exosphere: thermosphere
|
||||||
|
$(MAKE) -C exosphere all
|
||||||
|
|
||||||
|
stratosphere: exosphere
|
||||||
|
$(MAKE) -C stratosphere all
|
||||||
|
|
||||||
|
fusee: exosphere stratosphere
|
||||||
|
$(MAKE) -C $@ all
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(MAKE) -C fusee clean
|
$(MAKE) -C fusee clean
|
||||||
rm -rf out
|
rm -rf out
|
||||||
|
|
||||||
dist: fusee creport
|
dist: all
|
||||||
$(eval MAJORVER = $(shell grep '\ATMOSPHERE_RELEASE_VERSION_MAJOR\b' common/include/atmosphere/version.h \
|
$(eval MAJORVER = $(shell grep '\ATMOSPHERE_RELEASE_VERSION_MAJOR\b' common/include/atmosphere/version.h \
|
||||||
| tr -s [:blank:] \
|
| tr -s [:blank:] \
|
||||||
| cut -d' ' -f3))
|
| cut -d' ' -f3))
|
||||||
@@ -31,10 +40,13 @@ dist: fusee creport
|
|||||||
mkdir atmosphere-$(AMSVER)
|
mkdir atmosphere-$(AMSVER)
|
||||||
mkdir atmosphere-$(AMSVER)/atmosphere
|
mkdir atmosphere-$(AMSVER)/atmosphere
|
||||||
mkdir -p atmosphere-$(AMSVER)/atmosphere/titles/0100000000000036
|
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 fusee/fusee-secondary/fusee-secondary.bin atmosphere-$(AMSVER)/fusee-secondary.bin
|
||||||
cp common/defaults/BCT.ini atmosphere-$(AMSVER)/BCT.ini
|
cp common/defaults/BCT.ini atmosphere-$(AMSVER)/BCT.ini
|
||||||
cp common/defaults/loader.ini atmosphere-$(AMSVER)/atmosphere/loader.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/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 ../;
|
cd atmosphere-$(AMSVER); zip -r ../atmosphere-$(AMSVER).zip ./*; cd ../;
|
||||||
rm -r atmosphere-$(AMSVER)
|
rm -r atmosphere-$(AMSVER)
|
||||||
mkdir out
|
mkdir out
|
||||||
|
|||||||
@@ -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.
|
* __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.
|
* __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.
|
* __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.
|
* __Riley__ for suggesting "Atmosphere" as a Horizon OS reimplementation+customization project name.
|
||||||
* __hedgeberg__ for research and hardware testing.
|
* __hedgeberg__ for research and hardware testing.
|
||||||
* __lioncash__ for code cleanup and general improvements.
|
* __lioncash__ for code cleanup and general improvements.
|
||||||
|
|||||||
@@ -14,18 +14,17 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#ifndef ATMOSPHERE_H
|
||||||
#include <switch.h>
|
#define ATMOSPHERE_H
|
||||||
#include <atomic>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
class WaitableManagerBase {
|
#ifdef __cplusplus
|
||||||
std::atomic<u64> cur_priority = 0;
|
extern "C" {
|
||||||
public:
|
#endif
|
||||||
WaitableManagerBase() = default;
|
|
||||||
virtual ~WaitableManagerBase() = default;
|
|
||||||
|
|
||||||
u64 get_priority() {
|
#include "atmosphere/version.h"
|
||||||
return std::atomic_fetch_add(&cur_priority, (u64)1);
|
|
||||||
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
};
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -19,6 +19,6 @@
|
|||||||
|
|
||||||
#define ATMOSPHERE_RELEASE_VERSION_MAJOR 0
|
#define ATMOSPHERE_RELEASE_VERSION_MAJOR 0
|
||||||
#define ATMOSPHERE_RELEASE_VERSION_MINOR 7
|
#define ATMOSPHERE_RELEASE_VERSION_MINOR 7
|
||||||
#define ATMOSPHERE_RELEASE_VERSION_MICRO 2
|
#define ATMOSPHERE_RELEASE_VERSION_MICRO 5
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
1
common/include/boost
Submodule
1
common/include/boost
Submodule
Submodule common/include/boost added at fc6429e463
107
docs/changelog.md
Normal file
107
docs/changelog.md
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
# 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:
|
||||||
|
+ Fusée, a custom bootloader.
|
||||||
|
+ Supports loading/customizing of arbitrary KIPs from the SD card.
|
||||||
|
+ Supports loading a custom kernel from the SD card ("/atmosphere/kernel.bin").
|
||||||
|
+ Supports compile-time defined kernel patches on a per-firmware basis.
|
||||||
|
+ All patches at paths like /atmosphere/kip_patches/<user-defined patch name>/<SHA256 of KIP>.ips will be applied to the relevant KIPs, allowing for easy distribution of patches supporting multiple versions.
|
||||||
|
+ Both the IPS and IPS32 formats are supported.
|
||||||
|
+ All patches at paths like /atmosphere/kernel_patches/<user-defined patch name>/<SHA256 of Kernel>.ips will be applied to the kernel, allowing for easy distribution of patches supporting multiple versions.
|
||||||
|
+ Both the IPS and IPS32 formats are supported.
|
||||||
|
+ Configurable by editing BCT.ini on the SD card.
|
||||||
|
+ Atmosphère should also be launchable by the alternative hekate bootloader, for those who prefer it.
|
||||||
|
+ Exosphère, a fully-featured custom secure monitor.
|
||||||
|
+ Exosphere is a re-implementation of Nintendo's TrustZone firmware, fully replicating all of its features.
|
||||||
|
+ In addition, it has been extended to provide information on current Atmosphere API version, for homebrew wishing to make use of it.
|
||||||
|
+ Stratosphère, a set of custom system modules. This includes:
|
||||||
|
+ A loader system module.
|
||||||
|
+ Reimplementation of Nintendo's loader, fully replicating all original functionality.
|
||||||
|
+ Configurable by editing /atmosphere/loader.ini
|
||||||
|
+ First class support for the Homebrew Loader.
|
||||||
|
+ An exefs NSP (default "/atmosphere/hbl.nsp") will be used in place of the victim title's exefs.
|
||||||
|
+ By default, HBL will replace the album applet, but any application should also be supported.
|
||||||
|
+ Extended to support arbitrary redirection of executable content to the SD card.
|
||||||
|
+ Files will be preferentially loaded from /atmosphere/titles/<titleid>/exefs/, if present.
|
||||||
|
+ Files present in the original exefs a user wants to mark as not present may be "stubbed" by creating a .stub file on the SD.
|
||||||
|
+ If present, a PFS0 at /atmosphere/titles/<titleid>/exefs.nsp will fully replace the original exefs.
|
||||||
|
+ Redirection is optionally toggleable by holding down certain buttons (by default, holding R disables redirection).
|
||||||
|
+ Full support for patching NSO content is implemented.
|
||||||
|
+ All patches at paths like /atmosphere/exefs_patches/<user-defined patch name>/<Hex Build-ID for NSO to patch>.ips will be applied, allowing for easy distribution of patches supporting multiple firmware versions and/or titles.
|
||||||
|
+ Both the IPS and IPS32 formats are supported.
|
||||||
|
+ Extended to support launching content from loose executable files on the SD card, without requiring any official installation.
|
||||||
|
+ This is done by specifying FsStorageId_None on launch.
|
||||||
|
+ A service manager system module.
|
||||||
|
+ Reimplementation of Nintendo's service manager, fully replicating all original functionality.
|
||||||
|
+ Compile-time support for reintroduction of "smhax", allowing clients to optionally skip service access verification by skipping initialization.
|
||||||
|
+ Extended to allow homebrew to acquire more handles to privileged services than Nintendo natively allows.
|
||||||
|
+ Extended to add a new API for installing Man-In-The-Middle listeners for arbitrary services.
|
||||||
|
+ API can additionally be used to safely detect whether a service has been registered in a non-blocking way with no side-effects.
|
||||||
|
+ Full API documentation to come.
|
||||||
|
+ A process manager system module.
|
||||||
|
+ Reimplementation of Nintendo's process manager, fully replicating all original functionality.
|
||||||
|
+ Extended to allow homebrew to acquire handles to arbitrary processes, and thus read/modify system memory without blocking execution.
|
||||||
|
+ Extended to allow homebrew to retrieve information about system resource limits.
|
||||||
|
+ Extended by embedding a full, extended implementation of Nintendo's boot2 system module.
|
||||||
|
+ Title launch order has been optimized in order to grant access to the SD card faster.
|
||||||
|
+ The error-collection system module is intentionally not launched, preventing many system telemetry error reports from being generated at all.
|
||||||
|
+ Users may place their own custom sysmodules on the SD card and flag them for automatic boot2 launch by creating a /atmosphere/titles/<title ID>/boot2.flag file on their SD card.
|
||||||
|
+ A custom fs.mitm system module.
|
||||||
|
+ Uses Atmosphère's MitM API in order to provide an easy means for users to modify game content.
|
||||||
|
+ Intercepts all FS commands sent by games, with special handling for commands used to mount RomFS/DLC content to enable easy creation and distribution of game/DLC mods.
|
||||||
|
+ fs.mitm will parse the base RomFS image for a game, a RomFS image located at /atmosphere/titles/<title ID>/romfs.bin, and all loose files in /atmosphere/titles/<title ID>/romfs/, and merge them together into a single RomFS image.
|
||||||
|
+ When merging, loose files are preferred to content in the SD card romfs.bin image, and files from the SD card image are preferred to those in the base image.
|
||||||
|
+ Can additionally be used to intercept commands sent by arbitrary system titles (excepting those launched before SD card is active), by creating a /atmosphere/titles/<title ID>/fsmitm.flag file on the SD card.
|
||||||
|
+ Can be forcibly disabled for any title, by creating a /atmosphere/titles/<title ID>/fsmitm_disable.flag file on the SD card.
|
||||||
|
+ Redirection is optionally toggleable by holding down certain buttons (by default, holding R disables redirection).
|
||||||
|
+ A custom crash report system module.
|
||||||
|
+ Serves as a drop-in replacement for Nintendo's own creport system module.
|
||||||
|
+ Generates detailed, human-readable reports on system crashes, saving to /atmosphere/crash_reports/<timestamp>_<title ID>.log.
|
||||||
|
+ Because reports are not sent to the erpt sysmodule, this disables all crash report related telemetry.
|
||||||
|
+ General system stability improvements to enhance the user's experience.
|
||||||
@@ -22,5 +22,8 @@ Stratosphère's modules include:
|
|||||||
### Building Atmosphère
|
### Building Atmosphère
|
||||||
A guide to building Atmosphère can be found [here](../docs/building.md).
|
A guide to building Atmosphère can be found [here](../docs/building.md).
|
||||||
|
|
||||||
### Release Roadmap
|
### Upcoming Features
|
||||||
A roadmap of the releases of Atmosphère can be found [here](../docs/roadmap.md).
|
A list of planned features for Atmosphère can be found [here](../docs/roadmap.md).
|
||||||
|
|
||||||
|
### Release History
|
||||||
|
A changelog of previous versions of Atmosphère can be found [here](../docs/changelog.md).
|
||||||
|
|||||||
@@ -53,11 +53,15 @@ When authoring patches, [hactool](https://github.com/SciresM/hactool) can be use
|
|||||||
|
|
||||||
### HBL Support
|
### HBL Support
|
||||||
|
|
||||||
TODO
|
Atmosphère can use the loader module in order to turn any game on your Switch's home menu into a launchpoint for the Homebrew Menu, rather than launching it through the album applet. This allows one to launch the Homebrew Menu with access to the ~3.2GB of RAM that the Switch reserves for games and applications, as opposed to the 442MB of RAM we are limited to when launching the Homebrew Menu from the album. This also means that it is no longer necessary to install homebrew as `.nsp` files on your Switch so long as you are using this method, as the only reason to do so is to allow the homebrew to access all of the Switch's available memory.
|
||||||
|
|
||||||
|
In order to setup this method you will need the latest release of [hbmenu](https://github.com/switchbrew/nx-hbmenu/releases), and the latest release of [hbloader](https://github.com/switchbrew/nx-hbloader/releases). Place `hbmenu.nro` on the root of your Switch's SD Card, and place `hbl.nsp` in the atmosphere folder. From there, simply configure `loader.ini` in the atmosphere folder by replacing the Title ID in the ini (hbl_tid) (it is the Title ID for the album by default) with the Title ID of whatever game you wish to use to launch the Homebrew Menu. A list of Title IDs for Switch Games can be found [here](https://switchbrew.org/wiki/Title_list/Games). Afterwards you may reinsert your SD Card into your Switch and boot into Atmosphère as you normally would. You should now be able to boot into the Homebrew Menu by launching your designated game of choice.
|
||||||
|
|
||||||
### Button Overrides
|
### Button Overrides
|
||||||
|
|
||||||
TODO
|
By default `loader.ini` is configured to launch the Homebrew Menu when launching the game normally, and launching the game when selecting the game while holding down R. If you wish to change this, you can modify the override_key section of `loader.ini`. Placing an exclamation point in front of whatever button you wish to use will make it so that you will only launch the actual game while holding down that button, otherwise you will go into the Homebrew Menu. Removing the exclamation point will reverse this, meaning that you will boot into the Homebrew Menu only while holding down the assigned button when launching the game.
|
||||||
|
|
||||||
|
For example, `override_key=!R` will run the game only while holding down R when launching it, otherwise it will boot into the Homebrew Menu. `override_key=R` will only boot into the Homebrew Menu while holding down R when launching the game, otherwise it will launch the game as normal.
|
||||||
|
|
||||||
### SM MITM Integration
|
### SM MITM Integration
|
||||||
|
|
||||||
|
|||||||
@@ -1,19 +1,16 @@
|
|||||||
# Release Roadmap
|
# Planned Features
|
||||||
## Upcoming Releases
|
The following features are planned to be added in future versions of Atmosphère:
|
||||||
### 0.7
|
+ Thermosphère, a hypervisor-based emunand implementation.
|
||||||
0.7 will be Atmosphère's first official release.
|
+ A feature-rich debugging toolset (a component of Stratosphère).
|
||||||
This release will include:
|
+ A custom debug monitor system module, providing an API for debugging Switch's processes. This may not be a reimplementation of Nintendo's own debug monitor.
|
||||||
+ Fusée
|
+ This should include a gdbstub implementation, possibly borrowing from Luma3DS's.
|
||||||
+ Supports loading/customizing of arbitrary KIPs from the SD card.
|
+ This API should be additionally usable for RAM Editing/"Cheat Engine" purposes.
|
||||||
+ Supports compile-time defined kernel patches on a per-firmware basis.
|
+ A custom shell system module, providing an means for users to perform various RPC (with support for common/interesting functionality) on their Switch remotely. This may not be a reimplementation of Nintendo's own shell.
|
||||||
+ Configurable by editing BCT.ini on the SD card.
|
+ This should support client connections over both Wi-Fi and USB.
|
||||||
+ Atmosphère should also be launchable by the alternative hekate bootloader, for those who prefer it.
|
+ A custom logging system module, providing a means for other Atmosphère components (and possibly Nintendo's own system modules) to log debug output.
|
||||||
+ Exosphère
|
+ This should support logging to the SD card, over Wi-Fi, and over USB.
|
||||||
+ Exosphere is a re-implementation of Nintendo's TrustZone firmware, fully replicating all of its features.
|
+ An application-level plugin system.
|
||||||
+ In addition, it has been extended to provide information on current Atmosphere API version, for homebrew wishing to make use of it.
|
+ This will, ideally, work somewhat like NTR-CFW's plugin system on the 3DS, allowing users to run their own code in a game's process in their own thread.
|
||||||
+ Stratosphère
|
+ An AR Code/Gameshark analog implementation, allowing for easy sharing/development of cheat codes to run on device.
|
||||||
+ loader system module
|
+ Further extensions to existing Atmosphère components.
|
||||||
+ Service Manager system module (sm)
|
+ General system stability improvements to enhance the user's experience.
|
||||||
+ Process Manager system module (pm)
|
|
||||||
+ fs.mitm system module
|
|
||||||
+ creport system module
|
|
||||||
|
|||||||
@@ -24,15 +24,74 @@
|
|||||||
#define FUSEE_EMC_H_
|
#define FUSEE_EMC_H_
|
||||||
|
|
||||||
#define EMC_BASE 0x7001B000
|
#define EMC_BASE 0x7001B000
|
||||||
|
#define EMC0_BASE 0x7001E000
|
||||||
|
#define EMC1_BASE 0x7001F000
|
||||||
#define MAKE_EMC_REG(n) MAKE_REG32(EMC_BASE + n)
|
#define MAKE_EMC_REG(n) MAKE_REG32(EMC_BASE + n)
|
||||||
|
#define MAKE_EMC0_REG(n) MAKE_REG32(EMC0_BASE + n)
|
||||||
|
#define MAKE_EMC1_REG(n) MAKE_REG32(EMC1_BASE + n)
|
||||||
|
|
||||||
|
#define EMC_INTSTATUS 0x0
|
||||||
|
#define EMC_INTSTATUS_MRR_DIVLD (0x1 << 5)
|
||||||
|
#define EMC_INTSTATUS_CLKCHANGE_COMPLETE (0x1 << 4)
|
||||||
|
|
||||||
|
#define EMC_INTMASK 0x4
|
||||||
#define EMC_DBG 0x8
|
#define EMC_DBG 0x8
|
||||||
#define EMC_CFG 0xC
|
#define EMC_DBG_WRITE_MUX_ACTIVE (1 << 1)
|
||||||
|
#define EMC_DBG_CFG_SWAP_SHIFT 26
|
||||||
|
#define EMC_DBG_CFG_SWAP_MASK \
|
||||||
|
(0x3 << EMC_DBG_CFG_SWAP_SHIFT)
|
||||||
|
#define EMC_DBG_WRITE_ACTIVE_ONLY (1 << 30)
|
||||||
|
|
||||||
#define EMC_CONFIG_SAMPLE_DELAY 0x5f0
|
#define EMC_CONFIG_SAMPLE_DELAY 0x5f0
|
||||||
#define EMC_CFG_UPDATE 0x5f4
|
#define EMC_CFG_UPDATE 0x5f4
|
||||||
|
#define EMC_CFG_UPDATE_UPDATE_DLL_IN_UPDATE_SHIFT 9
|
||||||
|
#define EMC_CFG_UPDATE_UPDATE_DLL_IN_UPDATE_MASK \
|
||||||
|
(0x3 << EMC_CFG_UPDATE_UPDATE_DLL_IN_UPDATE_SHIFT)
|
||||||
|
#define EMC_CFG 0xc
|
||||||
|
#define EMC_CFG_DRAM_CLKSTOP_PD (1 << 31)
|
||||||
|
#define EMC_CFG_DRAM_CLKSTOP_SR (1 << 30)
|
||||||
|
#define EMC_CFG_DRAM_ACPD (1 << 29)
|
||||||
|
#define EMC_CFG_DYN_SELF_REF (1 << 28)
|
||||||
|
#define EMC_CFG_REQACT_ASYNC (1 << 26)
|
||||||
|
#define EMC_CFG_AUTO_PRE_WR (1 << 25)
|
||||||
|
#define EMC_CFG_AUTO_PRE_RD (1 << 24)
|
||||||
|
#define EMC_CFG_MAM_PRE_WR (1 << 23)
|
||||||
|
#define EMC_CFG_MAN_PRE_RD (1 << 22)
|
||||||
|
#define EMC_CFG_PERIODIC_QRST (1 << 21)
|
||||||
|
#define EMC_CFG_PERIODIC_QRST_SHIFT (21)
|
||||||
|
#define EMC_CFG_EN_DYNAMIC_PUTERM (1 << 20)
|
||||||
|
#define EMC_CFG_DLY_WR_DQ_HALF_CLOCK (1 << 19)
|
||||||
|
#define EMC_CFG_DSR_VTTGEN_DRV_EN (1 << 18)
|
||||||
|
#define EMC_CFG_EMC2MC_CLK_RATIO (3 << 16)
|
||||||
|
#define EMC_CFG_WAIT_FOR_ISP2B_READY_B4_CC (1 << 9)
|
||||||
|
#define EMC_CFG_WAIT_FOR_VI2_READY_B4_CC (1 << 8)
|
||||||
|
#define EMC_CFG_WAIT_FOR_ISP2_READY_B4_CC (1 << 7)
|
||||||
|
#define EMC_CFG_INVERT_DQM (1 << 6)
|
||||||
|
#define EMC_CFG_WAIT_FOR_DISPLAYB_READY_B4_CC (1 << 5)
|
||||||
|
#define EMC_CFG_WAIT_FOR_DISPLAY_READY_B4_CC (1 << 4)
|
||||||
|
#define EMC_CFG_EMC2PMACRO_CFG_BYPASS_DATAPIPE2 (1 << 3)
|
||||||
|
#define EMC_CFG_EMC2PMACRO_CFG_BYPASS_DATAPIPE1 (1 << 2)
|
||||||
|
#define EMC_CFG_EMC2PMACRO_CFG_BYPASS_ADDRPIPE (1 << 1)
|
||||||
|
|
||||||
#define EMC_ADR_CFG 0x10
|
#define EMC_ADR_CFG 0x10
|
||||||
#define EMC_REFCTRL 0x20
|
#define EMC_REFCTRL 0x20
|
||||||
|
#define EMC_REFCTRL_DEV_SEL_SHIFT 0
|
||||||
|
#define EMC_REFCTRL_DEV_SEL_MASK \
|
||||||
|
(0x3 << EMC_REFCTRL_DEV_SEL_SHIFT)
|
||||||
|
#define EMC_REFCTRL_ENABLE (0x1 << 31)
|
||||||
|
#define EMC_REFCTRL_ENABLE_ALL(num) \
|
||||||
|
(((((num) > 1) ? 0 : 2) << EMC_REFCTRL_DEV_SEL_SHIFT) \
|
||||||
|
| EMC_REFCTRL_ENABLE)
|
||||||
|
#define EMC_REFCTRL_DISABLE_ALL(num) \
|
||||||
|
((((num) > 1) ? 0 : 2) << EMC_REFCTRL_DEV_SEL_SHIFT)
|
||||||
|
|
||||||
#define EMC_PIN 0x24
|
#define EMC_PIN 0x24
|
||||||
|
#define EMC_PIN_PIN_CKE_PER_DEV (1 << 2)
|
||||||
|
#define EMC_PIN_PIN_CKEB (1 << 1)
|
||||||
|
#define EMC_PIN_PIN_CKE (1 << 0)
|
||||||
|
|
||||||
|
#define EMC_CLK_FORCE_CC_TRIGGER (1 << 27)
|
||||||
|
|
||||||
#define EMC_TIMING_CONTROL 0x28
|
#define EMC_TIMING_CONTROL 0x28
|
||||||
#define EMC_RC 0x2c
|
#define EMC_RC 0x2c
|
||||||
#define EMC_RFC 0x30
|
#define EMC_RFC 0x30
|
||||||
@@ -77,24 +136,88 @@
|
|||||||
#define EMC_WEXT 0xb8
|
#define EMC_WEXT 0xb8
|
||||||
#define EMC_RFC_SLR 0xc0
|
#define EMC_RFC_SLR 0xc0
|
||||||
#define EMC_MRS_WAIT_CNT2 0xc4
|
#define EMC_MRS_WAIT_CNT2 0xc4
|
||||||
|
#define EMC_MRS_WAIT_CNT2_MRS_EXT2_WAIT_CNT_SHIFT 16
|
||||||
|
#define EMC_MRS_WAIT_CNT2_MRS_EXT2_WAIT_CNT_MASK \
|
||||||
|
(0x7ff << EMC_MRS_WAIT_CNT2_MRS_EXT2_WAIT_CNT_SHIFT)
|
||||||
|
#define EMC_MRS_WAIT_CNT2_MRS_EXT1_WAIT_CNT_SHIFT 0
|
||||||
|
#define EMC_MRS_WAIT_CNT2_MRS_EXT1_WAIT_CNT_MASK \
|
||||||
|
(0x3ff << EMC_MRS_WAIT_CNT2_MRS_EXT1_WAIT_CNT_SHIFT)
|
||||||
|
|
||||||
#define EMC_MRS_WAIT_CNT 0xc8
|
#define EMC_MRS_WAIT_CNT 0xc8
|
||||||
|
#define EMC_MRS_WAIT_CNT_SHORT_WAIT_SHIFT 0
|
||||||
|
#define EMC_MRS_WAIT_CNT_SHORT_WAIT_MASK \
|
||||||
|
(0x3FF << EMC_MRS_WAIT_CNT_SHORT_WAIT_SHIFT)
|
||||||
|
#define EMC_MRS_WAIT_CNT_LONG_WAIT_SHIFT 16
|
||||||
|
#define EMC_MRS_WAIT_CNT_LONG_WAIT_MASK \
|
||||||
|
(0x3FF << EMC_MRS_WAIT_CNT_LONG_WAIT_SHIFT)
|
||||||
|
|
||||||
#define EMC_MRS 0xcc
|
#define EMC_MRS 0xcc
|
||||||
|
#define EMC_MODE_SET_DLL_RESET (1 << 8)
|
||||||
|
#define EMC_MRS_USE_MRS_LONG_CNT (1 << 26)
|
||||||
|
|
||||||
#define EMC_EMRS 0xd0
|
#define EMC_EMRS 0xd0
|
||||||
|
#define EMC_EMRS_USE_EMRS_LONG_CNT (1 << 26)
|
||||||
|
|
||||||
#define EMC_REF 0xd4
|
#define EMC_REF 0xd4
|
||||||
|
#define EMC_REF_FORCE_CMD 1
|
||||||
|
|
||||||
#define EMC_PRE 0xd8
|
#define EMC_PRE 0xd8
|
||||||
#define EMC_NOP 0xdc
|
#define EMC_NOP 0xdc
|
||||||
#define EMC_SELF_REF 0xe0
|
#define EMC_SELF_REF 0xe0
|
||||||
|
#define EMC_SELF_REF_CMD_ENABLED (1 << 0)
|
||||||
|
#define EMC_SELF_REF_ACTIVE_SELF_REF (1 << 8)
|
||||||
|
#define EMC_SELF_REF_DEV_SEL_SHIFT 30
|
||||||
|
#define EMC_SELF_REF_DEV_SEL_MASK \
|
||||||
|
(0x3 << EMC_SELF_REF_DEV_SEL_SHIFT)
|
||||||
|
|
||||||
#define EMC_DPD 0xe4
|
#define EMC_DPD 0xe4
|
||||||
#define EMC_MRW 0xe8
|
#define EMC_MRW 0xe8
|
||||||
|
#define EMC_MRW_MRW_OP_SHIFT 0
|
||||||
|
#define EMC_MRW_MRW_OP_MASK \
|
||||||
|
(0xff << EMC_MRW_MRW_OP_SHIFT)
|
||||||
|
#define EMC_MRW_MRW_MA_SHIFT 16
|
||||||
|
#define EMC_MRW_MRW_MA_MASK \
|
||||||
|
(0xff << EMC_MRW_MRW_MA_SHIFT)
|
||||||
|
#define EMC_MRW_USE_MRW_LONG_CNT 26
|
||||||
|
#define EMC_MRW_USE_MRW_EXT_CNT 27
|
||||||
|
#define EMC_MRW_MRW_DEV_SELECTN_SHIFT 30
|
||||||
|
#define EMC_MRW_MRW_DEV_SELECTN_MASK \
|
||||||
|
(0x3 << EMC_MRW_MRW_DEV_SELECTN_SHIFT)
|
||||||
|
|
||||||
#define EMC_MRR 0xec
|
#define EMC_MRR 0xec
|
||||||
|
#define EMC_MRR_DEV_SEL_SHIFT 30
|
||||||
|
#define EMC_MRR_DEV_SEL_MASK \
|
||||||
|
(0x3 << EMC_SELF_REF_DEV_SEL_SHIFT)
|
||||||
|
#define EMC_MRR_MA_SHIFT 16
|
||||||
|
#define EMC_MRR_MA_MASK \
|
||||||
|
(0xff << EMC_MRR_MA_SHIFT)
|
||||||
|
#define EMC_MRR_DATA_SHIFT 0
|
||||||
|
#define EMC_MRR_DATA_MASK \
|
||||||
|
(0xffff << EMC_MRR_DATA_SHIFT)
|
||||||
|
#define LPDDR2_MR4_TEMP_SHIFT 0
|
||||||
|
#define LPDDR2_MR4_TEMP_MASK \
|
||||||
|
(0x7 << LPDDR2_MR4_TEMP_SHIFT)
|
||||||
|
|
||||||
#define EMC_CMDQ 0xf0
|
#define EMC_CMDQ 0xf0
|
||||||
#define EMC_MC2EMCQ 0xf4
|
#define EMC_MC2EMCQ 0xf4
|
||||||
#define EMC_FBIO_SPARE 0x100
|
#define EMC_FBIO_SPARE 0x100
|
||||||
#define EMC_FBIO_CFG5 0x104
|
#define EMC_FBIO_CFG5 0x104
|
||||||
|
#define EMC_FBIO_CFG5_DRAM_TYPE_SHIFT 0
|
||||||
|
#define EMC_FBIO_CFG5_DRAM_TYPE_MASK \
|
||||||
|
(0x3 << EMC_FBIO_CFG5_DRAM_TYPE_SHIFT)
|
||||||
|
#define EMC_FBIO_CFG5_CMD_TX_DIS (1 << 8)
|
||||||
|
#define EMC_FBIO_CFG5_CMD_BUS_RETURN_TO_ZERO (1 << 27)
|
||||||
|
|
||||||
|
#define EMC_CFG5_QUSE_MODE_SHIFT 13
|
||||||
|
#define EMC_CFG5_QUSE_MODE_MASK \
|
||||||
|
(0x7 << EMC_CFG5_QUSE_MODE_SHIFT)
|
||||||
|
|
||||||
#define EMC_CFG_RSV 0x120
|
#define EMC_CFG_RSV 0x120
|
||||||
#define EMC_ACPD_CONTROL 0x124
|
#define EMC_ACPD_CONTROL 0x124
|
||||||
#define EMC_MPC 0x128
|
#define EMC_MPC 0x128
|
||||||
#define EMC_EMRS2 0x12c
|
#define EMC_EMRS2 0x12c
|
||||||
|
#define EMC_EMRS2_USE_EMRS2_LONG_CNT (1 << 26)
|
||||||
|
|
||||||
#define EMC_EMRS3 0x130
|
#define EMC_EMRS3 0x130
|
||||||
#define EMC_MRW2 0x134
|
#define EMC_MRW2 0x134
|
||||||
#define EMC_MRW3 0x138
|
#define EMC_MRW3 0x138
|
||||||
@@ -207,6 +330,12 @@
|
|||||||
#define EMC_STAT_DRAM_IO_SR_CKE_EQ0_CLKS_HI 0xcd0
|
#define EMC_STAT_DRAM_IO_SR_CKE_EQ0_CLKS_HI 0xcd0
|
||||||
#define EMC_STAT_DRAM_IO_DSR 0xcd4
|
#define EMC_STAT_DRAM_IO_DSR 0xcd4
|
||||||
#define EMC_AUTO_CAL_CONFIG 0x2a4
|
#define EMC_AUTO_CAL_CONFIG 0x2a4
|
||||||
|
#define EMC_AUTO_CAL_CONFIG_AUTO_CAL_COMPUTE_START (1 << 0)
|
||||||
|
#define EMC_AUTO_CAL_CONFIG_AUTO_CAL_MEASURE_STALL (1 << 9)
|
||||||
|
#define EMC_AUTO_CAL_CONFIG_AUTO_CAL_UPDATE_STALL (1 << 10)
|
||||||
|
#define EMC_AUTO_CAL_CONFIG_AUTO_CAL_ENABLE (1 << 29)
|
||||||
|
#define EMC_AUTO_CAL_CONFIG_AUTO_CAL_START (1 << 31)
|
||||||
|
|
||||||
#define EMC_AUTO_CAL_CONFIG2 0x458
|
#define EMC_AUTO_CAL_CONFIG2 0x458
|
||||||
#define EMC_AUTO_CAL_CONFIG3 0x45c
|
#define EMC_AUTO_CAL_CONFIG3 0x45c
|
||||||
#define EMC_AUTO_CAL_CONFIG4 0x5b0
|
#define EMC_AUTO_CAL_CONFIG4 0x5b0
|
||||||
@@ -228,17 +357,47 @@
|
|||||||
#define EMC_PMACRO_AUTOCAL_CFG_1 0x704
|
#define EMC_PMACRO_AUTOCAL_CFG_1 0x704
|
||||||
#define EMC_PMACRO_AUTOCAL_CFG_2 0x708
|
#define EMC_PMACRO_AUTOCAL_CFG_2 0x708
|
||||||
#define EMC_PMACRO_AUTOCAL_CFG_COMMON 0xc78
|
#define EMC_PMACRO_AUTOCAL_CFG_COMMON 0xc78
|
||||||
|
#define EMC_PMACRO_AUTOCAL_CFG_COMMON_E_CAL_BYPASS_DVFS (1 << 16)
|
||||||
|
|
||||||
#define EMC_PMACRO_ZCTRL 0xc44
|
#define EMC_PMACRO_ZCTRL 0xc44
|
||||||
#define EMC_XM2COMPPADCTRL 0x30c
|
#define EMC_XM2COMPPADCTRL 0x30c
|
||||||
|
#define EMC_XM2COMPPADCTRL_VREF_CAL_ENABLE (1 << 10)
|
||||||
|
|
||||||
#define EMC_XM2COMPPADCTRL2 0x578
|
#define EMC_XM2COMPPADCTRL2 0x578
|
||||||
#define EMC_XM2COMPPADCTRL3 0x2f4
|
#define EMC_XM2COMPPADCTRL3 0x2f4
|
||||||
#define EMC_COMP_PAD_SW_CTRL 0x57c
|
#define EMC_COMP_PAD_SW_CTRL 0x57c
|
||||||
#define EMC_REQ_CTRL 0x2b0
|
#define EMC_REQ_CTRL 0x2b0
|
||||||
#define EMC_EMC_STATUS 0x2b4
|
#define EMC_EMC_STATUS 0x2b4
|
||||||
|
#define EMC_EMC_STATUS_MRR_DIVLD (1 << 20)
|
||||||
|
#define EMC_EMC_STATUS_TIMING_UPDATE_STALLED (1 << 23)
|
||||||
|
#define EMC_EMC_STATUS_DRAM_IN_POWERDOWN_SHIFT 4
|
||||||
|
#define EMC_EMC_STATUS_DRAM_IN_POWERDOWN_MASK \
|
||||||
|
(0x3 << EMC_EMC_STATUS_DRAM_IN_POWERDOWN_SHIFT)
|
||||||
|
#define EMC_EMC_STATUS_DRAM_IN_SELF_REFRESH_SHIFT 8
|
||||||
|
#define EMC_EMC_STATUS_DRAM_IN_SELF_REFRESH_MASK \
|
||||||
|
(0x3 << EMC_EMC_STATUS_DRAM_IN_SELF_REFRESH_SHIFT)
|
||||||
|
|
||||||
#define EMC_CFG_2 0x2b8
|
#define EMC_CFG_2 0x2b8
|
||||||
#define EMC_CFG_DIG_DLL 0x2bc
|
#define EMC_CFG_DIG_DLL 0x2bc
|
||||||
|
#define EMC_CFG_DIG_DLL_CFG_DLL_EN (1 << 0)
|
||||||
|
#define EMC_CFG_DIG_DLL_CFG_DLL_STALL_ALL_UNTIL_LOCK (1 << 1)
|
||||||
|
#define EMC_CFG_DIG_DLL_CFG_DLL_STALL_ALL_TRAFFIC (1 << 3)
|
||||||
|
#define EMC_CFG_DIG_DLL_CFG_DLL_STALL_RW_UNTIL_LOCK (1 << 4)
|
||||||
|
#define EMC_CFG_DIG_DLL_CFG_DLL_MODE_SHIFT 6
|
||||||
|
#define EMC_CFG_DIG_DLL_CFG_DLL_MODE_MASK \
|
||||||
|
(0x3 << EMC_CFG_DIG_DLL_CFG_DLL_MODE_SHIFT)
|
||||||
|
#define EMC_CFG_DIG_DLL_CFG_DLL_LOCK_LIMIT_SHIFT 8
|
||||||
|
#define EMC_CFG_DIG_DLL_CFG_DLL_LOCK_LIMIT_MASK \
|
||||||
|
(0x7 << EMC_CFG_DIG_DLL_CFG_DLL_LOCK_LIMIT_SHIFT)
|
||||||
|
|
||||||
#define EMC_CFG_DIG_DLL_PERIOD 0x2c0
|
#define EMC_CFG_DIG_DLL_PERIOD 0x2c0
|
||||||
#define EMC_DIG_DLL_STATUS 0x2c4
|
#define EMC_DIG_DLL_STATUS 0x2c4
|
||||||
|
#define EMC_DIG_DLL_STATUS_DLL_LOCK (1 << 15)
|
||||||
|
#define EMC_DIG_DLL_STATUS_DLL_PRIV_UPDATED (1 << 17)
|
||||||
|
#define EMC_DIG_DLL_STATUS_DLL_OUT_SHIFT 0
|
||||||
|
#define EMC_DIG_DLL_STATUS_DLL_OUT_MASK \
|
||||||
|
(0x7ff << EMC_DIG_DLL_STATUS_DLL_OUT_SHIFT)
|
||||||
|
|
||||||
#define EMC_CFG_DIG_DLL_1 0x2c8
|
#define EMC_CFG_DIG_DLL_1 0x2c8
|
||||||
#define EMC_RDV_MASK 0x2cc
|
#define EMC_RDV_MASK 0x2cc
|
||||||
#define EMC_WDV_MASK 0x2d0
|
#define EMC_WDV_MASK 0x2d0
|
||||||
@@ -247,21 +406,100 @@
|
|||||||
#define EMC_WDV_CHK 0x4e0
|
#define EMC_WDV_CHK 0x4e0
|
||||||
#define EMC_ZCAL_INTERVAL 0x2e0
|
#define EMC_ZCAL_INTERVAL 0x2e0
|
||||||
#define EMC_ZCAL_WAIT_CNT 0x2e4
|
#define EMC_ZCAL_WAIT_CNT 0x2e4
|
||||||
|
#define EMC_ZCAL_WAIT_CNT_ZCAL_WAIT_CNT_MASK 0x7ff
|
||||||
|
#define EMC_ZCAL_WAIT_CNT_ZCAL_WAIT_CNT_SHIFT 0
|
||||||
|
|
||||||
#define EMC_ZCAL_MRW_CMD 0x2e8
|
#define EMC_ZCAL_MRW_CMD 0x2e8
|
||||||
#define EMC_ZQ_CAL 0x2ec
|
#define EMC_ZQ_CAL 0x2ec
|
||||||
|
#define EMC_ZQ_CAL_DEV_SEL_SHIFT 30
|
||||||
|
#define EMC_ZQ_CAL_DEV_SEL_MASK \
|
||||||
|
(0x3 << EMC_SELF_REF_DEV_SEL_SHIFT)
|
||||||
|
#define EMC_ZQ_CAL_LONG (1 << 4)
|
||||||
|
#define EMC_ZQ_CAL_ZQ_LATCH_CMD (1 << 1)
|
||||||
|
#define EMC_ZQ_CAL_ZQ_CAL_CMD (1 << 0)
|
||||||
|
#define EMC_ZQ_CAL_LONG_CMD_DEV0 \
|
||||||
|
(DRAM_DEV_SEL_0 | EMC_ZQ_CAL_LONG | EMC_ZQ_CAL_CMD)
|
||||||
|
#define EMC_ZQ_CAL_LONG_CMD_DEV1 \
|
||||||
|
(DRAM_DEV_SEL_1 | EMC_ZQ_CAL_LONG | EMC_ZQ_CAL_CMD)
|
||||||
|
|
||||||
#define EMC_SCRATCH0 0x324
|
#define EMC_SCRATCH0 0x324
|
||||||
#define EMC_STALL_THEN_EXE_BEFORE_CLKCHANGE 0x3c8
|
#define EMC_STALL_THEN_EXE_BEFORE_CLKCHANGE 0x3c8
|
||||||
#define EMC_STALL_THEN_EXE_AFTER_CLKCHANGE 0x3cc
|
#define EMC_STALL_THEN_EXE_AFTER_CLKCHANGE 0x3cc
|
||||||
#define EMC_UNSTALL_RW_AFTER_CLKCHANGE 0x3d0
|
#define EMC_UNSTALL_RW_AFTER_CLKCHANGE 0x3d0
|
||||||
#define EMC_FDPD_CTRL_CMD_NO_RAMP 0x4d8
|
#define EMC_FDPD_CTRL_CMD_NO_RAMP 0x4d8
|
||||||
|
#define EMC_FDPD_CTRL_CMD_NO_RAMP_CMD_DPD_NO_RAMP_ENABLE (1 << 0)
|
||||||
|
|
||||||
#define EMC_SEL_DPD_CTRL 0x3d8
|
#define EMC_SEL_DPD_CTRL 0x3d8
|
||||||
|
#define EMC_SEL_DPD_CTRL_DATA_SEL_DPD_EN (1 << 8)
|
||||||
|
#define EMC_SEL_DPD_CTRL_ODT_SEL_DPD_EN (1 << 5)
|
||||||
|
#define EMC_SEL_DPD_CTRL_RESET_SEL_DPD_EN (1 << 4)
|
||||||
|
#define EMC_SEL_DPD_CTRL_CA_SEL_DPD_EN (1 << 3)
|
||||||
|
#define EMC_SEL_DPD_CTRL_CLK_SEL_DPD_EN (1 << 2)
|
||||||
|
#define EMC_SEL_DPD_CTRL_DDR3_MASK \
|
||||||
|
((0xf << 2) | (0x1 << 8))
|
||||||
|
#define EMC_SEL_DPD_CTRL_MAS \
|
||||||
|
((0x3 << 2) | (0x1 << 5) | (0x1 << 8))
|
||||||
|
|
||||||
#define EMC_FDPD_CTRL_DQ 0x310
|
#define EMC_FDPD_CTRL_DQ 0x310
|
||||||
#define EMC_FDPD_CTRL_CMD 0x314
|
#define EMC_FDPD_CTRL_CMD 0x314
|
||||||
#define EMC_PRE_REFRESH_REQ_CNT 0x3dc
|
#define EMC_PRE_REFRESH_REQ_CNT 0x3dc
|
||||||
#define EMC_REFCTRL2 0x580
|
#define EMC_REFCTRL2 0x580
|
||||||
#define EMC_FBIO_CFG7 0x584
|
#define EMC_FBIO_CFG7 0x584
|
||||||
|
#define EMC_FBIO_CFG7_CH0_ENABLE (1 << 1)
|
||||||
|
#define EMC_FBIO_CFG7_CH1_ENABLE (1 << 2)
|
||||||
|
|
||||||
#define EMC_DATA_BRLSHFT_0 0x588
|
#define EMC_DATA_BRLSHFT_0 0x588
|
||||||
|
#define EMC_DATA_BRLSHFT_0_RANK0_BYTE7_DATA_BRLSHFT_SHIFT 21
|
||||||
|
#define EMC_DATA_BRLSHFT_0_RANK0_BYTE7_DATA_BRLSHFT_MASK \
|
||||||
|
(0x7 << EMC_DATA_BRLSHFT_0_RANK0_BYTE7_DATA_BRLSHFT_SHIFT)
|
||||||
|
#define EMC_DATA_BRLSHFT_0_RANK0_BYTE6_DATA_BRLSHFT_SHIFT 18
|
||||||
|
#define EMC_DATA_BRLSHFT_0_RANK0_BYTE6_DATA_BRLSHFT_MASK \
|
||||||
|
(0x7 << EMC_DATA_BRLSHFT_0_RANK0_BYTE6_DATA_BRLSHFT_SHIFT)
|
||||||
|
#define EMC_DATA_BRLSHFT_0_RANK0_BYTE5_DATA_BRLSHFT_SHIFT 15
|
||||||
|
#define EMC_DATA_BRLSHFT_0_RANK0_BYTE5_DATA_BRLSHFT_MASK \
|
||||||
|
(0x7 << EMC_DATA_BRLSHFT_0_RANK0_BYTE5_DATA_BRLSHFT_SHIFT)
|
||||||
|
#define EMC_DATA_BRLSHFT_0_RANK0_BYTE4_DATA_BRLSHFT_SHIFT 12
|
||||||
|
#define EMC_DATA_BRLSHFT_0_RANK0_BYTE4_DATA_BRLSHFT_MASK \
|
||||||
|
(0x7 << EMC_DATA_BRLSHFT_0_RANK0_BYTE4_DATA_BRLSHFT_SHIFT)
|
||||||
|
#define EMC_DATA_BRLSHFT_0_RANK0_BYTE3_DATA_BRLSHFT_SHIFT 9
|
||||||
|
#define EMC_DATA_BRLSHFT_0_RANK0_BYTE3_DATA_BRLSHFT_MASK \
|
||||||
|
(0x7 << EMC_DATA_BRLSHFT_0_RANK0_BYTE3_DATA_BRLSHFT_SHIFT)
|
||||||
|
#define EMC_DATA_BRLSHFT_0_RANK0_BYTE2_DATA_BRLSHFT_SHIFT 6
|
||||||
|
#define EMC_DATA_BRLSHFT_0_RANK0_BYTE2_DATA_BRLSHFT_MASK \
|
||||||
|
(0x7 << EMC_DATA_BRLSHFT_0_RANK0_BYTE2_DATA_BRLSHFT_SHIFT)
|
||||||
|
#define EMC_DATA_BRLSHFT_0_RANK0_BYTE1_DATA_BRLSHFT_SHIFT 3
|
||||||
|
#define EMC_DATA_BRLSHFT_0_RANK0_BYTE1_DATA_BRLSHFT_MASK \
|
||||||
|
(0x7 << EMC_DATA_BRLSHFT_0_RANK0_BYTE1_DATA_BRLSHFT_SHIFT)
|
||||||
|
#define EMC_DATA_BRLSHFT_0_RANK0_BYTE0_DATA_BRLSHFT_SHIFT 0
|
||||||
|
#define EMC_DATA_BRLSHFT_0_RANK0_BYTE0_DATA_BRLSHFT_MASK \
|
||||||
|
(0x7 << EMC_DATA_BRLSHFT_0_RANK0_BYTE0_DATA_BRLSHFT_SHIFT)
|
||||||
|
|
||||||
#define EMC_DATA_BRLSHFT_1 0x58c
|
#define EMC_DATA_BRLSHFT_1 0x58c
|
||||||
|
#define EMC_DATA_BRLSHFT_1_RANK1_BYTE7_DATA_BRLSHFT_SHIFT 21
|
||||||
|
#define EMC_DATA_BRLSHFT_1_RANK1_BYTE7_DATA_BRLSHFT_MASK \
|
||||||
|
(0x7 << EMC_DATA_BRLSHFT_1_RANK1_BYTE7_DATA_BRLSHFT_SHIFT)
|
||||||
|
#define EMC_DATA_BRLSHFT_1_RANK1_BYTE6_DATA_BRLSHFT_SHIFT 18
|
||||||
|
#define EMC_DATA_BRLSHFT_1_RANK1_BYTE6_DATA_BRLSHFT_MASK \
|
||||||
|
(0x7 << EMC_DATA_BRLSHFT_1_RANK1_BYTE6_DATA_BRLSHFT_SHIFT)
|
||||||
|
#define EMC_DATA_BRLSHFT_1_RANK1_BYTE5_DATA_BRLSHFT_SHIFT 15
|
||||||
|
#define EMC_DATA_BRLSHFT_1_RANK1_BYTE5_DATA_BRLSHFT_MASK \
|
||||||
|
(0x7 << EMC_DATA_BRLSHFT_1_RANK1_BYTE5_DATA_BRLSHFT_SHIFT)
|
||||||
|
#define EMC_DATA_BRLSHFT_1_RANK1_BYTE4_DATA_BRLSHFT_SHIFT 12
|
||||||
|
#define EMC_DATA_BRLSHFT_1_RANK1_BYTE4_DATA_BRLSHFT_MASK \
|
||||||
|
(0x7 << EMC_DATA_BRLSHFT_1_RANK1_BYTE4_DATA_BRLSHFT_SHIFT)
|
||||||
|
#define EMC_DATA_BRLSHFT_1_RANK1_BYTE3_DATA_BRLSHFT_SHIFT 9
|
||||||
|
#define EMC_DATA_BRLSHFT_1_RANK1_BYTE3_DATA_BRLSHFT_MASK \
|
||||||
|
(0x7 << EMC_DATA_BRLSHFT_1_RANK1_BYTE3_DATA_BRLSHFT_SHIFT)
|
||||||
|
#define EMC_DATA_BRLSHFT_1_RANK1_BYTE2_DATA_BRLSHFT_SHIFT 6
|
||||||
|
#define EMC_DATA_BRLSHFT_1_RANK1_BYTE2_DATA_BRLSHFT_MASK \
|
||||||
|
(0x7 << EMC_DATA_BRLSHFT_1_RANK1_BYTE2_DATA_BRLSHFT_SHIFT)
|
||||||
|
#define EMC_DATA_BRLSHFT_1_RANK1_BYTE1_DATA_BRLSHFT_SHIFT 3
|
||||||
|
#define EMC_DATA_BRLSHFT_1_RANK1_BYTE1_DATA_BRLSHFT_MASK \
|
||||||
|
(0x7 << EMC_DATA_BRLSHFT_1_RANK1_BYTE1_DATA_BRLSHFT_SHIFT)
|
||||||
|
#define EMC_DATA_BRLSHFT_1_RANK1_BYTE0_DATA_BRLSHFT_SHIFT 0
|
||||||
|
#define EMC_DATA_BRLSHFT_1_RANK1_BYTE0_DATA_BRLSHFT_MASK \
|
||||||
|
(0x7 << EMC_DATA_BRLSHFT_1_RANK1_BYTE0_DATA_BRLSHFT_SHIFT)
|
||||||
|
|
||||||
#define EMC_DQS_BRLSHFT_0 0x594
|
#define EMC_DQS_BRLSHFT_0 0x594
|
||||||
#define EMC_DQS_BRLSHFT_1 0x598
|
#define EMC_DQS_BRLSHFT_1 0x598
|
||||||
#define EMC_CMD_BRLSHFT_0 0x59c
|
#define EMC_CMD_BRLSHFT_0 0x59c
|
||||||
@@ -303,6 +541,8 @@
|
|||||||
#define EMC_TR_CTRL_0 0x3b8
|
#define EMC_TR_CTRL_0 0x3b8
|
||||||
#define EMC_TR_CTRL_1 0x3bc
|
#define EMC_TR_CTRL_1 0x3bc
|
||||||
#define EMC_TR_DVFS 0x460
|
#define EMC_TR_DVFS 0x460
|
||||||
|
#define EMC_TR_DVFS_TRAINING_DVFS (1 << 0)
|
||||||
|
|
||||||
#define EMC_SWITCH_BACK_CTRL 0x3c0
|
#define EMC_SWITCH_BACK_CTRL 0x3c0
|
||||||
#define EMC_TR_RDV 0x3c4
|
#define EMC_TR_RDV 0x3c4
|
||||||
#define EMC_TR_QPOP 0x3f4
|
#define EMC_TR_QPOP 0x3f4
|
||||||
@@ -319,6 +559,8 @@
|
|||||||
#define EMC_CFG_3 0x49c
|
#define EMC_CFG_3 0x49c
|
||||||
#define EMC_CFG_PIPE_2 0x554
|
#define EMC_CFG_PIPE_2 0x554
|
||||||
#define EMC_CFG_PIPE_CLK 0x558
|
#define EMC_CFG_PIPE_CLK 0x558
|
||||||
|
#define EMC_CFG_PIPE_CLK_CLK_ALWAYS_ON (1 << 0)
|
||||||
|
|
||||||
#define EMC_CFG_PIPE_1 0x55c
|
#define EMC_CFG_PIPE_1 0x55c
|
||||||
#define EMC_CFG_PIPE 0x560
|
#define EMC_CFG_PIPE 0x560
|
||||||
#define EMC_QPOP 0x564
|
#define EMC_QPOP 0x564
|
||||||
@@ -331,9 +573,47 @@
|
|||||||
#define EMC_PROTOBIST_WDATA_UPPER 0x5e0
|
#define EMC_PROTOBIST_WDATA_UPPER 0x5e0
|
||||||
#define EMC_PROTOBIST_RDATA 0x5ec
|
#define EMC_PROTOBIST_RDATA 0x5ec
|
||||||
#define EMC_DLL_CFG_0 0x5e4
|
#define EMC_DLL_CFG_0 0x5e4
|
||||||
|
#define EMC_DLL_CFG_0_DDLLCAL_CTRL_IGNORE_START (1 << 29)
|
||||||
|
#define EMC_DLL_CFG_0_DDLLCAL_CTRL_DUAL_PASS_LOCK (1 << 28)
|
||||||
|
#define EMC_DLL_CFG_0_DDLLCAL_CTRL_STEP_SIZE_SHIFT 24
|
||||||
|
#define EMC_DLL_CFG_0_DDLLCAL_CTRL_STEP_SIZE_MASK \
|
||||||
|
(0xf << EMC_DLL_CFG_0_DDLLCAL_CTRL_STEP_SIZE_SHIFT)
|
||||||
|
#define EMC_DLL_CFG_0_DDLLCAL_CTRL_END_COUNT_SHIFT 20
|
||||||
|
#define EMC_DLL_CFG_0_DDLLCAL_CTRL_END_COUNT_MASK \
|
||||||
|
(0xf << EMC_DLL_CFG_0_DDLLCAL_CTRL_END_COUNT_SHIFT)
|
||||||
|
#define EMC_DLL_CFG_0_DDLLCAL_CTRL_FILTER_BITS_SHIFT 16
|
||||||
|
#define EMC_DLL_CFG_0_DDLLCAL_CTRL_FILTER_BITS_MASK \
|
||||||
|
(0xf << EMC_DLL_CFG_0_DDLLCAL_CTRL_FILTER_BITS_SHIFT)
|
||||||
|
#define EMC_DLL_CFG_0_DDLLCAL_CTRL_SAMPLE_COUNT_SHIFT 12
|
||||||
|
#define EMC_DLL_CFG_0_DDLLCAL_CTRL_SAMPLE_COUNT_MASK \
|
||||||
|
(0xf << EMC_DLL_CFG_0_DDLLCAL_CTRL_SAMPLE_COUNT_SHIFT)
|
||||||
|
#define EMC_DLL_CFG_0_DDLLCAL_CTRL_SAMPLE_DELAY_SHIFT 4
|
||||||
|
#define EMC_DLL_CFG_0_DDLLCAL_CTRL_SAMPLE_DELAY_MASK \
|
||||||
|
(0xff << EMC_DLL_CFG_0_DDLLCAL_CTRL_SAMPLE_DELAY_SHIFT)
|
||||||
|
#define EMC_DLL_CFG_0_DDLLCAL_UPDATE_CNT_LIMIT_SHIFT 0
|
||||||
|
#define EMC_DLL_CFG_0_DDLLCAL_UPDATE_CNT_LIMIT_MASK \
|
||||||
|
(0xf << EMC_DLL_CFG_0_DDLLCAL_UPDATE_CNT_LIMIT_SHIFT)
|
||||||
|
|
||||||
#define EMC_DLL_CFG_1 0x5e8
|
#define EMC_DLL_CFG_1 0x5e8
|
||||||
|
#define EMC_DLL_CFG_1_DDLLCAL_CTRL_START_TRIM_SHIFT 10
|
||||||
|
#define EMC_DLL_CFG_1_DDLLCAL_CTRL_START_TRIM_MASK \
|
||||||
|
(0x7ff << EMC_DLL_CFG_1_DDLLCAL_CTRL_START_TRIM_SHIFT)
|
||||||
|
|
||||||
#define EMC_TRAINING_CMD 0xe00
|
#define EMC_TRAINING_CMD 0xe00
|
||||||
|
#define EMC_TRAINING_CMD_PRIME (1 << 0)
|
||||||
|
#define EMC_TRAINING_CMD_CA (1 << 1)
|
||||||
|
#define EMC_TRAINING_CMD_RD (1 << 2)
|
||||||
|
#define EMC_TRAINING_CMD_WR (1 << 3)
|
||||||
|
#define EMC_TRAINING_CMD_QUSE (1 << 4)
|
||||||
|
#define EMC_TRAINING_CMD_CA_VREF (1 << 5)
|
||||||
|
#define EMC_TRAINING_CMD_RD_VREF (1 << 6)
|
||||||
|
#define EMC_TRAINING_CMD_WR_VREF (1 << 7)
|
||||||
|
#define EMC_TRAINING_CMD_QUSE_VREF (1 << 8)
|
||||||
|
#define EMC_TRAINING_CMD_GO (1 << 31)
|
||||||
|
|
||||||
#define EMC_TRAINING_CTRL 0xe04
|
#define EMC_TRAINING_CTRL 0xe04
|
||||||
|
#define EMC_TRAINING_CTRL_SWAP_RANK (1 << 14)
|
||||||
|
|
||||||
#define EMC_TRAINING_STATUS 0xe08
|
#define EMC_TRAINING_STATUS 0xe08
|
||||||
#define EMC_TRAINING_QUSE_CORS_CTRL 0xe0c
|
#define EMC_TRAINING_QUSE_CORS_CTRL 0xe0c
|
||||||
#define EMC_TRAINING_QUSE_FINE_CTRL 0xe10
|
#define EMC_TRAINING_QUSE_FINE_CTRL 0xe10
|
||||||
@@ -401,15 +681,104 @@
|
|||||||
#define EMC_PMACRO_QUSE_DDLL_RANK1_4 0x630
|
#define EMC_PMACRO_QUSE_DDLL_RANK1_4 0x630
|
||||||
#define EMC_PMACRO_QUSE_DDLL_RANK1_5 0x634
|
#define EMC_PMACRO_QUSE_DDLL_RANK1_5 0x634
|
||||||
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0 0x640
|
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0 0x640
|
||||||
|
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0_OB_DDLL_LONG_DQ_RANK0_BYTE1_SHIFT \
|
||||||
|
16
|
||||||
|
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0_OB_DDLL_LONG_DQ_RANK0_BYTE1_MASK \
|
||||||
|
0x3ff << \
|
||||||
|
EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0_OB_DDLL_LONG_DQ_RANK0_BYTE1_SHIFT
|
||||||
|
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0_OB_DDLL_LONG_DQ_RANK0_BYTE0_SHIFT \
|
||||||
|
0
|
||||||
|
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0_OB_DDLL_LONG_DQ_RANK0_BYTE0_MASK \
|
||||||
|
0x3ff << \
|
||||||
|
EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0_OB_DDLL_LONG_DQ_RANK0_BYTE0_SHIFT
|
||||||
|
|
||||||
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1 0x644
|
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1 0x644
|
||||||
|
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1_OB_DDLL_LONG_DQ_RANK0_BYTE3_SHIFT \
|
||||||
|
16
|
||||||
|
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1_OB_DDLL_LONG_DQ_RANK0_BYTE3_MASK \
|
||||||
|
0x3ff << \
|
||||||
|
EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1_OB_DDLL_LONG_DQ_RANK0_BYTE3_SHIFT
|
||||||
|
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1_OB_DDLL_LONG_DQ_RANK0_BYTE2_SHIFT \
|
||||||
|
0
|
||||||
|
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1_OB_DDLL_LONG_DQ_RANK0_BYTE2_MASK \
|
||||||
|
0x3ff << \
|
||||||
|
EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1_OB_DDLL_LONG_DQ_RANK0_BYTE2_SHIFT
|
||||||
|
|
||||||
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_2 0x648
|
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_2 0x648
|
||||||
|
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_2_OB_DDLL_LONG_DQ_RANK0_BYTE5_SHIFT \
|
||||||
|
16
|
||||||
|
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_2_OB_DDLL_LONG_DQ_RANK0_BYTE5_MASK \
|
||||||
|
0x3ff << \
|
||||||
|
EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_2_OB_DDLL_LONG_DQ_RANK0_BYTE5_SHIFT
|
||||||
|
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_2_OB_DDLL_LONG_DQ_RANK0_BYTE4_SHIFT \
|
||||||
|
0
|
||||||
|
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_2_OB_DDLL_LONG_DQ_RANK0_BYTE4_MASK \
|
||||||
|
0x3ff << \
|
||||||
|
EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_2_OB_DDLL_LONG_DQ_RANK0_BYTE4_SHIFT
|
||||||
|
|
||||||
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_3 0x64c
|
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_3 0x64c
|
||||||
|
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_3_OB_DDLL_LONG_DQ_RANK0_BYTE7_SHIFT \
|
||||||
|
16
|
||||||
|
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_3_OB_DDLL_LONG_DQ_RANK0_BYTE7_MASK \
|
||||||
|
0x3ff << \
|
||||||
|
EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_3_OB_DDLL_LONG_DQ_RANK0_BYTE7_SHIFT
|
||||||
|
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_3_OB_DDLL_LONG_DQ_RANK0_BYTE6_SHIFT \
|
||||||
|
0
|
||||||
|
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_3_OB_DDLL_LONG_DQ_RANK0_BYTE6_MASK \
|
||||||
|
0x3ff << \
|
||||||
|
EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_3_OB_DDLL_LONG_DQ_RANK0_BYTE6_SHIFT
|
||||||
|
|
||||||
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_4 0x650
|
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_4 0x650
|
||||||
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_5 0x654
|
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_5 0x654
|
||||||
|
|
||||||
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_0 0x660
|
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_0 0x660
|
||||||
|
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_0_OB_DDLL_LONG_DQ_RANK1_BYTE1_SHIFT \
|
||||||
|
16
|
||||||
|
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_0_OB_DDLL_LONG_DQ_RANK1_BYTE1_MASK \
|
||||||
|
0x3ff << \
|
||||||
|
EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_0_OB_DDLL_LONG_DQ_RANK1_BYTE1_SHIFT
|
||||||
|
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_0_OB_DDLL_LONG_DQ_RANK1_BYTE0_SHIFT \
|
||||||
|
0
|
||||||
|
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_0_OB_DDLL_LONG_DQ_RANK1_BYTE0_MASK \
|
||||||
|
0x3ff << \
|
||||||
|
EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_0_OB_DDLL_LONG_DQ_RANK1_BYTE0_SHIFT
|
||||||
|
|
||||||
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_1 0x664
|
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_1 0x664
|
||||||
|
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_1_OB_DDLL_LONG_DQ_RANK1_BYTE3_SHIFT \
|
||||||
|
16
|
||||||
|
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_1_OB_DDLL_LONG_DQ_RANK1_BYTE3_MASK \
|
||||||
|
0x3ff << \
|
||||||
|
EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_1_OB_DDLL_LONG_DQ_RANK1_BYTE3_SHIFT
|
||||||
|
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_1_OB_DDLL_LONG_DQ_RANK1_BYTE2_SHIFT \
|
||||||
|
0
|
||||||
|
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_1_OB_DDLL_LONG_DQ_RANK1_BYTE2_MASK \
|
||||||
|
0x3ff << \
|
||||||
|
EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_1_OB_DDLL_LONG_DQ_RANK1_BYTE2_SHIFT
|
||||||
|
|
||||||
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_2 0x668
|
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_2 0x668
|
||||||
|
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_2_OB_DDLL_LONG_DQ_RANK1_BYTE5_SHIFT \
|
||||||
|
16
|
||||||
|
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_2_OB_DDLL_LONG_DQ_RANK1_BYTE5_MASK \
|
||||||
|
0x3ff << \
|
||||||
|
EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_2_OB_DDLL_LONG_DQ_RANK1_BYTE5_SHIFT
|
||||||
|
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_2_OB_DDLL_LONG_DQ_RANK1_BYTE4_SHIFT \
|
||||||
|
0
|
||||||
|
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_2_OB_DDLL_LONG_DQ_RANK1_BYTE4_MASK \
|
||||||
|
0x3ff << \
|
||||||
|
EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_2_OB_DDLL_LONG_DQ_RANK1_BYTE4_SHIFT
|
||||||
|
|
||||||
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_3 0x66c
|
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_3 0x66c
|
||||||
|
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_3_OB_DDLL_LONG_DQ_RANK1_BYTE7_SHIFT \
|
||||||
|
16
|
||||||
|
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_3_OB_DDLL_LONG_DQ_RANK1_BYTE7_MASK \
|
||||||
|
0x3ff << \
|
||||||
|
EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_3_OB_DDLL_LONG_DQ_RANK1_BYTE7_SHIFT
|
||||||
|
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_3_OB_DDLL_LONG_DQ_RANK1_BYTE6_SHIFT \
|
||||||
|
0
|
||||||
|
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_3_OB_DDLL_LONG_DQ_RANK1_BYTE6_MASK \
|
||||||
|
0x3ff << \
|
||||||
|
EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_3_OB_DDLL_LONG_DQ_RANK1_BYTE6_SHIFT
|
||||||
|
|
||||||
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_4 0x670
|
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_4 0x670
|
||||||
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_5 0x674
|
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_5 0x674
|
||||||
#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_0 0x680
|
#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_0 0x680
|
||||||
@@ -640,17 +1009,62 @@
|
|||||||
#define EMC_PMACRO_DDLL_SHORT_CMD_1 0xc24
|
#define EMC_PMACRO_DDLL_SHORT_CMD_1 0xc24
|
||||||
#define EMC_PMACRO_DDLL_SHORT_CMD_2 0xc28
|
#define EMC_PMACRO_DDLL_SHORT_CMD_2 0xc28
|
||||||
#define EMC_PMACRO_CFG_PM_GLOBAL_0 0xc30
|
#define EMC_PMACRO_CFG_PM_GLOBAL_0 0xc30
|
||||||
|
#define EMC_PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_BYTE0 (1 << 16)
|
||||||
|
#define EMC_PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_BYTE1 (1 << 17)
|
||||||
|
#define EMC_PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_BYTE2 (1 << 18)
|
||||||
|
#define EMC_PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_BYTE3 (1 << 19)
|
||||||
|
#define EMC_PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_BYTE4 (1 << 20)
|
||||||
|
#define EMC_PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_BYTE5 (1 << 21)
|
||||||
|
#define EMC_PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_BYTE6 (1 << 22)
|
||||||
|
#define EMC_PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_BYTE7 (1 << 23)
|
||||||
|
#define EMC_PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_CMD0 (1 << 24)
|
||||||
|
#define EMC_PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_CMD1 (1 << 25)
|
||||||
|
#define EMC_PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_CMD2 (1 << 26)
|
||||||
|
#define EMC_PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_CMD3 (1 << 27)
|
||||||
|
|
||||||
#define EMC_PMACRO_VTTGEN_CTRL_0 0xc34
|
#define EMC_PMACRO_VTTGEN_CTRL_0 0xc34
|
||||||
#define EMC_PMACRO_VTTGEN_CTRL_1 0xc38
|
#define EMC_PMACRO_VTTGEN_CTRL_1 0xc38
|
||||||
#define EMC_PMACRO_VTTGEN_CTRL_2 0xcf0
|
#define EMC_PMACRO_VTTGEN_CTRL_2 0xcf0
|
||||||
#define EMC_PMACRO_BG_BIAS_CTRL_0 0xc3c
|
#define EMC_PMACRO_BG_BIAS_CTRL_0 0xc3c
|
||||||
|
#define EMC_PMACRO_BG_BIAS_CTRL_0_BG_E_PWRD (1 << 0)
|
||||||
|
#define EMC_PMACRO_BG_BIAS_CTRL_0_BG_MODE (1 << 1)
|
||||||
|
#define EMC_PMACRO_BG_BIAS_CTRL_0_BGLP_E_PWRD (1 << 2)
|
||||||
|
|
||||||
#define EMC_PMACRO_PAD_CFG_CTRL 0xc40
|
#define EMC_PMACRO_PAD_CFG_CTRL 0xc40
|
||||||
#define EMC_PMACRO_CMD_PAD_RX_CTRL 0xc50
|
#define EMC_PMACRO_CMD_PAD_RX_CTRL 0xc50
|
||||||
#define EMC_PMACRO_DATA_PAD_RX_CTRL 0xc54
|
#define EMC_PMACRO_DATA_PAD_RX_CTRL 0xc54
|
||||||
#define EMC_PMACRO_CMD_RX_TERM_MODE 0xc58
|
#define EMC_PMACRO_CMD_RX_TERM_MODE 0xc58
|
||||||
#define EMC_PMACRO_DATA_RX_TERM_MODE 0xc5c
|
#define EMC_PMACRO_DATA_RX_TERM_MODE 0xc5c
|
||||||
|
#define EMC_PMACRO_DATA_RX_TERM_MODE_DATA_DQSN_RX_TERM_MODE_SHIFT 8
|
||||||
|
#define EMC_PMACRO_DATA_RX_TERM_MODE_DATA_DQSN_RX_TERM_MODE_MASK (0x3 << \
|
||||||
|
EMC_PMACRO_DATA_RX_TERM_MODE_DATA_DQSN_RX_TERM_MODE_SHIFT)
|
||||||
|
#define EMC_PMACRO_DATA_RX_TERM_MODE_DATA_DQSP_RX_TERM_MODE_SHIFT 4
|
||||||
|
#define EMC_PMACRO_DATA_RX_TERM_MODE_DATA_DQSP_RX_TERM_MODE_MASK (0x3 << \
|
||||||
|
EMC_PMACRO_DATA_RX_TERM_MODE_DATA_DQSP_RX_TERM_MODE_SHIFT)
|
||||||
|
#define EMC_PMACRO_DATA_RX_TERM_MODE_DATA_DQ_RX_TERM_MODE_SHIFT 0
|
||||||
|
#define EMC_PMACRO_DATA_RX_TERM_MODE_DATA_DQ_RX_TERM_MODE_MASK (0x3 << \
|
||||||
|
EMC_PMACRO_DATA_RX_TERM_MODE_DATA_DQ_RX_TERM_MODE_SHIFT)
|
||||||
|
|
||||||
|
#define RX_TERM_MODE \
|
||||||
|
~(EMC_PMACRO_DATA_RX_TERM_MODE_DATA_DQSN_RX_TERM_MODE_MASK | \
|
||||||
|
EMC_PMACRO_DATA_RX_TERM_MODE_DATA_DQSP_RX_TERM_MODE_MASK | \
|
||||||
|
EMC_PMACRO_DATA_RX_TERM_MODE_DATA_DQ_RX_TERM_MODE_MASK)
|
||||||
|
|
||||||
#define EMC_PMACRO_CMD_PAD_TX_CTRL 0xc60
|
#define EMC_PMACRO_CMD_PAD_TX_CTRL 0xc60
|
||||||
|
#define EMC_PMACRO_CMD_PAD_TX_CTRL_CMD_DQ_TX_E_DCC (1 << 1)
|
||||||
|
#define EMC_PMACRO_CMD_PAD_TX_CTRL_CMD_DQSP_TX_E_DCC (1 << 9)
|
||||||
|
#define EMC_PMACRO_CMD_PAD_TX_CTRL_CMD_DQSN_TX_E_DCC (1 << 16)
|
||||||
|
#define EMC_PMACRO_CMD_PAD_TX_CTRL_CMD_CMD_TX_E_DCC (1 << 24)
|
||||||
|
#define EMC_PMACRO_CMD_PAD_TX_CTRL_CMD_DQ_TX_DRVFORCEON (1 << 26)
|
||||||
|
|
||||||
#define EMC_PMACRO_DATA_PAD_TX_CTRL 0xc64
|
#define EMC_PMACRO_DATA_PAD_TX_CTRL 0xc64
|
||||||
|
#define EMC_PMACRO_DATA_PAD_TX_CTRL_DATA_DQ_E_IVREF (1 << 0)
|
||||||
|
#define EMC_PMACRO_DATA_PAD_TX_CTRL_DATA_DQ_TX_E_DCC (1 << 1)
|
||||||
|
#define EMC_PMACRO_DATA_PAD_TX_CTRL_DATA_DQS_E_IVREF (1 << 8)
|
||||||
|
#define EMC_PMACRO_DATA_PAD_TX_CTRL_DATA_DQSP_TX_E_DCC (1 << 9)
|
||||||
|
#define EMC_PMACRO_DATA_PAD_TX_CTRL_DATA_DQSN_TX_E_DCC (1 << 16)
|
||||||
|
#define EMC_PMACRO_DATA_PAD_TX_CTRL_DATA_CMD_TX_E_DCC (1 << 24)
|
||||||
|
|
||||||
#define EMC_PMACRO_COMMON_PAD_TX_CTRL 0xc68
|
#define EMC_PMACRO_COMMON_PAD_TX_CTRL 0xc68
|
||||||
#define EMC_PMACRO_BRICK_MAPPING_0 0xc80
|
#define EMC_PMACRO_BRICK_MAPPING_0 0xc80
|
||||||
#define EMC_PMACRO_BRICK_MAPPING_1 0xc84
|
#define EMC_PMACRO_BRICK_MAPPING_1 0xc84
|
||||||
@@ -663,7 +1077,11 @@
|
|||||||
#define EMC_PMACRO_CMD_BRICK_CTRL_FDPD 0x318
|
#define EMC_PMACRO_CMD_BRICK_CTRL_FDPD 0x318
|
||||||
#define EMC_PMACRO_DATA_BRICK_CTRL_FDPD 0x31c
|
#define EMC_PMACRO_DATA_BRICK_CTRL_FDPD 0x31c
|
||||||
#define EMC_PMACRO_TRAINING_CTRL_0 0xcf8
|
#define EMC_PMACRO_TRAINING_CTRL_0 0xcf8
|
||||||
|
#define EMC_PMACRO_TRAINING_CTRL_0_CH0_TRAINING_E_WRPTR (1 << 3)
|
||||||
|
|
||||||
#define EMC_PMACRO_TRAINING_CTRL_1 0xcfc
|
#define EMC_PMACRO_TRAINING_CTRL_1 0xcfc
|
||||||
|
#define EMC_PMACRO_TRAINING_CTRL_1_CH1_TRAINING_E_WRPTR (1 << 3)
|
||||||
|
|
||||||
#define EMC_PMC_SCRATCH1 0x440
|
#define EMC_PMC_SCRATCH1 0x440
|
||||||
#define EMC_PMC_SCRATCH2 0x444
|
#define EMC_PMC_SCRATCH2 0x444
|
||||||
#define EMC_PMC_SCRATCH3 0x448
|
#define EMC_PMC_SCRATCH3 0x448
|
||||||
|
|||||||
1089
fusee/fusee-secondary/src/emc.h
Normal file
1089
fusee/fusee-secondary/src/emc.h
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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");
|
fatal_error("kernel_patcher: unable to identify kernel!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (kernel_info == NULL && is_sd_kernel) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Apply hooks. */
|
/* Apply hooks. */
|
||||||
uint8_t *kernel = (uint8_t *)_kernel;
|
uint8_t *kernel = (uint8_t *)_kernel;
|
||||||
size_t free_space_offset = kernel_info->free_code_space_offset;
|
size_t free_space_offset = kernel_info->free_code_space_offset;
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
#include "loader.h"
|
#include "loader.h"
|
||||||
#include "chainloader.h"
|
#include "chainloader.h"
|
||||||
#include "stage2.h"
|
#include "stage2.h"
|
||||||
|
#include "mtc.h"
|
||||||
#include "nxboot.h"
|
#include "nxboot.h"
|
||||||
#include "console.h"
|
#include "console.h"
|
||||||
#include "fs_utils.h"
|
#include "fs_utils.h"
|
||||||
@@ -52,6 +53,9 @@ static void setup_env(void) {
|
|||||||
if (nxfs_mount_all() < 0) {
|
if (nxfs_mount_all() < 0) {
|
||||||
fatal_error("Failed to mount at least one parition: %s\n", strerror(errno));
|
fatal_error("Failed to mount at least one parition: %s\n", strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Train DRAM. */
|
||||||
|
train_dram();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cleanup_env(void) {
|
static void cleanup_env(void) {
|
||||||
|
|||||||
3750
fusee/fusee-secondary/src/mtc.c
Normal file
3750
fusee/fusee-secondary/src/mtc.c
Normal file
File diff suppressed because it is too large
Load Diff
759
fusee/fusee-secondary/src/mtc.h
Normal file
759
fusee/fusee-secondary/src/mtc.h
Normal 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
|
||||||
6189
fusee/fusee-secondary/src/mtc_tables.h
Normal file
6189
fusee/fusee-secondary/src/mtc_tables.h
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,4 @@
|
|||||||
KIPS := loader pm sm boot fs_mitm creport
|
KIPS := loader pm sm boot fs_mitm set_mitm creport
|
||||||
|
|
||||||
#TODO: boot2 ?
|
#TODO: boot2 ?
|
||||||
|
|
||||||
|
|||||||
@@ -5,9 +5,14 @@
|
|||||||
"main_thread_priority": 27,
|
"main_thread_priority": 27,
|
||||||
"default_cpu_id": 3,
|
"default_cpu_id": 3,
|
||||||
"process_category": 1,
|
"process_category": 1,
|
||||||
"kernel_capabilities" : {
|
"kernel_capabilities": [
|
||||||
"handle_table_size" : 128,
|
{
|
||||||
"syscalls" : {
|
"type": "handle_table_size",
|
||||||
|
"value": 128
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "syscalls",
|
||||||
|
"value": {
|
||||||
"svcSetHeapSize": "0x01",
|
"svcSetHeapSize": "0x01",
|
||||||
"svcSetMemoryPermission": "0x02",
|
"svcSetMemoryPermission": "0x02",
|
||||||
"svcSetMemoryAttribute": "0x03",
|
"svcSetMemoryAttribute": "0x03",
|
||||||
@@ -57,63 +62,109 @@
|
|||||||
"svcMapDeviceAddressSpaceAligned": "0x5A",
|
"svcMapDeviceAddressSpaceAligned": "0x5A",
|
||||||
"svcUnmapDeviceAddressSpace": "0x5C",
|
"svcUnmapDeviceAddressSpace": "0x5C",
|
||||||
"svcFlushProcessDataCache": "0x5F"
|
"svcFlushProcessDataCache": "0x5F"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"map" : {
|
{
|
||||||
|
"type": "map",
|
||||||
|
"value": {
|
||||||
"address": "0x50003000",
|
"address": "0x50003000",
|
||||||
"size": "0x1000",
|
"size": "0x1000",
|
||||||
"is_ro": false,
|
"is_ro": false,
|
||||||
"is_io": true
|
"is_io": true
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"map" : {
|
{
|
||||||
|
"type": "map",
|
||||||
|
"value": {
|
||||||
"address": "0x54200000",
|
"address": "0x54200000",
|
||||||
"size": "0x3000",
|
"size": "0x3000",
|
||||||
"is_ro": false,
|
"is_ro": false,
|
||||||
"is_io": true
|
"is_io": true
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"map" : {
|
{
|
||||||
|
"type": "map",
|
||||||
|
"value": {
|
||||||
"address": "0x54300000",
|
"address": "0x54300000",
|
||||||
"size": "0x1000",
|
"size": "0x1000",
|
||||||
"is_ro": false,
|
"is_ro": false,
|
||||||
"is_io": true
|
"is_io": true
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"map" : {
|
{
|
||||||
|
"type": "map",
|
||||||
|
"value": {
|
||||||
"address": "0x60006000",
|
"address": "0x60006000",
|
||||||
"size": "0x1000",
|
"size": "0x1000",
|
||||||
"is_ro": false,
|
"is_ro": false,
|
||||||
"is_io": true
|
"is_io": true
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"map" : {
|
{
|
||||||
|
"type": "map",
|
||||||
|
"value": {
|
||||||
"address": "0x6000D000",
|
"address": "0x6000D000",
|
||||||
"size": "0x1000",
|
"size": "0x1000",
|
||||||
"is_ro": false,
|
"is_ro": false,
|
||||||
"is_io": true
|
"is_io": true
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"map" : {
|
{
|
||||||
|
"type": "map",
|
||||||
|
"value": {
|
||||||
"address": "0x70000000",
|
"address": "0x70000000",
|
||||||
"size": "0x4000",
|
"size": "0x4000",
|
||||||
"is_ro": false,
|
"is_ro": false,
|
||||||
"is_io": true
|
"is_io": true
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"map" : {
|
{
|
||||||
|
"type": "map",
|
||||||
|
"value": {
|
||||||
"address": "0x7000C000",
|
"address": "0x7000C000",
|
||||||
"size": "0x2000",
|
"size": "0x2000",
|
||||||
"is_ro": false,
|
"is_ro": false,
|
||||||
"is_io": true
|
"is_io": true
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"map" : {
|
{
|
||||||
|
"type": "map",
|
||||||
|
"value": {
|
||||||
"address": "0x7000E000",
|
"address": "0x7000E000",
|
||||||
"size": "0x4000",
|
"size": "0x4000",
|
||||||
"is_ro": false,
|
"is_ro": false,
|
||||||
"is_io": true
|
"is_io": true
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"map" : {
|
{
|
||||||
|
"type": "map",
|
||||||
|
"value": {
|
||||||
"address": "0x700E3000",
|
"address": "0x700E3000",
|
||||||
"size": "0x1000",
|
"size": "0x1000",
|
||||||
"is_ro": false,
|
"is_ro": false,
|
||||||
"is_io": true
|
"is_io": true
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"irq_pair" : [70, 116],
|
{
|
||||||
"irq_pair" : [124, 152],
|
"type": "irq_pair",
|
||||||
"irq_pair" : [85, 95]
|
"value": [
|
||||||
|
70,
|
||||||
|
116
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "irq_pair",
|
||||||
|
"value": [
|
||||||
|
124,
|
||||||
|
152
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "irq_pair",
|
||||||
|
"value": [
|
||||||
|
85,
|
||||||
|
95
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
@@ -5,9 +5,14 @@
|
|||||||
"main_thread_priority": 27,
|
"main_thread_priority": 27,
|
||||||
"default_cpu_id": 3,
|
"default_cpu_id": 3,
|
||||||
"process_category": 1,
|
"process_category": 1,
|
||||||
"kernel_capabilities" : {
|
"kernel_capabilities": [
|
||||||
"handle_table_size" : 128,
|
{
|
||||||
"syscalls" : {
|
"type": "handle_table_size",
|
||||||
|
"value": 128
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "syscalls",
|
||||||
|
"value": {
|
||||||
"svcSetHeapSize": "0x01",
|
"svcSetHeapSize": "0x01",
|
||||||
"svcSetMemoryPermission": "0x02",
|
"svcSetMemoryPermission": "0x02",
|
||||||
"svcSetMemoryAttribute": "0x03",
|
"svcSetMemoryAttribute": "0x03",
|
||||||
@@ -60,57 +65,100 @@
|
|||||||
"svcMapDeviceAddressSpaceAligned": "0x5A",
|
"svcMapDeviceAddressSpaceAligned": "0x5A",
|
||||||
"svcUnmapDeviceAddressSpace": "0x5C",
|
"svcUnmapDeviceAddressSpace": "0x5C",
|
||||||
"svcFlushProcessDataCache": "0x5F"
|
"svcFlushProcessDataCache": "0x5F"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"map" : {
|
{
|
||||||
|
"type": "map",
|
||||||
|
"value": {
|
||||||
"address": "0x50003000",
|
"address": "0x50003000",
|
||||||
"size": "0x1000",
|
"size": "0x1000",
|
||||||
"is_ro": false,
|
"is_ro": false,
|
||||||
"is_io": true
|
"is_io": true
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"map" : {
|
{
|
||||||
|
"type": "map",
|
||||||
|
"value": {
|
||||||
"address": "0x54200000",
|
"address": "0x54200000",
|
||||||
"size": "0x3000",
|
"size": "0x3000",
|
||||||
"is_ro": false,
|
"is_ro": false,
|
||||||
"is_io": true
|
"is_io": true
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"map" : {
|
{
|
||||||
|
"type": "map",
|
||||||
|
"value": {
|
||||||
"address": "0x54300000",
|
"address": "0x54300000",
|
||||||
"size": "0x1000",
|
"size": "0x1000",
|
||||||
"is_ro": false,
|
"is_ro": false,
|
||||||
"is_io": true
|
"is_io": true
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"map" : {
|
{
|
||||||
|
"type": "map",
|
||||||
|
"value": {
|
||||||
"address": "0x60006000",
|
"address": "0x60006000",
|
||||||
"size": "0x1000",
|
"size": "0x1000",
|
||||||
"is_ro": false,
|
"is_ro": false,
|
||||||
"is_io": true
|
"is_io": true
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"map" : {
|
{
|
||||||
|
"type": "map",
|
||||||
|
"value": {
|
||||||
"address": "0x6000D000",
|
"address": "0x6000D000",
|
||||||
"size": "0x1000",
|
"size": "0x1000",
|
||||||
"is_ro": false,
|
"is_ro": false,
|
||||||
"is_io": true
|
"is_io": true
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"map" : {
|
{
|
||||||
|
"type": "map",
|
||||||
|
"value": {
|
||||||
"address": "0x70000000",
|
"address": "0x70000000",
|
||||||
"size": "0x4000",
|
"size": "0x4000",
|
||||||
"is_ro": false,
|
"is_ro": false,
|
||||||
"is_io": true
|
"is_io": true
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"map" : {
|
{
|
||||||
|
"type": "map",
|
||||||
|
"value": {
|
||||||
"address": "0x7000C000",
|
"address": "0x7000C000",
|
||||||
"size": "0x2000",
|
"size": "0x2000",
|
||||||
"is_ro": false,
|
"is_ro": false,
|
||||||
"is_io": true
|
"is_io": true
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"map" : {
|
{
|
||||||
|
"type": "map",
|
||||||
|
"value": {
|
||||||
"address": "0x700E3000",
|
"address": "0x700E3000",
|
||||||
"size": "0x1000",
|
"size": "0x1000",
|
||||||
"is_ro": false,
|
"is_ro": false,
|
||||||
"is_io": true
|
"is_io": true
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"irq_pair" : [70, 116],
|
{
|
||||||
"irq_pair" : [124, 152],
|
"type": "irq_pair",
|
||||||
"irq_pair" : [85, 95]
|
"value": [
|
||||||
|
70,
|
||||||
|
116
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "irq_pair",
|
||||||
|
"value": [
|
||||||
|
124,
|
||||||
|
152
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "irq_pair",
|
||||||
|
"value": [
|
||||||
|
85,
|
||||||
|
95
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
@@ -20,6 +20,7 @@
|
|||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
|
|
||||||
#include <switch.h>
|
#include <switch.h>
|
||||||
|
#include <atmosphere.h>
|
||||||
#include <stratosphere.hpp>
|
#include <stratosphere.hpp>
|
||||||
|
|
||||||
#define CAR_BASE 0x60006000
|
#define CAR_BASE 0x60006000
|
||||||
@@ -84,7 +85,7 @@ void __appInit(void) {
|
|||||||
|
|
||||||
fsdevMountSdmc();
|
fsdevMountSdmc();
|
||||||
|
|
||||||
CheckAtmosphereVersion();
|
CheckAtmosphereVersion(CURRENT_ATMOSPHERE_VERSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
void __appExit(void) {
|
void __appExit(void) {
|
||||||
|
|||||||
@@ -14,22 +14,29 @@
|
|||||||
"filesystem_access": {
|
"filesystem_access": {
|
||||||
"permissions": "0xFFFFFFFFFFFFFFFF"
|
"permissions": "0xFFFFFFFFFFFFFFFF"
|
||||||
},
|
},
|
||||||
"service_access": {
|
"service_host": [
|
||||||
"csrng": false,
|
"time:s"
|
||||||
"erpt:c": false,
|
],
|
||||||
"fatal:u": false,
|
"service_access": [
|
||||||
"ns:dev": false,
|
"csrng",
|
||||||
"fsp-srv": false,
|
"erpt:c",
|
||||||
"time:s": true
|
"fatal:u",
|
||||||
},
|
"ns:dev",
|
||||||
"kernel_capabilities": {
|
"fsp-srv"
|
||||||
"kernel_flags": {
|
],
|
||||||
|
"kernel_capabilities": [
|
||||||
|
{
|
||||||
|
"type": "kernel_flags",
|
||||||
|
"value": {
|
||||||
"highest_thread_priority": 63,
|
"highest_thread_priority": 63,
|
||||||
"lowest_thread_priority": 24,
|
"lowest_thread_priority": 24,
|
||||||
"lowest_cpu_id": 3,
|
"lowest_cpu_id": 3,
|
||||||
"highest_cpu_id": 3
|
"highest_cpu_id": 3
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"syscalls": {
|
{
|
||||||
|
"type": "syscalls",
|
||||||
|
"value": {
|
||||||
"svcSetHeapSize": "0x01",
|
"svcSetHeapSize": "0x01",
|
||||||
"svcSetMemoryPermission": "0x02",
|
"svcSetMemoryPermission": "0x02",
|
||||||
"svcSetMemoryAttribute": "0x03",
|
"svcSetMemoryAttribute": "0x03",
|
||||||
@@ -86,11 +93,18 @@
|
|||||||
"svcQueryDebugProcessMemory": "0x69",
|
"svcQueryDebugProcessMemory": "0x69",
|
||||||
"svcReadDebugProcessMemory": "0x6a",
|
"svcReadDebugProcessMemory": "0x6a",
|
||||||
"svcGetDebugThreadParam": "0x6d"
|
"svcGetDebugThreadParam": "0x6d"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"min_kernel_version": "0x0060",
|
{
|
||||||
"debug_flags": {
|
"type": "min_kernel_version",
|
||||||
|
"value": "0x0060"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "debug_flags",
|
||||||
|
"value": {
|
||||||
"allow_debug": false,
|
"allow_debug": false,
|
||||||
"force_debug": true
|
"force_debug": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
@@ -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;
|
u64 code_base;
|
||||||
|
|
||||||
/* Guess that either PC or LR will point to a code region. This could be false. */
|
/* Try to add the thread's PC. */
|
||||||
if (!TryFindCodeRegion(debug_handle, pc, &code_base) && !TryFindCodeRegion(debug_handle, lr, &code_base)) {
|
if (TryFindCodeRegion(debug_handle, thread->GetPC(), &code_base)) {
|
||||||
return;
|
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) {
|
while (this->code_count < max_code_count) {
|
||||||
MemoryInfo mi;
|
MemoryInfo mi;
|
||||||
u32 pi;
|
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) {
|
bool CodeList::TryFindCodeRegion(Handle debug_handle, u64 guess, u64 *address) {
|
||||||
MemoryInfo mi;
|
MemoryInfo mi;
|
||||||
u32 pi;
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
#include "creport_debug_types.hpp"
|
#include "creport_debug_types.hpp"
|
||||||
|
#include "creport_thread_info.hpp"
|
||||||
|
|
||||||
struct CodeInfo {
|
struct CodeInfo {
|
||||||
char name[0x20];
|
char name[0x20];
|
||||||
@@ -29,18 +30,19 @@ struct CodeInfo {
|
|||||||
|
|
||||||
class CodeList {
|
class CodeList {
|
||||||
private:
|
private:
|
||||||
static const size_t max_code_count = 0x10;
|
static const size_t max_code_count = 0x60;
|
||||||
u32 code_count = 0;
|
u32 code_count = 0;
|
||||||
CodeInfo code_infos[max_code_count];
|
CodeInfo code_infos[max_code_count];
|
||||||
|
|
||||||
/* For pretty-printing. */
|
/* For pretty-printing. */
|
||||||
char address_str_buf[0x280];
|
char address_str_buf[0x280];
|
||||||
public:
|
public:
|
||||||
void ReadCodeRegionsFromProcess(Handle debug_handle, u64 pc, u64 lr);
|
void ReadCodeRegionsFromThreadInfo(Handle debug_handle, const ThreadInfo *thread);
|
||||||
const char *GetFormattedAddressString(u64 address);
|
const char *GetFormattedAddressString(u64 address);
|
||||||
void SaveToFile(FILE *f_report);
|
void SaveToFile(FILE *f_report);
|
||||||
private:
|
private:
|
||||||
bool TryFindCodeRegion(Handle debug_handle, u64 guess, u64 *address);
|
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 GetCodeInfoName(u64 debug_handle, u64 rx_address, u64 ro_address, char *name);
|
||||||
void GetCodeInfoBuildId(u64 debug_handle, u64 ro_address, u8 *build_id);
|
void GetCodeInfoBuildId(u64 debug_handle, u64 ro_address, u8 *build_id);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ void CrashReport::BuildReport(u64 pid, bool has_extra_info) {
|
|||||||
this->has_extra_info = has_extra_info;
|
this->has_extra_info = has_extra_info;
|
||||||
if (OpenProcess(pid)) {
|
if (OpenProcess(pid)) {
|
||||||
ProcessExceptions();
|
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->thread_list.ReadThreadsFromProcess(this->debug_handle, Is64Bit());
|
||||||
this->crashed_thread_info.SetCodeList(&this->code_list);
|
this->crashed_thread_info.SetCodeList(&this->code_list);
|
||||||
this->thread_list.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();
|
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. */
|
/* Real creport builds the report here. We do it later. */
|
||||||
|
|
||||||
Close();
|
Close();
|
||||||
@@ -258,7 +263,7 @@ void CrashReport::SaveReport() {
|
|||||||
|
|
||||||
void CrashReport::SaveToFile(FILE *f_report) {
|
void CrashReport::SaveToFile(FILE *f_report) {
|
||||||
char buf[0x10] = {0};
|
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));
|
fprintf(f_report, "Result: 0x%X (2%03d-%04d)\n\n", this->result, R_MODULE(this->result), R_DESCRIPTION(this->result));
|
||||||
|
|
||||||
/* Process Info. */
|
/* Process Info. */
|
||||||
|
|||||||
@@ -19,7 +19,8 @@
|
|||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
#include "creport_debug_types.hpp"
|
#include "creport_debug_types.hpp"
|
||||||
#include "creport_code_info.hpp"
|
|
||||||
|
class CodeList;
|
||||||
|
|
||||||
class ThreadInfo {
|
class ThreadInfo {
|
||||||
private:
|
private:
|
||||||
@@ -31,9 +32,11 @@ class ThreadInfo {
|
|||||||
u32 stack_trace_size = 0;
|
u32 stack_trace_size = 0;
|
||||||
CodeList *code_list;
|
CodeList *code_list;
|
||||||
public:
|
public:
|
||||||
u64 GetPC() { return context.pc.x; }
|
u64 GetPC() const { return context.pc.x; }
|
||||||
u64 GetLR() { return context.lr; }
|
u64 GetLR() const { return context.lr; }
|
||||||
u64 GetId() { return thread_id; }
|
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);
|
bool ReadFromProcess(Handle debug_handle, u64 thread_id, bool is_64_bit);
|
||||||
void SaveToFile(FILE *f_report);
|
void SaveToFile(FILE *f_report);
|
||||||
@@ -49,6 +52,9 @@ class ThreadList {
|
|||||||
u32 thread_count = 0;
|
u32 thread_count = 0;
|
||||||
ThreadInfo thread_infos[max_thread_count];
|
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 SaveToFile(FILE *f_report);
|
||||||
void DumpBinary(FILE *f_bin, u64 crashed_id);
|
void DumpBinary(FILE *f_bin, u64 crashed_id);
|
||||||
void ReadThreadsFromProcess(Handle debug_handle, bool is_64_bit);
|
void ReadThreadsFromProcess(Handle debug_handle, bool is_64_bit);
|
||||||
|
|||||||
@@ -5,9 +5,14 @@
|
|||||||
"main_thread_priority": 43,
|
"main_thread_priority": 43,
|
||||||
"default_cpu_id": 3,
|
"default_cpu_id": 3,
|
||||||
"process_category": 1,
|
"process_category": 1,
|
||||||
"kernel_capabilities" : {
|
"kernel_capabilities": [
|
||||||
"handle_table_size" : 512,
|
{
|
||||||
"syscalls": {
|
"type": "handle_table_size",
|
||||||
|
"value": 512
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "syscalls",
|
||||||
|
"value": {
|
||||||
"svcSetHeapSize": "0x01",
|
"svcSetHeapSize": "0x01",
|
||||||
"svcSetMemoryPermission": "0x02",
|
"svcSetMemoryPermission": "0x02",
|
||||||
"svcSetMemoryAttribute": "0x03",
|
"svcSetMemoryAttribute": "0x03",
|
||||||
@@ -58,6 +63,7 @@
|
|||||||
"svcReplyAndReceiveWithUserBuffer": "0x44",
|
"svcReplyAndReceiveWithUserBuffer": "0x44",
|
||||||
"svcCreateEvent": "0x45",
|
"svcCreateEvent": "0x45",
|
||||||
"svcCreateInterruptEvent": "0x53",
|
"svcCreateInterruptEvent": "0x53",
|
||||||
|
"svcReadWriteRegister": "0x4E",
|
||||||
"svcQueryIoMapping": "0x55",
|
"svcQueryIoMapping": "0x55",
|
||||||
"svcCreateDeviceAddressSpace": "0x56",
|
"svcCreateDeviceAddressSpace": "0x56",
|
||||||
"svcAttachDeviceAddressSpace": "0x57",
|
"svcAttachDeviceAddressSpace": "0x57",
|
||||||
@@ -67,4 +73,5 @@
|
|||||||
"svcGetSystemInfo": "0x6f"
|
"svcGetSystemInfo": "0x6f"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
@@ -24,7 +24,5 @@ void Reboot() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Log(const void *data, int size) {
|
void Log(const void *data, int size) {
|
||||||
(void)(data);
|
|
||||||
(void)(size);
|
|
||||||
/* ... */
|
/* ... */
|
||||||
}
|
}
|
||||||
@@ -21,21 +21,19 @@
|
|||||||
|
|
||||||
#include "debug.hpp"
|
#include "debug.hpp"
|
||||||
|
|
||||||
enum class FsIStorageCmd {
|
enum FsIStorageCmd : u32 {
|
||||||
Read = 0,
|
FsIStorageCmd_Read = 0,
|
||||||
Write = 1,
|
FsIStorageCmd_Write = 1,
|
||||||
Flush = 2,
|
FsIStorageCmd_Flush = 2,
|
||||||
SetSize = 3,
|
FsIStorageCmd_SetSize = 3,
|
||||||
GetSize = 4,
|
FsIStorageCmd_GetSize = 4,
|
||||||
OperateRange = 5,
|
FsIStorageCmd_OperateRange = 5,
|
||||||
};
|
};
|
||||||
|
|
||||||
class IStorage {
|
class IStorage {
|
||||||
public:
|
public:
|
||||||
virtual ~IStorage();
|
virtual ~IStorage();
|
||||||
|
|
||||||
virtual IStorage *Clone() = 0;
|
|
||||||
|
|
||||||
virtual Result Read(void *buffer, size_t size, u64 offset) = 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 Write(void *buffer, size_t size, u64 offset) = 0;
|
||||||
virtual Result Flush() = 0;
|
virtual Result Flush() = 0;
|
||||||
@@ -52,87 +50,58 @@ class IStorageInterface : public IServiceObject {
|
|||||||
/* ... */
|
/* ... */
|
||||||
};
|
};
|
||||||
|
|
||||||
IStorageInterface *clone() override {
|
|
||||||
return new IStorageInterface(this->base_storage->Clone());
|
|
||||||
}
|
|
||||||
|
|
||||||
~IStorageInterface() {
|
~IStorageInterface() {
|
||||||
delete base_storage;
|
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:
|
private:
|
||||||
/* Actual command API. */
|
/* Actual command API. */
|
||||||
virtual std::tuple<Result> read(OutBuffer<u8, BufferType_Type1> buffer, u64 offset, u64 size) final {
|
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)};
|
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 {
|
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)};
|
return this->base_storage->Write(buffer.buffer, std::min(buffer.num_elements, size), offset);
|
||||||
|
|
||||||
};
|
};
|
||||||
virtual std::tuple<Result> flush() final {
|
virtual Result Flush() final {
|
||||||
return {this->base_storage->Flush()};
|
return this->base_storage->Flush();
|
||||||
};
|
};
|
||||||
virtual std::tuple<Result> set_size(u64 size) final {
|
virtual Result SetSize(u64 size) final {
|
||||||
return {this->base_storage->SetSize(size)};
|
return this->base_storage->SetSize(size);
|
||||||
};
|
};
|
||||||
virtual std::tuple<Result, u64> get_size() final {
|
virtual Result GetSize(Out<u64> size) final {
|
||||||
u64 out_size = 0;
|
return this->base_storage->GetSize(size.GetPointer());
|
||||||
Result rc = this->base_storage->GetSize(&out_size);
|
|
||||||
return {rc, out_size};
|
|
||||||
};
|
};
|
||||||
virtual std::tuple<Result, FsRangeInfo> operate_range(u32 operation_type, u64 offset, u64 size) final {
|
virtual Result OperateRange(Out<FsRangeInfo> range_info, u32 operation_type, u64 offset, u64 size) final {
|
||||||
FsRangeInfo out_range_info = {0};
|
return this->base_storage->OperateRange(operation_type, offset, size, range_info.GetPointer());
|
||||||
Result rc = this->base_storage->OperateRange(operation_type, offset, size, &out_range_info);
|
};
|
||||||
return {rc, out_range_info};
|
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 {
|
class IROStorage : public IStorage {
|
||||||
public:
|
public:
|
||||||
virtual Result Read(void *buffer, size_t size, u64 offset) = 0;
|
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)(buffer);
|
||||||
(void)(offset);
|
(void)(offset);
|
||||||
(void)(size);
|
(void)(size);
|
||||||
return 0x313802;
|
return 0x313802;
|
||||||
};
|
};
|
||||||
Result Flush() final {
|
virtual Result Flush() final {
|
||||||
return 0x0;
|
return 0x0;
|
||||||
};
|
};
|
||||||
Result SetSize(u64 size) final {
|
virtual Result SetSize(u64 size) final {
|
||||||
(void)(size);
|
(void)(size);
|
||||||
return 0x313802;
|
return 0x313802;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -46,6 +46,11 @@ LayeredRomFS::LayeredRomFS(std::shared_ptr<RomInterfaceStorage> s_r, std::shared
|
|||||||
|
|
||||||
|
|
||||||
Result LayeredRomFS::Read(void *buffer, size_t size, u64 offset) {
|
Result LayeredRomFS::Read(void *buffer, size_t size, u64 offset) {
|
||||||
|
/* Size zero reads should always succeed. */
|
||||||
|
if (size == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Validate size. */
|
/* 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;
|
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) {
|
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);
|
cur_read_size = cur_source->size - (offset - cur_source->virtual_offset);
|
||||||
}
|
}
|
||||||
switch (cur_source->type) {
|
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:
|
case RomFSDataSource::LooseFile:
|
||||||
{
|
{
|
||||||
FsFile file;
|
FsFile file;
|
||||||
|
|||||||
@@ -33,15 +33,11 @@ class LayeredRomFS : public IROStorage {
|
|||||||
u64 title_id;
|
u64 title_id;
|
||||||
std::shared_ptr<std::vector<RomFSSourceInfo>> p_source_infos;
|
std::shared_ptr<std::vector<RomFSSourceInfo>> p_source_infos;
|
||||||
|
|
||||||
LayeredRomFS *Clone() override {
|
|
||||||
return new LayeredRomFS(*this);
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
LayeredRomFS(std::shared_ptr<RomInterfaceStorage> s_r, std::shared_ptr<RomFileStorage> f_r, u64 tid);
|
LayeredRomFS(std::shared_ptr<RomInterfaceStorage> s_r, std::shared_ptr<RomFileStorage> f_r, u64 tid);
|
||||||
virtual ~LayeredRomFS() = default;
|
virtual ~LayeredRomFS() = default;
|
||||||
|
|
||||||
Result Read(void *buffer, size_t size, u64 offset) override;
|
virtual Result Read(void *buffer, size_t size, u64 offset) override;
|
||||||
Result GetSize(u64 *out_size) override;
|
virtual Result GetSize(u64 *out_size) override;
|
||||||
Result OperateRange(u32 operation_type, u64 offset, u64 size, FsRangeInfo *out_range_info) override;
|
virtual Result OperateRange(u32 operation_type, u64 offset, u64 size, FsRangeInfo *out_range_info) override;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -20,15 +20,10 @@
|
|||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
|
|
||||||
#include <switch.h>
|
#include <switch.h>
|
||||||
|
#include <atmosphere.h>
|
||||||
#include <stratosphere.hpp>
|
#include <stratosphere.hpp>
|
||||||
|
|
||||||
#include "sm_mitm.h"
|
|
||||||
|
|
||||||
#include "mitm_server.hpp"
|
|
||||||
#include "fsmitm_service.hpp"
|
#include "fsmitm_service.hpp"
|
||||||
#include "fsmitm_worker.hpp"
|
|
||||||
|
|
||||||
#include "mitm_query_service.hpp"
|
|
||||||
|
|
||||||
#include "fsmitm_utils.hpp"
|
#include "fsmitm_utils.hpp"
|
||||||
|
|
||||||
@@ -67,41 +62,33 @@ void __appInit(void) {
|
|||||||
fatalSimple(MAKERESULT(Module_Libnx, LibnxError_InitFail_SM));
|
fatalSimple(MAKERESULT(Module_Libnx, LibnxError_InitFail_SM));
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = smMitMInitialize();
|
|
||||||
if (R_FAILED(rc)) {
|
|
||||||
fatalSimple(MAKERESULT(Module_Libnx, LibnxError_InitFail_SM));
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = fsInitialize();
|
rc = fsInitialize();
|
||||||
if (R_FAILED(rc)) {
|
if (R_FAILED(rc)) {
|
||||||
fatalSimple(MAKERESULT(Module_Libnx, LibnxError_InitFail_FS));
|
fatalSimple(MAKERESULT(Module_Libnx, LibnxError_InitFail_FS));
|
||||||
}
|
}
|
||||||
CheckAtmosphereVersion();
|
|
||||||
|
CheckAtmosphereVersion(CURRENT_ATMOSPHERE_VERSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
void __appExit(void) {
|
void __appExit(void) {
|
||||||
/* Cleanup services. */
|
/* Cleanup services. */
|
||||||
fsExit();
|
fsExit();
|
||||||
smMitMExit();
|
|
||||||
smExit();
|
smExit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct FsMitmManagerOptions {
|
||||||
|
static const size_t PointerBufferSize = 0x800;
|
||||||
|
static const size_t MaxDomains = 0x10;
|
||||||
|
static const size_t MaxDomainObjects = 0x4000;
|
||||||
|
};
|
||||||
|
using FsMitmManager = WaitableManager<FsMitmManagerOptions>;
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
Thread worker_thread = {0};
|
|
||||||
Thread sd_initializer_thread = {0};
|
Thread sd_initializer_thread = {0};
|
||||||
Thread hid_initializer_thread = {0};
|
Thread hid_initializer_thread = {0};
|
||||||
consoleDebugInit(debugDevice_SVC);
|
consoleDebugInit(debugDevice_SVC);
|
||||||
|
|
||||||
consoleDebugInit(debugDevice_SVC);
|
|
||||||
|
|
||||||
if (R_FAILED(threadCreate(&worker_thread, &FsMitMWorker::Main, NULL, 0x20000, 45, 0))) {
|
|
||||||
/* TODO: Panic. */
|
|
||||||
}
|
|
||||||
if (R_FAILED(threadStart(&worker_thread))) {
|
|
||||||
/* TODO: Panic. */
|
|
||||||
}
|
|
||||||
|
|
||||||
if (R_FAILED(threadCreate(&sd_initializer_thread, &Utils::InitializeSdThreadFunc, NULL, 0x4000, 0x15, 0))) {
|
if (R_FAILED(threadCreate(&sd_initializer_thread, &Utils::InitializeSdThreadFunc, NULL, 0x4000, 0x15, 0))) {
|
||||||
/* TODO: Panic. */
|
/* TODO: Panic. */
|
||||||
}
|
}
|
||||||
@@ -117,17 +104,15 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: What's a good timeout value to use here? */
|
/* TODO: What's a good timeout value to use here? */
|
||||||
auto server_manager = std::make_unique<MultiThreadedWaitableManager>(5, U64_MAX, 0x20000);
|
auto server_manager = new FsMitmManager(5);
|
||||||
//auto server_manager = std::make_unique<WaitableManager>(U64_MAX);
|
|
||||||
|
|
||||||
/* Create fsp-srv mitm. */
|
/* Create fsp-srv mitm. */
|
||||||
ISession<MitMQueryService<FsMitMService>> *fs_query_srv = NULL;
|
AddMitmServerToManager<FsMitmService>(server_manager, "fsp-srv", 61);
|
||||||
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);
|
|
||||||
|
|
||||||
/* Loop forever, servicing our services. */
|
/* Loop forever, servicing our services. */
|
||||||
server_manager->process();
|
server_manager->Process();
|
||||||
|
|
||||||
|
delete server_manager;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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_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;
|
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. */
|
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. */
|
||||||
FsFileSystem sd_fs;
|
if (R_SUCCEEDED(Utils::SaveSdFileForAtmosphere(this->title_id, ROMFS_METADATA_FILE_PATH, metadata, metadata_size))) {
|
||||||
if (R_SUCCEEDED(fsMountSdcard(&sd_fs))) {
|
out_infos->emplace_back(header->dir_hash_table_ofs, metadata_size, RomFSDataSource::MetaData);
|
||||||
FsFile f;
|
delete metadata;
|
||||||
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);
|
} else {
|
||||||
if (R_SUCCEEDED(fsFsOpenFile(&sd_fs, "/METADATALOG.bin", FS_OPEN_READ | FS_OPEN_WRITE, &f))) {
|
out_infos->emplace_back(header->dir_hash_table_ofs, metadata_size, metadata, RomFSDataSource::Memory);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
out_infos->emplace_back(header->dir_hash_table_ofs, this->dir_hash_table_size + this->dir_table_size + this->file_hash_table_size + this->file_table_size, metadata, RomFSDataSource::Memory);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,11 +25,14 @@
|
|||||||
#define ROMFS_ENTRY_EMPTY 0xFFFFFFFF
|
#define ROMFS_ENTRY_EMPTY 0xFFFFFFFF
|
||||||
#define ROMFS_FILEPARTITION_OFS 0x200
|
#define ROMFS_FILEPARTITION_OFS 0x200
|
||||||
|
|
||||||
|
#define ROMFS_METADATA_FILE_PATH "romfs_metadata.bin"
|
||||||
|
|
||||||
/* Types for RomFS Meta construction. */
|
/* Types for RomFS Meta construction. */
|
||||||
enum class RomFSDataSource {
|
enum class RomFSDataSource {
|
||||||
BaseRomFS,
|
BaseRomFS,
|
||||||
FileRomFS,
|
FileRomFS,
|
||||||
LooseFile,
|
LooseFile,
|
||||||
|
MetaData,
|
||||||
Memory,
|
Memory,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -49,6 +52,10 @@ struct RomFSMemorySourceInfo {
|
|||||||
const u8 *data;
|
const u8 *data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct RomFSMetaDataSourceInfo {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
struct RomFSSourceInfo {
|
struct RomFSSourceInfo {
|
||||||
u64 virtual_offset;
|
u64 virtual_offset;
|
||||||
u64 size;
|
u64 size;
|
||||||
@@ -57,6 +64,7 @@ struct RomFSSourceInfo {
|
|||||||
RomFSFileSourceInfo file_source_info;
|
RomFSFileSourceInfo file_source_info;
|
||||||
RomFSLooseSourceInfo loose_source_info;
|
RomFSLooseSourceInfo loose_source_info;
|
||||||
RomFSMemorySourceInfo memory_source_info;
|
RomFSMemorySourceInfo memory_source_info;
|
||||||
|
RomFSMemorySourceInfo metadata_source_info;
|
||||||
};
|
};
|
||||||
RomFSDataSource type;
|
RomFSDataSource type;
|
||||||
|
|
||||||
@@ -69,6 +77,7 @@ struct RomFSSourceInfo {
|
|||||||
this->file_source_info.offset = offset;
|
this->file_source_info.offset = offset;
|
||||||
break;
|
break;
|
||||||
case RomFSDataSource::LooseFile:
|
case RomFSDataSource::LooseFile:
|
||||||
|
case RomFSDataSource::MetaData:
|
||||||
case RomFSDataSource::Memory:
|
case RomFSDataSource::Memory:
|
||||||
default:
|
default:
|
||||||
fatalSimple(0xF601);
|
fatalSimple(0xF601);
|
||||||
@@ -83,6 +92,20 @@ struct RomFSSourceInfo {
|
|||||||
case RomFSDataSource::Memory:
|
case RomFSDataSource::Memory:
|
||||||
this->memory_source_info.data = (decltype(this->memory_source_info.data))arg;
|
this->memory_source_info.data = (decltype(this->memory_source_info.data))arg;
|
||||||
break;
|
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::BaseRomFS:
|
||||||
case RomFSDataSource::FileRomFS:
|
case RomFSDataSource::FileRomFS:
|
||||||
default:
|
default:
|
||||||
@@ -94,6 +117,7 @@ struct RomFSSourceInfo {
|
|||||||
switch (this->type) {
|
switch (this->type) {
|
||||||
case RomFSDataSource::BaseRomFS:
|
case RomFSDataSource::BaseRomFS:
|
||||||
case RomFSDataSource::FileRomFS:
|
case RomFSDataSource::FileRomFS:
|
||||||
|
case RomFSDataSource::MetaData:
|
||||||
break;
|
break;
|
||||||
case RomFSDataSource::LooseFile:
|
case RomFSDataSource::LooseFile:
|
||||||
delete this->loose_source_info.path;
|
delete this->loose_source_info.path;
|
||||||
|
|||||||
@@ -35,10 +35,6 @@ class RomFileStorage : public IROStorage {
|
|||||||
fsFileClose(base_file);
|
fsFileClose(base_file);
|
||||||
delete base_file;
|
delete base_file;
|
||||||
};
|
};
|
||||||
|
|
||||||
RomFileStorage *Clone() override {
|
|
||||||
return new RomFileStorage(this->base_file);
|
|
||||||
};
|
|
||||||
public:
|
public:
|
||||||
Result Read(void *buffer, size_t size, u64 offset) override {
|
Result Read(void *buffer, size_t size, u64 offset) override {
|
||||||
size_t out_sz = 0;
|
size_t out_sz = 0;
|
||||||
@@ -72,10 +68,6 @@ class RomInterfaceStorage : public IROStorage {
|
|||||||
fsStorageClose(base_storage);
|
fsStorageClose(base_storage);
|
||||||
delete base_storage;
|
delete base_storage;
|
||||||
};
|
};
|
||||||
|
|
||||||
RomInterfaceStorage *Clone() override {
|
|
||||||
return new RomInterfaceStorage(this->base_storage);
|
|
||||||
};
|
|
||||||
public:
|
public:
|
||||||
Result Read(void *buffer, size_t size, u64 offset) override {
|
Result Read(void *buffer, size_t size, u64 offset) override {
|
||||||
return fsStorageRead(this->base_storage, offset, buffer, size);
|
return fsStorageRead(this->base_storage, offset, buffer, size);
|
||||||
|
|||||||
@@ -14,150 +14,194 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
#include <switch.h>
|
#include <switch.h>
|
||||||
|
#include <stratosphere.hpp>
|
||||||
#include "fsmitm_service.hpp"
|
#include "fsmitm_service.hpp"
|
||||||
#include "fs_shim.h"
|
#include "fs_shim.h"
|
||||||
|
|
||||||
#include "fsmitm_worker.hpp"
|
|
||||||
#include "fsmitm_utils.hpp"
|
#include "fsmitm_utils.hpp"
|
||||||
#include "fsmitm_romstorage.hpp"
|
#include "fsmitm_romstorage.hpp"
|
||||||
#include "fsmitm_layeredrom.hpp"
|
#include "fsmitm_layeredrom.hpp"
|
||||||
|
|
||||||
#include "mitm_query_service.hpp"
|
|
||||||
#include "debug.hpp"
|
#include "debug.hpp"
|
||||||
|
|
||||||
Result FsMitMService::dispatch(IpcParsedCommand &r, IpcCommand &out_c, u64 cmd_id, u8 *pointer_buffer, size_t pointer_buffer_size) {
|
static HosMutex g_StorageCacheLock;
|
||||||
Result rc = 0xF601;
|
static std::unordered_map<u64, std::weak_ptr<IStorageInterface>> g_StorageCache;
|
||||||
if (this->has_initialized) {
|
|
||||||
switch (static_cast<FspSrvCmd>(cmd_id)) {
|
static bool StorageCacheGetEntry(u64 title_id, std::shared_ptr<IStorageInterface> *out) {
|
||||||
case FspSrvCmd::OpenDataStorageByCurrentProcess:
|
std::scoped_lock<HosMutex> lock(g_StorageCacheLock);
|
||||||
rc = WrapIpcCommandImpl<&FsMitMService::open_data_storage_by_current_process>(this, r, out_c, pointer_buffer, pointer_buffer_size);
|
if (g_StorageCache.find(title_id) == g_StorageCache.end()) {
|
||||||
break;
|
return false;
|
||||||
case FspSrvCmd::OpenDataStorageByDataId:
|
|
||||||
rc = WrapIpcCommandImpl<&FsMitMService::open_data_storage_by_data_id>(this, r, out_c, pointer_buffer, pointer_buffer_size);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (static_cast<FspSrvCmd>(cmd_id) == FspSrvCmd::SetCurrentProcess) {
|
|
||||||
if (r.HasPid) {
|
|
||||||
this->init_pid = r.Pid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return rc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FsMitMService::postprocess(IpcParsedCommand &r, IpcCommand &out_c, u64 cmd_id, u8 *pointer_buffer, size_t pointer_buffer_size) {
|
auto intf = g_StorageCache[title_id].lock();
|
||||||
struct {
|
if (intf != nullptr) {
|
||||||
u64 magic;
|
*out = intf;
|
||||||
u64 result;
|
return true;
|
||||||
} *resp = (decltype(resp))r.Raw;
|
|
||||||
|
|
||||||
u64 *tls = (u64 *)armGetTls();
|
|
||||||
std::array<u64, 0x100/sizeof(u64)> backup_tls;
|
|
||||||
std::copy(tls, tls + backup_tls.size(), backup_tls.begin());
|
|
||||||
|
|
||||||
Result rc = (Result)resp->result;
|
|
||||||
switch (static_cast<FspSrvCmd>(cmd_id)) {
|
|
||||||
case FspSrvCmd::SetCurrentProcess:
|
|
||||||
if (R_SUCCEEDED(rc)) {
|
|
||||||
this->has_initialized = true;
|
|
||||||
}
|
}
|
||||||
this->process_id = this->init_pid;
|
return false;
|
||||||
this->title_id = this->process_id;
|
}
|
||||||
if (R_FAILED(MitMQueryUtils::get_associated_tid_for_pid(this->process_id, &this->title_id))) {
|
|
||||||
|
static void StorageCacheSetEntry(u64 title_id, std::shared_ptr<IStorageInterface> *ptr) {
|
||||||
|
std::scoped_lock<HosMutex> lock(g_StorageCacheLock);
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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. */
|
/* Log here, if desired. */
|
||||||
}
|
}
|
||||||
std::copy(backup_tls.begin(), backup_tls.end(), tls);
|
break;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
resp->result = rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
Result FsMitMService::handle_deferred() {
|
|
||||||
/* This service is never deferrable. */
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add redirection for RomFS to the SD card. */
|
/* Add redirection for RomFS to the SD card. */
|
||||||
std::tuple<Result, OutSession<IStorageInterface>> FsMitMService::open_data_storage_by_current_process() {
|
Result FsMitmService::OpenDataStorageByCurrentProcess(Out<std::shared_ptr<IStorageInterface>> out_storage) {
|
||||||
IPCSession<IStorageInterface> *out_session = NULL;
|
std::shared_ptr<IStorageInterface> storage = nullptr;
|
||||||
std::shared_ptr<IStorageInterface> out_storage = nullptr;
|
|
||||||
u32 out_domain_id = 0;
|
u32 out_domain_id = 0;
|
||||||
Result rc;
|
Result rc = 0;
|
||||||
if (this->romfs_storage != nullptr) {
|
|
||||||
if (this->get_owner() != NULL) {
|
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};
|
FsStorage s = {0};
|
||||||
rc = fsOpenDataStorageByCurrentProcessFwd(this->forward_service, &s);
|
rc = fsOpenDataStorageByCurrentProcessFwd(this->forward_service.get(), &s);
|
||||||
if (R_SUCCEEDED(rc)) {
|
if (R_SUCCEEDED(rc)) {
|
||||||
out_domain_id = s.s.object_id;
|
out_domain_id = s.s.object_id;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
rc = 0;
|
rc = 0;
|
||||||
}
|
}
|
||||||
if (R_SUCCEEDED(rc)) {
|
if (R_FAILED(rc)) {
|
||||||
out_storage = this->romfs_storage;
|
storage.reset();
|
||||||
out_session = new IPCSession<IStorageInterface>(out_storage);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
FsStorage data_storage;
|
FsStorage data_storage;
|
||||||
FsFile data_file;
|
FsFile data_file;
|
||||||
|
|
||||||
rc = fsOpenDataStorageByCurrentProcessFwd(this->forward_service, &data_storage);
|
rc = fsOpenDataStorageByCurrentProcessFwd(this->forward_service.get(), &data_storage);
|
||||||
|
|
||||||
Log(armGetTls(), 0x100);
|
Log(armGetTls(), 0x100);
|
||||||
if (R_SUCCEEDED(rc)) {
|
if (R_SUCCEEDED(rc)) {
|
||||||
|
if (Utils::HasSdRomfsContent(this->title_id)) {
|
||||||
/* TODO: Is there a sensible path that ends in ".romfs" we can use?" */
|
/* 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))) {
|
if (R_SUCCEEDED(Utils::OpenSdFileForAtmosphere(this->title_id, "romfs.bin", FS_OPEN_READ, &data_file))) {
|
||||||
out_storage = std::make_shared<IStorageInterface>(new LayeredRomFS(std::make_shared<RomInterfaceStorage>(data_storage), std::make_shared<RomFileStorage>(data_file), this->title_id));
|
storage = std::make_shared<IStorageInterface>(new LayeredRomFS(std::make_shared<RomInterfaceStorage>(data_storage), std::make_shared<RomFileStorage>(data_file), this->title_id));
|
||||||
} else {
|
} else {
|
||||||
out_storage = std::make_shared<IStorageInterface>(new LayeredRomFS(std::make_shared<RomInterfaceStorage>(data_storage), nullptr, this->title_id));
|
storage = std::make_shared<IStorageInterface>(new LayeredRomFS(std::make_shared<RomInterfaceStorage>(data_storage), nullptr, this->title_id));
|
||||||
}
|
}
|
||||||
this->romfs_storage = out_storage;
|
if (out_storage.IsDomain()) {
|
||||||
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;
|
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);
|
return rc;
|
||||||
out_s.domain_id = out_domain_id;
|
|
||||||
return {rc, out_s};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add redirection for System Data Archives to the SD card. */
|
/* 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;
|
FsStorageId storage_id = (FsStorageId)sid;
|
||||||
IPCSession<IStorageInterface> *out_session = NULL;
|
|
||||||
FsStorage data_storage;
|
FsStorage data_storage;
|
||||||
FsFile data_file;
|
FsFile data_file;
|
||||||
u32 out_domain_id = 0;
|
|
||||||
Result rc;
|
|
||||||
|
|
||||||
rc = fsOpenDataStorageByDataIdFwd(this->forward_service, storage_id, data_id, &data_storage);
|
std::shared_ptr<IStorageInterface> storage = nullptr;
|
||||||
|
u32 out_domain_id = 0;
|
||||||
|
Result rc = 0;
|
||||||
|
|
||||||
|
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 (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 {
|
||||||
|
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 (R_SUCCEEDED(rc)) {
|
||||||
|
if (Utils::HasSdRomfsContent(data_id)) {
|
||||||
/* TODO: Is there a sensible path that ends in ".romfs" we can use?" */
|
/* 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))) {
|
if (R_SUCCEEDED(Utils::OpenSdFileForAtmosphere(data_id, "romfs.bin", FS_OPEN_READ, &data_file))) {
|
||||||
out_session = new IPCSession<IStorageInterface>(std::make_shared<IStorageInterface>(new LayeredRomFS(std::make_shared<RomInterfaceStorage>(data_storage), std::make_shared<RomFileStorage>(data_file), data_id)));
|
storage = std::make_shared<IStorageInterface>(new LayeredRomFS(std::make_shared<RomInterfaceStorage>(data_storage), std::make_shared<RomFileStorage>(data_file), data_id));
|
||||||
} else {
|
} else {
|
||||||
out_session = new IPCSession<IStorageInterface>(std::make_shared<IStorageInterface>(new LayeredRomFS(std::make_shared<RomInterfaceStorage>(data_storage), nullptr, data_id)));
|
storage = std::make_shared<IStorageInterface>(new LayeredRomFS(std::make_shared<RomInterfaceStorage>(data_storage), nullptr, data_id));
|
||||||
}
|
}
|
||||||
if (this->get_owner() == NULL) {
|
if (out_storage.IsDomain()) {
|
||||||
FsMitMWorker::AddWaitable(out_session);
|
|
||||||
} else {
|
|
||||||
out_domain_id = data_storage.s.object_id;
|
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);
|
return rc;
|
||||||
out_s.domain_id = out_domain_id;
|
|
||||||
return {rc, out_s};
|
|
||||||
}
|
}
|
||||||
@@ -16,52 +16,40 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <switch.h>
|
#include <switch.h>
|
||||||
#include <stratosphere/iserviceobject.hpp>
|
#include <stratosphere.hpp>
|
||||||
#include "imitmserviceobject.hpp"
|
|
||||||
#include "fs_istorage.hpp"
|
#include "fs_istorage.hpp"
|
||||||
#include "fsmitm_utils.hpp"
|
#include "fsmitm_utils.hpp"
|
||||||
|
|
||||||
enum class FspSrvCmd {
|
enum FspSrvCmd : u32 {
|
||||||
SetCurrentProcess = 1,
|
FspSrvCmd_SetCurrentProcess = 1,
|
||||||
OpenDataStorageByCurrentProcess = 200,
|
FspSrvCmd_OpenDataStorageByCurrentProcess = 200,
|
||||||
OpenDataStorageByDataId = 202,
|
FspSrvCmd_OpenDataStorageByDataId = 202,
|
||||||
};
|
};
|
||||||
|
|
||||||
class FsMitMService : public IMitMServiceObject {
|
class FsMitmService : public IMitmServiceObject {
|
||||||
private:
|
private:
|
||||||
bool has_initialized = false;
|
bool has_initialized = false;
|
||||||
u64 init_pid = 0;
|
|
||||||
std::shared_ptr<IStorageInterface> romfs_storage;
|
|
||||||
public:
|
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)) {
|
if (Utils::HasSdDisableMitMFlag(tid)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return (tid >= 0x0100000000010000ULL || Utils::HasSdMitMFlag(tid)) && Utils::HasOverrideButton(tid);
|
return (tid >= 0x0100000000010000ULL || Utils::HasSdMitMFlag(tid)) && Utils::HasOverrideButton(tid);
|
||||||
}
|
}
|
||||||
|
|
||||||
FsMitMService *clone() override {
|
static void PostProcess(IMitmServiceObject *obj, IpcResponseContext *ctx);
|
||||||
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();
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/* Overridden commands. */
|
/* Overridden commands. */
|
||||||
std::tuple<Result, OutSession<IStorageInterface>> open_data_storage_by_current_process();
|
Result OpenDataStorageByCurrentProcess(Out<std::shared_ptr<IStorageInterface>> out);
|
||||||
std::tuple<Result, OutSession<IStorageInterface>> open_data_storage_by_data_id(u64 storage_id, u64 data_id);
|
Result OpenDataStorageByDataId(Out<std::shared_ptr<IStorageInterface>> out, u64 data_id, u8 storage_id);
|
||||||
|
public:
|
||||||
|
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||||
|
MakeServiceCommandMeta<FspSrvCmd_OpenDataStorageByCurrentProcess, &FsMitmService::OpenDataStorageByCurrentProcess>(),
|
||||||
|
MakeServiceCommandMeta<FspSrvCmd_OpenDataStorageByDataId, &FsMitmService::OpenDataStorageByDataId>(),
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -20,7 +20,6 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
|
|
||||||
#include "sm_mitm.h"
|
|
||||||
#include "debug.hpp"
|
#include "debug.hpp"
|
||||||
#include "fsmitm_utils.hpp"
|
#include "fsmitm_utils.hpp"
|
||||||
#include "ini.h"
|
#include "ini.h"
|
||||||
@@ -34,6 +33,9 @@ static std::atomic_bool g_has_hid_session = false;
|
|||||||
static u64 g_override_key_combination = KEY_R;
|
static u64 g_override_key_combination = KEY_R;
|
||||||
static bool g_override_by_default = true;
|
static bool g_override_by_default = true;
|
||||||
|
|
||||||
|
/* Static buffer for loader.ini contents at runtime. */
|
||||||
|
static char g_config_ini_data[0x800];
|
||||||
|
|
||||||
static bool IsHexadecimal(const char *str) {
|
static bool IsHexadecimal(const char *str) {
|
||||||
while (*str) {
|
while (*str) {
|
||||||
if (isxdigit(*str)) {
|
if (isxdigit(*str)) {
|
||||||
@@ -93,12 +95,7 @@ void Utils::InitializeSdThreadFunc(void *args) {
|
|||||||
fsDirClose(&titles_dir);
|
fsDirClose(&titles_dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
FsFile config_file;
|
Utils::RefreshConfiguration();
|
||||||
if (R_SUCCEEDED(fsFsOpenFile(&g_sd_filesystem, "/atmosphere/loader.ini", FS_OPEN_READ, &config_file))) {
|
|
||||||
Utils::LoadConfiguration(&config_file);
|
|
||||||
fsFileClose(&config_file);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
g_has_initialized = true;
|
g_has_initialized = true;
|
||||||
|
|
||||||
@@ -204,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);
|
return fsFsOpenDirectory(fs, safe_path, FS_DIROPEN_DIRECTORY | FS_DIROPEN_FILE, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result Utils::HasSdRomfsContent(u64 title_id, bool *out) {
|
bool Utils::HasSdRomfsContent(u64 title_id) {
|
||||||
Result rc;
|
/* Check for romfs.bin. */
|
||||||
FsDir dir;
|
FsFile data_file;
|
||||||
if (R_FAILED((rc = Utils::OpenRomFSSdDir(title_id, "", &dir)))) {
|
if (R_SUCCEEDED(Utils::OpenSdFileForAtmosphere(title_id, "romfs.bin", FS_OPEN_READ, &data_file))) {
|
||||||
return rc;
|
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;
|
FsDirectoryEntry dir_entry;
|
||||||
u64 read_entries;
|
u64 read_entries;
|
||||||
if (R_SUCCEEDED((rc = fsDirRead(&dir, 0, &read_entries, 1, &dir_entry)))) {
|
return R_SUCCEEDED(fsDirRead(&dir, 0, &read_entries, 1, &dir_entry)) && read_entries == 1;
|
||||||
*out = (read_entries == 1);
|
|
||||||
}
|
}
|
||||||
fsDirClose(&dir);
|
|
||||||
|
Result Utils::SaveSdFileForAtmosphere(u64 title_id, const char *fn, void *data, size_t size) {
|
||||||
|
if (!IsSdInitialized()) {
|
||||||
|
return 0xFA202;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -246,11 +290,14 @@ Result Utils::GetKeysDown(u64 *keys) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool Utils::HasOverrideButton(u64 tid) {
|
bool Utils::HasOverrideButton(u64 tid) {
|
||||||
if (tid < 0x0100000000010000ULL) {
|
if (tid < 0x0100000000010000ULL || !IsSdInitialized()) {
|
||||||
/* Disable button override disable for non-applications. */
|
/* Disable button override disable for non-applications. */
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Unconditionally refresh loader.ini contents. */
|
||||||
|
RefreshConfiguration();
|
||||||
|
|
||||||
u64 kDown = 0;
|
u64 kDown = 0;
|
||||||
bool keys_triggered = (R_SUCCEEDED(GetKeysDown(&kDown)) && ((kDown & g_override_key_combination) != 0));
|
bool keys_triggered = (R_SUCCEEDED(GetKeysDown(&kDown)) && ((kDown & g_override_key_combination) != 0));
|
||||||
return IsSdInitialized() && (g_override_by_default ^ keys_triggered);
|
return IsSdInitialized() && (g_override_by_default ^ keys_triggered);
|
||||||
@@ -314,27 +361,24 @@ static int FsMitMIniHandler(void *user, const char *section, const char *name, c
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Utils::LoadConfiguration(FsFile *f) {
|
void Utils::RefreshConfiguration() {
|
||||||
if (f == NULL) {
|
FsFile config_file;
|
||||||
|
if (R_FAILED(fsFsOpenFile(&g_sd_filesystem, "/atmosphere/loader.ini", FS_OPEN_READ, &config_file))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 size;
|
u64 size;
|
||||||
if (R_FAILED(fsFileGetSize(f, &size))) {
|
if (R_FAILED(fsFileGetSize(&config_file, &size))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
size = std::min(size, (decltype(size))0x7FF);
|
size = std::min(size, (decltype(size))0x7FF);
|
||||||
|
|
||||||
char *config_str = new char[0x800];
|
|
||||||
if (config_str != NULL) {
|
|
||||||
/* Read in string. */
|
/* Read in string. */
|
||||||
std::fill(config_str, config_str + 0x800, 0);
|
std::fill(g_config_ini_data, g_config_ini_data + 0x800, 0);
|
||||||
size_t r_s;
|
size_t r_s;
|
||||||
fsFileRead(f, 0, config_str, size, &r_s);
|
fsFileRead(&config_file, 0, g_config_ini_data, size, &r_s);
|
||||||
|
fsFileClose(&config_file);
|
||||||
|
|
||||||
ini_parse_string(config_str, FsMitMIniHandler, NULL);
|
ini_parse_string(g_config_ini_data, FsMitMIniHandler, NULL);
|
||||||
|
|
||||||
delete[] config_str;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -21,6 +21,7 @@
|
|||||||
class Utils {
|
class Utils {
|
||||||
public:
|
public:
|
||||||
static bool IsSdInitialized();
|
static bool IsSdInitialized();
|
||||||
|
|
||||||
static Result OpenSdFile(const char *fn, int flags, FsFile *out);
|
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 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 OpenRomFSSdFile(u64 title_id, const char *fn, int flags, FsFile *out);
|
||||||
@@ -28,11 +29,12 @@ class Utils {
|
|||||||
static Result OpenSdDirForAtmosphere(u64 title_id, 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 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 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. */
|
/* SD card Initialization + MitM detection. */
|
||||||
static void InitializeSdThreadFunc(void *args);
|
static void InitializeSdThreadFunc(void *args);
|
||||||
@@ -45,5 +47,5 @@ class Utils {
|
|||||||
static Result GetKeysDown(u64 *keys);
|
static Result GetKeysDown(u64 *keys);
|
||||||
static bool HasOverrideButton(u64 tid);
|
static bool HasOverrideButton(u64 tid);
|
||||||
private:
|
private:
|
||||||
static void LoadConfiguration(FsFile *f);
|
static void RefreshConfiguration();
|
||||||
};
|
};
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2018 Atmosphère-NX
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms and conditions of the GNU General Public License,
|
|
||||||
* version 2, as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
* more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <mutex>
|
|
||||||
#include <switch.h>
|
|
||||||
#include <stratosphere.hpp>
|
|
||||||
#include "fsmitm_worker.hpp"
|
|
||||||
|
|
||||||
static SystemEvent *g_new_waitable_event = NULL;
|
|
||||||
|
|
||||||
static HosMutex g_new_waitable_mutex;
|
|
||||||
static HosSemaphore g_sema_new_waitable_finish;
|
|
||||||
|
|
||||||
static std::unique_ptr<WaitableManager> g_worker_waiter;
|
|
||||||
|
|
||||||
Result FsMitMWorker::AddWaitableCallback(void *arg, Handle *handles, size_t num_handles, u64 timeout) {
|
|
||||||
(void)arg;
|
|
||||||
svcClearEvent(handles[0]);
|
|
||||||
g_sema_new_waitable_finish.Signal();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FsMitMWorker::AddWaitable(IWaitable *waitable) {
|
|
||||||
g_worker_waiter->add_waitable(waitable);
|
|
||||||
std::scoped_lock lk{g_new_waitable_mutex};
|
|
||||||
g_new_waitable_event->signal_event();
|
|
||||||
g_sema_new_waitable_finish.Wait();
|
|
||||||
}
|
|
||||||
|
|
||||||
void FsMitMWorker::Main(void *arg) {
|
|
||||||
/* Initialize waitable event. */
|
|
||||||
g_new_waitable_event = new SystemEvent(NULL, &FsMitMWorker::AddWaitableCallback);
|
|
||||||
|
|
||||||
/* Make a new waitable manager. */
|
|
||||||
g_worker_waiter = std::make_unique<WaitableManager>(U64_MAX);
|
|
||||||
g_worker_waiter->add_waitable(g_new_waitable_event);
|
|
||||||
|
|
||||||
/* Service processes. */
|
|
||||||
g_worker_waiter->process();
|
|
||||||
}
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2018 Atmosphère-NX
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms and conditions of the GNU General Public License,
|
|
||||||
* version 2, as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
* more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#include <switch.h>
|
|
||||||
#include <atomic>
|
|
||||||
|
|
||||||
#include <stratosphere.hpp>
|
|
||||||
|
|
||||||
#include "debug.hpp"
|
|
||||||
|
|
||||||
class IMitMServiceObject : public IServiceObject {
|
|
||||||
protected:
|
|
||||||
Service *forward_service;
|
|
||||||
u64 process_id = 0;
|
|
||||||
u64 title_id = 0;
|
|
||||||
public:
|
|
||||||
IMitMServiceObject(Service *s) : forward_service(s) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool should_mitm(u64 pid, u64 tid) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void clone_to(void *o) = 0;
|
|
||||||
protected:
|
|
||||||
virtual ~IMitMServiceObject() = default;
|
|
||||||
virtual Result dispatch(IpcParsedCommand &r, IpcCommand &out_c, u64 cmd_id, u8 *pointer_buffer, size_t pointer_buffer_size) = 0;
|
|
||||||
virtual void postprocess(IpcParsedCommand &r, IpcCommand &out_c, u64 cmd_id, u8 *pointer_buffer, size_t pointer_buffer_size) = 0;
|
|
||||||
virtual Result handle_deferred() = 0;
|
|
||||||
};
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2018 Atmosphère-NX
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms and conditions of the GNU General Public License,
|
|
||||||
* version 2, as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
* more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <mutex>
|
|
||||||
#include <switch.h>
|
|
||||||
#include <stratosphere.hpp>
|
|
||||||
#include "mitm_query_service.hpp"
|
|
||||||
|
|
||||||
static std::vector<u64> g_known_pids;
|
|
||||||
static std::vector<u64> g_known_tids;
|
|
||||||
static HosMutex g_pid_tid_mutex;
|
|
||||||
|
|
||||||
Result MitMQueryUtils::get_associated_tid_for_pid(u64 pid, u64 *tid) {
|
|
||||||
Result rc = 0xCAFE;
|
|
||||||
std::scoped_lock lk{g_pid_tid_mutex};
|
|
||||||
for (unsigned int i = 0; i < g_known_pids.size(); i++) {
|
|
||||||
if (g_known_pids[i] == pid) {
|
|
||||||
*tid = g_known_tids[i];
|
|
||||||
rc = 0x0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MitMQueryUtils::associate_pid_to_tid(u64 pid, u64 tid) {
|
|
||||||
std::scoped_lock lk{g_pid_tid_mutex};
|
|
||||||
g_known_pids.push_back(pid);
|
|
||||||
g_known_tids.push_back(tid);
|
|
||||||
}
|
|
||||||
@@ -1,75 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2018 Atmosphère-NX
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms and conditions of the GNU General Public License,
|
|
||||||
* version 2, as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
* more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#include <switch.h>
|
|
||||||
#include <stratosphere/iserviceobject.hpp>
|
|
||||||
|
|
||||||
#include "debug.hpp"
|
|
||||||
|
|
||||||
enum MitMQueryServiceCommand {
|
|
||||||
MQS_Cmd_ShouldMitm = 65000,
|
|
||||||
MQS_Cmd_AssociatePidTid = 65001
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace MitMQueryUtils {
|
|
||||||
Result get_associated_tid_for_pid(u64 pid, u64 *tid);
|
|
||||||
|
|
||||||
void associate_pid_to_tid(u64 pid, u64 tid);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
class MitMQueryService : public IServiceObject {
|
|
||||||
public:
|
|
||||||
MitMQueryService<T> *clone() override {
|
|
||||||
return new MitMQueryService<T>();
|
|
||||||
}
|
|
||||||
Result dispatch(IpcParsedCommand &r, IpcCommand &out_c, u64 cmd_id, u8 *pointer_buffer, size_t pointer_buffer_size) override {
|
|
||||||
Log(armGetTls(), 0x100);
|
|
||||||
switch (cmd_id) {
|
|
||||||
case MQS_Cmd_ShouldMitm:
|
|
||||||
return WrapIpcCommandImpl<&MitMQueryService::should_mitm>(this, r, out_c, pointer_buffer, pointer_buffer_size);
|
|
||||||
case MQS_Cmd_AssociatePidTid:
|
|
||||||
return WrapIpcCommandImpl<&MitMQueryService::associate_pid_tid>(this, r, out_c, pointer_buffer, pointer_buffer_size);
|
|
||||||
default:
|
|
||||||
return 0xF601;
|
|
||||||
}
|
|
||||||
if (cmd_id == 65000) {
|
|
||||||
|
|
||||||
} else {
|
|
||||||
return 0xF601;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Result handle_deferred() override {
|
|
||||||
/* This service is never deferrable. */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
std::tuple<Result, u64> should_mitm(u64 pid) {
|
|
||||||
u64 should_mitm = 0;
|
|
||||||
u64 tid = 0;
|
|
||||||
if (R_SUCCEEDED(MitMQueryUtils::get_associated_tid_for_pid(pid, &tid))) {
|
|
||||||
should_mitm = T::should_mitm(pid, tid);
|
|
||||||
}
|
|
||||||
return {0, should_mitm};
|
|
||||||
}
|
|
||||||
std::tuple<Result> associate_pid_tid(u64 pid, u64 tid) {
|
|
||||||
MitMQueryUtils::associate_pid_to_tid(pid, tid);
|
|
||||||
return {0x0};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@@ -1,69 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2018 Atmosphère-NX
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms and conditions of the GNU General Public License,
|
|
||||||
* version 2, as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
* more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#include <switch.h>
|
|
||||||
#include <stratosphere.hpp>
|
|
||||||
|
|
||||||
#include "mitm_query_service.hpp"
|
|
||||||
#include "sm_mitm.h"
|
|
||||||
#include "mitm_session.hpp"
|
|
||||||
|
|
||||||
#include "debug.hpp"
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
class MitMSession;
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
class MitMServer final : public IServer<T> {
|
|
||||||
static_assert(std::is_base_of<IServiceObject, T>::value, "Service Objects must derive from IServiceObject");
|
|
||||||
private:
|
|
||||||
char mitm_name[9];
|
|
||||||
|
|
||||||
public:
|
|
||||||
MitMServer(ISession<MitMQueryService<T>> **out_query_session, const char *service_name, unsigned int max_s, bool s_d = false) : IServer<T>(service_name, max_s, s_d) {
|
|
||||||
Handle tmp_hnd;
|
|
||||||
Handle out_query_h;
|
|
||||||
Result rc;
|
|
||||||
|
|
||||||
if (R_SUCCEEDED((rc = smGetServiceOriginal(&tmp_hnd, smEncodeName(service_name))))) {
|
|
||||||
svcCloseHandle(tmp_hnd);
|
|
||||||
} else {
|
|
||||||
fatalSimple(rc);
|
|
||||||
}
|
|
||||||
strncpy(mitm_name, service_name, 8);
|
|
||||||
mitm_name[8] = '\x00';
|
|
||||||
if (R_FAILED((rc = smMitMInstall(&this->port_handle, &out_query_h, mitm_name)))) {
|
|
||||||
fatalSimple(rc);
|
|
||||||
}
|
|
||||||
*out_query_session = new ServiceSession<MitMQueryService<T>>(NULL, out_query_h, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~MitMServer() {
|
|
||||||
if (this->port_handle) {
|
|
||||||
if (R_FAILED(smMitMUninstall(this->mitm_name))) {
|
|
||||||
/* TODO: Panic. */
|
|
||||||
}
|
|
||||||
/* svcCloseHandle(port_handle); was called by ~IServer. */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ISession<T> *get_new_session(Handle session_h) override {
|
|
||||||
return new MitMSession<T>(this, session_h, 0, mitm_name);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,246 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2018 Atmosphère-NX
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms and conditions of the GNU General Public License,
|
|
||||||
* version 2, as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
* more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#include <switch.h>
|
|
||||||
#include <stratosphere.hpp>
|
|
||||||
#include "imitmserviceobject.hpp"
|
|
||||||
|
|
||||||
#include "mitm_query_service.hpp"
|
|
||||||
#include "mitm_server.hpp"
|
|
||||||
#include "fsmitm_worker.hpp"
|
|
||||||
|
|
||||||
#include "debug.hpp"
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
class MitMServer;
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
class MitMSession final : public ISession<T> {
|
|
||||||
static_assert(std::is_base_of<IMitMServiceObject, T>::value, "MitM Service Objects must derive from IMitMServiceObject");
|
|
||||||
|
|
||||||
/* This will be for the actual session. */
|
|
||||||
Service forward_service;
|
|
||||||
IpcParsedCommand cur_out_r;
|
|
||||||
u32 mitm_domain_id = 0;
|
|
||||||
bool got_first_message;
|
|
||||||
|
|
||||||
public:
|
|
||||||
MitMSession<T>(MitMServer<T> *s, Handle s_h, Handle c_h, const char *srv) : ISession<T>(s, s_h, c_h, NULL, 0), got_first_message(false) {
|
|
||||||
this->server = s;
|
|
||||||
this->server_handle = s_h;
|
|
||||||
this->client_handle = c_h;
|
|
||||||
if (R_FAILED(smMitMGetService(&forward_service, srv))) {
|
|
||||||
/* TODO: Panic. */
|
|
||||||
}
|
|
||||||
size_t pointer_buffer_size = 0;
|
|
||||||
if (R_FAILED(ipcQueryPointerBufferSize(forward_service.handle, &pointer_buffer_size))) {
|
|
||||||
/* TODO: Panic. */
|
|
||||||
}
|
|
||||||
this->service_object = std::make_shared<T>(&forward_service);
|
|
||||||
this->pointer_buffer.resize(pointer_buffer_size);
|
|
||||||
}
|
|
||||||
MitMSession<T>(MitMServer<T> *s, Handle s_h, Handle c_h, Handle f_h) : ISession<T>(s, s_h, c_h, NULL, 0), got_first_message(true) {
|
|
||||||
this->server = s;
|
|
||||||
this->server_handle = s_h;
|
|
||||||
this->client_handle = c_h;
|
|
||||||
serviceCreate(&this->forward_service, f_h);
|
|
||||||
size_t pointer_buffer_size = 0;
|
|
||||||
if (R_FAILED(ipcQueryPointerBufferSize(forward_service.handle, &pointer_buffer_size))) {
|
|
||||||
/* TODO: Panic. */
|
|
||||||
}
|
|
||||||
this->service_object = std::make_shared<T>(&forward_service);
|
|
||||||
this->pointer_buffer.resize(pointer_buffer_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~MitMSession() {
|
|
||||||
serviceClose(&forward_service);
|
|
||||||
}
|
|
||||||
|
|
||||||
Result handle_message(IpcParsedCommand &r) override {
|
|
||||||
IpcCommand c;
|
|
||||||
ipcInitialize(&c);
|
|
||||||
u64 cmd_id = ((u32 *)r.Raw)[2];
|
|
||||||
Result retval = 0xF601;
|
|
||||||
|
|
||||||
cur_out_r.NumHandles = 0;
|
|
||||||
|
|
||||||
Log(armGetTls(), 0x100);
|
|
||||||
|
|
||||||
u32 *cmdbuf = (u32 *)armGetTls();
|
|
||||||
if (r.CommandType == IpcCommandType_Close) {
|
|
||||||
Reboot();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (r.CommandType == IpcCommandType_Request || r.CommandType == IpcCommandType_RequestWithContext) {
|
|
||||||
std::shared_ptr<IServiceObject> obj;
|
|
||||||
if (r.IsDomainRequest) {
|
|
||||||
obj = this->domain->get_domain_object(r.InThisObjectId);
|
|
||||||
if (obj != nullptr && r.InMessageType == DomainMessageType_Close) {
|
|
||||||
if (r.InThisObjectId == this->mitm_domain_id) {
|
|
||||||
Reboot();
|
|
||||||
}
|
|
||||||
this->domain->delete_object(r.InThisObjectId);
|
|
||||||
struct {
|
|
||||||
u64 magic;
|
|
||||||
u64 result;
|
|
||||||
} *o_resp;
|
|
||||||
|
|
||||||
o_resp = (decltype(o_resp)) ipcPrepareHeaderForDomain(&c, sizeof(*o_resp), 0);
|
|
||||||
*(DomainResponseHeader *)((uintptr_t)o_resp - sizeof(DomainResponseHeader)) = {0};
|
|
||||||
o_resp->magic = SFCO_MAGIC;
|
|
||||||
o_resp->result = 0x0;
|
|
||||||
Log(armGetTls(), 0x100);
|
|
||||||
return o_resp->result;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
obj = this->service_object;
|
|
||||||
}
|
|
||||||
if (obj != nullptr) {
|
|
||||||
retval = obj->dispatch(r, c, cmd_id, (u8 *)this->pointer_buffer.data(), this->pointer_buffer.size());
|
|
||||||
if (R_SUCCEEDED(retval)) {
|
|
||||||
if (r.IsDomainRequest) {
|
|
||||||
/* We never work with out object ids, so this should be fine. */
|
|
||||||
ipcParseDomainResponse(&cur_out_r, 0);
|
|
||||||
} else {
|
|
||||||
ipcParse(&cur_out_r);
|
|
||||||
}
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (r.CommandType == IpcCommandType_Control || r.CommandType == IpcCommandType_ControlWithContext) {
|
|
||||||
/* Ipc Clone Current Object. */
|
|
||||||
retval = serviceIpcDispatch(&forward_service);
|
|
||||||
Log(armGetTls(), 0x100);
|
|
||||||
if (R_SUCCEEDED(retval)) {
|
|
||||||
ipcParse(&cur_out_r);
|
|
||||||
struct {
|
|
||||||
u64 magic;
|
|
||||||
u64 result;
|
|
||||||
} *resp = (decltype(resp))cur_out_r.Raw;
|
|
||||||
retval = resp->result;
|
|
||||||
if ((cmd_id == IpcCtrl_Cmd_CloneCurrentObject || cmd_id == IpcCtrl_Cmd_CloneCurrentObjectEx)) {
|
|
||||||
if (R_SUCCEEDED(retval)) {
|
|
||||||
Handle s_h;
|
|
||||||
Handle c_h;
|
|
||||||
Result rc;
|
|
||||||
if (R_FAILED((rc = svcCreateSession(&s_h, &c_h, 0, 0)))) {
|
|
||||||
fatalSimple(rc);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cur_out_r.NumHandles != 1) {
|
|
||||||
Reboot();
|
|
||||||
}
|
|
||||||
|
|
||||||
MitMSession<T> *new_sess = new MitMSession<T>((MitMServer<T> *)this->server, s_h, c_h, cur_out_r.Handles[0]);
|
|
||||||
new_sess->service_object = this->service_object;
|
|
||||||
|
|
||||||
if (this->is_domain) {
|
|
||||||
new_sess->is_domain = true;
|
|
||||||
new_sess->domain = this->domain;
|
|
||||||
new_sess->mitm_domain_id = this->mitm_domain_id;
|
|
||||||
new_sess->forward_service.type = this->forward_service.type;
|
|
||||||
new_sess->forward_service.object_id = this->forward_service.object_id;
|
|
||||||
}
|
|
||||||
this->get_manager()->add_waitable(new_sess);
|
|
||||||
ipcSendHandleMove(&c, c_h);
|
|
||||||
struct {
|
|
||||||
u64 magic;
|
|
||||||
u64 result;
|
|
||||||
} *o_resp;
|
|
||||||
|
|
||||||
o_resp = (decltype(o_resp)) ipcPrepareHeader(&c, sizeof(*o_resp));
|
|
||||||
o_resp->magic = SFCO_MAGIC;
|
|
||||||
o_resp->result = 0x0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Log(armGetTls(), 0x100);
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 0xF601 --> Dispatch onwards. */
|
|
||||||
if (retval == 0xF601) {
|
|
||||||
/* Patch PID Descriptor, if relevant. */
|
|
||||||
if (r.HasPid) {
|
|
||||||
/* [ctrl 0] [ctrl 1] [handle desc 0] [pid low] [pid high] */
|
|
||||||
cmdbuf[4] = 0xFFFE0000UL | (cmdbuf[4] & 0xFFFFUL);
|
|
||||||
}
|
|
||||||
|
|
||||||
Log(armGetTls(), 0x100);
|
|
||||||
retval = serviceIpcDispatch(&forward_service);
|
|
||||||
if (R_SUCCEEDED(retval)) {
|
|
||||||
if (r.IsDomainRequest) {
|
|
||||||
/* We never work with out object ids, so this should be fine. */
|
|
||||||
ipcParseDomainResponse(&cur_out_r, 0);
|
|
||||||
} else {
|
|
||||||
ipcParse(&cur_out_r);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct {
|
|
||||||
u64 magic;
|
|
||||||
u64 result;
|
|
||||||
} *resp = (decltype(resp))cur_out_r.Raw;
|
|
||||||
|
|
||||||
retval = resp->result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Log(armGetTls(), 0x100);
|
|
||||||
Log(&cmd_id, sizeof(u64));
|
|
||||||
u64 retval_for_log = retval;
|
|
||||||
Log(&retval_for_log, sizeof(u64));
|
|
||||||
if (R_FAILED(retval)) {
|
|
||||||
//Reboot();
|
|
||||||
}
|
|
||||||
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
void postprocess(IpcParsedCommand &r, u64 cmd_id) override {
|
|
||||||
if (this->active_object == this->service_object && (r.CommandType == IpcCommandType_Request || r.CommandType == IpcCommandType_RequestWithContext)) {
|
|
||||||
IpcCommand c;
|
|
||||||
ipcInitialize(&c);
|
|
||||||
this->service_object->postprocess(cur_out_r, c, cmd_id, (u8 *)this->pointer_buffer.data(), this->pointer_buffer.size());
|
|
||||||
} else if (r.CommandType == IpcCommandType_Control || r.CommandType == IpcCommandType_ControlWithContext) {
|
|
||||||
if (cmd_id == IpcCtrl_Cmd_ConvertCurrentObjectToDomain) {
|
|
||||||
this->is_domain = true;
|
|
||||||
this->domain = std::make_shared<DomainOwner>();
|
|
||||||
struct {
|
|
||||||
u64 magic;
|
|
||||||
u64 result;
|
|
||||||
u32 domain_id;
|
|
||||||
} *resp = (decltype(resp))cur_out_r.Raw;
|
|
||||||
Result rc;
|
|
||||||
if (R_FAILED((rc = this->domain->set_object(this->service_object, resp->domain_id)))) {
|
|
||||||
fatalSimple(rc);
|
|
||||||
}
|
|
||||||
this->mitm_domain_id = resp->domain_id;
|
|
||||||
this->forward_service.type = ServiceType_Domain;
|
|
||||||
this->forward_service.object_id = resp->domain_id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void cleanup() override {
|
|
||||||
/* Clean up copy handles. */
|
|
||||||
for (unsigned int i = 0; i < cur_out_r.NumHandles; i++) {
|
|
||||||
if (cur_out_r.WasHandleCopied[i]) {
|
|
||||||
svcCloseHandle(cur_out_r.Handles[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@@ -1,190 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2018 Atmosphère-NX
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms and conditions of the GNU General Public License,
|
|
||||||
* version 2, as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
* more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <switch.h>
|
|
||||||
#include <switch/arm/atomics.h>
|
|
||||||
#include "sm_mitm.h"
|
|
||||||
|
|
||||||
static Handle g_smMitmHandle = INVALID_HANDLE;
|
|
||||||
static u64 g_refCnt;
|
|
||||||
|
|
||||||
Result smMitMInitialize(void) {
|
|
||||||
atomicIncrement64(&g_refCnt);
|
|
||||||
|
|
||||||
if (g_smMitmHandle != INVALID_HANDLE)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
Result rc = svcConnectToNamedPort(&g_smMitmHandle, "sm:");
|
|
||||||
|
|
||||||
if (R_SUCCEEDED(rc)) {
|
|
||||||
IpcCommand c;
|
|
||||||
ipcInitialize(&c);
|
|
||||||
ipcSendPid(&c);
|
|
||||||
|
|
||||||
struct {
|
|
||||||
u64 magic;
|
|
||||||
u64 cmd_id;
|
|
||||||
u64 zero;
|
|
||||||
u64 reserved[2];
|
|
||||||
} *raw;
|
|
||||||
|
|
||||||
raw = ipcPrepareHeader(&c, sizeof(*raw));
|
|
||||||
|
|
||||||
raw->magic = SFCI_MAGIC;
|
|
||||||
raw->cmd_id = 0;
|
|
||||||
raw->zero = 0;
|
|
||||||
|
|
||||||
rc = ipcDispatch(g_smMitmHandle);
|
|
||||||
|
|
||||||
if (R_SUCCEEDED(rc)) {
|
|
||||||
IpcParsedCommand r;
|
|
||||||
ipcParse(&r);
|
|
||||||
|
|
||||||
struct {
|
|
||||||
u64 magic;
|
|
||||||
u64 result;
|
|
||||||
} *resp = r.Raw;
|
|
||||||
|
|
||||||
rc = resp->result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (R_FAILED(rc))
|
|
||||||
smExit();
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
void smMitMExit(void) {
|
|
||||||
if (atomicDecrement64(&g_refCnt) == 0) {
|
|
||||||
svcCloseHandle(g_smMitmHandle);
|
|
||||||
g_smMitmHandle = INVALID_HANDLE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Result smMitMGetService(Service* service_out, const char *name_str)
|
|
||||||
{
|
|
||||||
u64 name = smEncodeName(name_str);
|
|
||||||
IpcCommand c;
|
|
||||||
ipcInitialize(&c);
|
|
||||||
|
|
||||||
struct {
|
|
||||||
u64 magic;
|
|
||||||
u64 cmd_id;
|
|
||||||
u64 service_name;
|
|
||||||
u64 reserved[2];
|
|
||||||
} *raw;
|
|
||||||
|
|
||||||
raw = ipcPrepareHeader(&c, sizeof(*raw));
|
|
||||||
|
|
||||||
raw->magic = SFCI_MAGIC;
|
|
||||||
raw->cmd_id = 1;
|
|
||||||
raw->service_name = name;
|
|
||||||
|
|
||||||
Result rc = ipcDispatch(g_smMitmHandle);
|
|
||||||
|
|
||||||
if (R_SUCCEEDED(rc)) {
|
|
||||||
IpcParsedCommand r;
|
|
||||||
ipcParse(&r);
|
|
||||||
|
|
||||||
struct {
|
|
||||||
u64 magic;
|
|
||||||
u64 result;
|
|
||||||
} *resp = r.Raw;
|
|
||||||
|
|
||||||
rc = resp->result;
|
|
||||||
|
|
||||||
if (R_SUCCEEDED(rc)) {
|
|
||||||
service_out->type = ServiceType_Normal;
|
|
||||||
service_out->handle = r.Handles[0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Result smMitMInstall(Handle *handle_out, Handle *query_out, const char *name) {
|
|
||||||
IpcCommand c;
|
|
||||||
ipcInitialize(&c);
|
|
||||||
|
|
||||||
struct {
|
|
||||||
u64 magic;
|
|
||||||
u64 cmd_id;
|
|
||||||
u64 service_name;
|
|
||||||
} *raw;
|
|
||||||
|
|
||||||
raw = ipcPrepareHeader(&c, sizeof(*raw));
|
|
||||||
|
|
||||||
raw->magic = SFCI_MAGIC;
|
|
||||||
raw->cmd_id = 65000;
|
|
||||||
raw->service_name = smEncodeName(name);
|
|
||||||
|
|
||||||
Result rc = ipcDispatch(g_smMitmHandle);
|
|
||||||
|
|
||||||
if (R_SUCCEEDED(rc)) {
|
|
||||||
IpcParsedCommand r;
|
|
||||||
ipcParse(&r);
|
|
||||||
|
|
||||||
struct {
|
|
||||||
u64 magic;
|
|
||||||
u64 result;
|
|
||||||
} *resp = r.Raw;
|
|
||||||
|
|
||||||
rc = resp->result;
|
|
||||||
|
|
||||||
if (R_SUCCEEDED(rc)) {
|
|
||||||
*handle_out = r.Handles[0];
|
|
||||||
*query_out = r.Handles[1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
Result smMitMUninstall(const char *name) {
|
|
||||||
IpcCommand c;
|
|
||||||
ipcInitialize(&c);
|
|
||||||
|
|
||||||
struct {
|
|
||||||
u64 magic;
|
|
||||||
u64 cmd_id;
|
|
||||||
u64 service_name;
|
|
||||||
u64 reserved;
|
|
||||||
} *raw;
|
|
||||||
|
|
||||||
raw = ipcPrepareHeader(&c, sizeof(*raw));
|
|
||||||
|
|
||||||
raw->magic = SFCI_MAGIC;
|
|
||||||
raw->cmd_id = 65001;
|
|
||||||
raw->service_name = smEncodeName(name);
|
|
||||||
|
|
||||||
Result rc = ipcDispatch(g_smMitmHandle);
|
|
||||||
|
|
||||||
if (R_SUCCEEDED(rc)) {
|
|
||||||
IpcParsedCommand r;
|
|
||||||
ipcParse(&r);
|
|
||||||
|
|
||||||
struct {
|
|
||||||
u64 magic;
|
|
||||||
u64 result;
|
|
||||||
} *resp = r.Raw;
|
|
||||||
|
|
||||||
rc = resp->result;
|
|
||||||
}
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file sm_mitm.h
|
|
||||||
* @brief Service manager (sm) IPC wrapper for Atmosphere extensions.
|
|
||||||
* @author SciresM
|
|
||||||
* @copyright libnx Authors
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
#include <switch.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Result smMitMInitialize(void);
|
|
||||||
void smMitMExit(void);
|
|
||||||
Result smMitMGetService(Service* service_out, const char *name);
|
|
||||||
Result smMitMInstall(Handle *handle_out, Handle *query_out, const char *name);
|
|
||||||
Result smMitMUninstall(const char *name);
|
|
||||||
|
|
||||||
Result smMitMIsRegistered(const char *name);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
1
stratosphere/libstratosphere
Submodule
1
stratosphere/libstratosphere
Submodule
Submodule stratosphere/libstratosphere added at bcd80ab445
4
stratosphere/libstratosphere/.gitignore
vendored
4
stratosphere/libstratosphere/.gitignore
vendored
@@ -1,4 +0,0 @@
|
|||||||
debug
|
|
||||||
release
|
|
||||||
lib
|
|
||||||
*.bz2
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
/*
|
|
||||||
|
|
||||||
@Copyright Barrett Adair 2015-2017
|
|
||||||
Distributed under the Boost Software License, Version 1.0.
|
|
||||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef BOOST_CLBL_TRTS_BOOST_CLBL_TRTS_HPP
|
|
||||||
#define BOOST_CLBL_TRTS_BOOST_CLBL_TRTS_HPP
|
|
||||||
|
|
||||||
#include <boost/callable_traits/detail/core.hpp>
|
|
||||||
#include <boost/callable_traits/add_member_const.hpp>
|
|
||||||
#include <boost/callable_traits/add_member_cv.hpp>
|
|
||||||
#include <boost/callable_traits/add_member_lvalue_reference.hpp>
|
|
||||||
#include <boost/callable_traits/add_member_rvalue_reference.hpp>
|
|
||||||
#include <boost/callable_traits/add_member_volatile.hpp>
|
|
||||||
#include <boost/callable_traits/add_noexcept.hpp>
|
|
||||||
#include <boost/callable_traits/add_transaction_safe.hpp>
|
|
||||||
#include <boost/callable_traits/add_varargs.hpp>
|
|
||||||
#include <boost/callable_traits/apply_member_pointer.hpp>
|
|
||||||
#include <boost/callable_traits/apply_return.hpp>
|
|
||||||
#include <boost/callable_traits/args.hpp>
|
|
||||||
#include <boost/callable_traits/class_of.hpp>
|
|
||||||
#include <boost/callable_traits/function_type.hpp>
|
|
||||||
#include <boost/callable_traits/has_member_qualifiers.hpp>
|
|
||||||
#include <boost/callable_traits/has_varargs.hpp>
|
|
||||||
#include <boost/callable_traits/has_void_return.hpp>
|
|
||||||
#include <boost/callable_traits/is_const_member.hpp>
|
|
||||||
#include <boost/callable_traits/is_invocable.hpp>
|
|
||||||
#include <boost/callable_traits/is_lvalue_reference_member.hpp>
|
|
||||||
#include <boost/callable_traits/is_reference_member.hpp>
|
|
||||||
#include <boost/callable_traits/is_rvalue_reference_member.hpp>
|
|
||||||
#include <boost/callable_traits/is_noexcept.hpp>
|
|
||||||
#include <boost/callable_traits/is_transaction_safe.hpp>
|
|
||||||
#include <boost/callable_traits/is_volatile_member.hpp>
|
|
||||||
#include <boost/callable_traits/qualified_class_of.hpp>
|
|
||||||
#include <boost/callable_traits/remove_member_const.hpp>
|
|
||||||
#include <boost/callable_traits/remove_member_cv.hpp>
|
|
||||||
#include <boost/callable_traits/remove_member_reference.hpp>
|
|
||||||
#include <boost/callable_traits/remove_member_volatile.hpp>
|
|
||||||
#include <boost/callable_traits/remove_noexcept.hpp>
|
|
||||||
#include <boost/callable_traits/remove_transaction_safe.hpp>
|
|
||||||
#include <boost/callable_traits/remove_varargs.hpp>
|
|
||||||
#include <boost/callable_traits/return_type.hpp>
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,105 +0,0 @@
|
|||||||
/*
|
|
||||||
|
|
||||||
@Copyright Barrett Adair 2015-2017
|
|
||||||
Distributed under the Boost Software License, Version 1.0.
|
|
||||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef BOOST_CLBL_TRTS_ADD_MEMBER_CONST_HPP
|
|
||||||
#define BOOST_CLBL_TRTS_ADD_MEMBER_CONST_HPP
|
|
||||||
|
|
||||||
#include <boost/callable_traits/detail/core.hpp>
|
|
||||||
|
|
||||||
namespace boost { namespace callable_traits {
|
|
||||||
|
|
||||||
//[ add_member_const_hpp
|
|
||||||
/*`
|
|
||||||
[section:ref_add_member_const add_member_const]
|
|
||||||
[heading Header]
|
|
||||||
``#include <boost/callable_traits/add_member_const.hpp>``
|
|
||||||
[heading Definition]
|
|
||||||
*/
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
using add_member_const_t = //see below
|
|
||||||
//<-
|
|
||||||
#ifdef BOOST_CLBL_TRTS_DISABLE_ABOMINABLE_FUNCTIONS
|
|
||||||
|
|
||||||
detail::sfinae_try<
|
|
||||||
typename detail::traits<T>::add_member_const,
|
|
||||||
|
|
||||||
detail::fail_when_same<typename detail::traits<T>::add_member_const,
|
|
||||||
detail::abominable_functions_not_supported_on_this_compiler,
|
|
||||||
this_compiler_doesnt_support_abominable_function_types>,
|
|
||||||
|
|
||||||
detail::fail_if_invalid<typename detail::traits<T>::add_member_const,
|
|
||||||
member_qualifiers_are_illegal_for_this_type>>;
|
|
||||||
#else
|
|
||||||
|
|
||||||
detail::try_but_fail_if_invalid<
|
|
||||||
typename detail::traits<T>::add_member_const,
|
|
||||||
member_qualifiers_are_illegal_for_this_type>;
|
|
||||||
|
|
||||||
#endif // #ifdef BOOST_CLBL_TRTS_DISABLE_ABOMINABLE_FUNCTIONS
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
template<typename T, typename = std::false_type>
|
|
||||||
struct add_member_const_impl {};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct add_member_const_impl <T, typename std::is_same<
|
|
||||||
add_member_const_t<T>, detail::dummy>::type>
|
|
||||||
{
|
|
||||||
using type = add_member_const_t<T>;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
//->
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct add_member_const : detail::add_member_const_impl<T> {};
|
|
||||||
|
|
||||||
//<-
|
|
||||||
}} // namespace boost::callable_traits
|
|
||||||
//->
|
|
||||||
|
|
||||||
|
|
||||||
/*`
|
|
||||||
[heading Constraints]
|
|
||||||
* `T` must be a function type or a member function pointer type
|
|
||||||
* If `T` is a pointer, it may not be cv/ref qualified
|
|
||||||
|
|
||||||
[heading Behavior]
|
|
||||||
* A substitution failure occurs if the constraints are violated.
|
|
||||||
* Adds a member `const` qualifier to `T`, if not already present.
|
|
||||||
|
|
||||||
[heading Input/Output Examples]
|
|
||||||
[table
|
|
||||||
[[`T`] [`add_member_const_t<T>`]]
|
|
||||||
[[`int()`] [`int() const`]]
|
|
||||||
[[`int(foo::*)()`] [`int(foo::*)() const`]]
|
|
||||||
[[`int(foo::*)() &`] [`int(foo::*)() const &`]]
|
|
||||||
[[`int(foo::*)() &&`] [`int(foo::*)() const &&`]]
|
|
||||||
[[`int(foo::*)() const`] [`int(foo::*)() const`]]
|
|
||||||
[[`int(foo::*)() volatile`] [`int(foo::*)() const volatile`]]
|
|
||||||
[[`int(foo::*)() transaction_safe`] [`int(foo::*)() const transaction_safe`]]
|
|
||||||
[[`int`] [(substitution failure)]]
|
|
||||||
[[`int (&)()`] [(substitution failure)]]
|
|
||||||
[[`int (*)()`] [(substitution failure)]]
|
|
||||||
[[`int foo::*`] [(substitution failure)]]
|
|
||||||
[[`int (foo::* const)()`] [(substitution failure)]]
|
|
||||||
]
|
|
||||||
|
|
||||||
[heading Example Program]
|
|
||||||
[import ../example/add_member_const.cpp]
|
|
||||||
[add_member_const]
|
|
||||||
[endsect]
|
|
||||||
*/
|
|
||||||
//]
|
|
||||||
|
|
||||||
#endif // #ifndef BOOST_CLBL_TRTS_ADD_MEMBER_CONST_HPP
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,101 +0,0 @@
|
|||||||
/*
|
|
||||||
|
|
||||||
@Copyright Barrett Adair 2015-2017
|
|
||||||
Distributed under the Boost Software License, Version 1.0.
|
|
||||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef BOOST_CLBL_TRTS_ADD_MEMBER_CV_HPP
|
|
||||||
#define BOOST_CLBL_TRTS_ADD_MEMBER_CV_HPP
|
|
||||||
|
|
||||||
#include <boost/callable_traits/detail/core.hpp>
|
|
||||||
|
|
||||||
namespace boost { namespace callable_traits {
|
|
||||||
|
|
||||||
//[ add_member_cv_hpp
|
|
||||||
/*`
|
|
||||||
[section:ref_add_member_cv add_member_cv]
|
|
||||||
[heading Header]
|
|
||||||
``#include <boost/callable_traits/add_member_cv.hpp>``
|
|
||||||
[heading Definition]
|
|
||||||
*/
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
using add_member_cv_t = //see below
|
|
||||||
//<-
|
|
||||||
#ifdef BOOST_CLBL_TRTS_DISABLE_ABOMINABLE_FUNCTIONS
|
|
||||||
|
|
||||||
detail::sfinae_try<
|
|
||||||
typename detail::traits<T>::add_member_cv,
|
|
||||||
|
|
||||||
detail::fail_when_same<typename detail::traits<T>::add_member_cv,
|
|
||||||
detail::abominable_functions_not_supported_on_this_compiler,
|
|
||||||
this_compiler_doesnt_support_abominable_function_types>,
|
|
||||||
|
|
||||||
detail::fail_if_invalid<typename detail::traits<T>::add_member_cv,
|
|
||||||
member_qualifiers_are_illegal_for_this_type>>;
|
|
||||||
#else
|
|
||||||
|
|
||||||
detail::try_but_fail_if_invalid<
|
|
||||||
typename detail::traits<T>::add_member_cv,
|
|
||||||
member_qualifiers_are_illegal_for_this_type>;
|
|
||||||
|
|
||||||
#endif // #ifdef BOOST_CLBL_TRTS_DISABLE_ABOMINABLE_FUNCTIONS
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
template<typename T, typename = std::false_type>
|
|
||||||
struct add_member_cv_impl {};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct add_member_cv_impl <T, typename std::is_same<
|
|
||||||
add_member_cv_t<T>, detail::dummy>::type>
|
|
||||||
{
|
|
||||||
using type = add_member_cv_t<T>;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
//->
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct add_member_cv : detail::add_member_cv_impl<T> {};
|
|
||||||
|
|
||||||
//<-
|
|
||||||
}} // namespace boost::callable_traits
|
|
||||||
//->
|
|
||||||
|
|
||||||
/*`
|
|
||||||
[heading Constraints]
|
|
||||||
* `T` must be a function type or a member function pointer type
|
|
||||||
* If `T` is a pointer, it may not be cv/ref qualified
|
|
||||||
|
|
||||||
[heading Behavior]
|
|
||||||
* A substitution failure occurs if the constraints are violated.
|
|
||||||
* Adds member `const` and `volatile` qualifiers to `T`, if not already present.
|
|
||||||
|
|
||||||
[heading Input/Output Examples]
|
|
||||||
[table
|
|
||||||
[[`T`] [`add_member_cv_t<T>`]]
|
|
||||||
[[`int()`] [`int() const volatile`]]
|
|
||||||
[[`int(foo::*)()`] [`int(foo::*)() const volatile`]]
|
|
||||||
[[`int(foo::*)() &`] [`int(foo::*)() const volatile &`]]
|
|
||||||
[[`int(foo::*)() &&`] [`int(foo::*)() const volatile &&`]]
|
|
||||||
[[`int(foo::*)() const`] [`int(foo::*)() const volatile`]]
|
|
||||||
[[`int(foo::*)() volatile`] [`int(foo::*)() const volatile`]]
|
|
||||||
[[`int(foo::*)() transaction_safe`] [`int(foo::*)() const volatile transaction_safe`]]
|
|
||||||
[[`int`] [(substitution failure)]]
|
|
||||||
[[`int (&)()`] [(substitution failure)]]
|
|
||||||
[[`int (*)()`] [(substitution failure)]]
|
|
||||||
[[`int foo::*`] [(substitution failure)]]
|
|
||||||
[[`int (foo::* const)()`] [(substitution failure)]]
|
|
||||||
]
|
|
||||||
|
|
||||||
[heading Example Program]
|
|
||||||
[import ../example/add_member_cv.cpp]
|
|
||||||
[add_member_cv]
|
|
||||||
[endsect]
|
|
||||||
*/
|
|
||||||
//]
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,114 +0,0 @@
|
|||||||
/*
|
|
||||||
|
|
||||||
@Copyright Barrett Adair 2015-2017
|
|
||||||
Distributed under the Boost Software License, Version 1.0.
|
|
||||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef BOOST_CLBL_TRTS_ADD_MEMBER_LVALUE_REFERENCE_HPP
|
|
||||||
#define BOOST_CLBL_TRTS_ADD_MEMBER_LVALUE_REFERENCE_HPP
|
|
||||||
|
|
||||||
#include <boost/callable_traits/detail/core.hpp>
|
|
||||||
|
|
||||||
namespace boost { namespace callable_traits {
|
|
||||||
|
|
||||||
//[ add_member_lvalue_reference_hpp
|
|
||||||
/*`
|
|
||||||
[section:ref_add_member_lvalue_reference add_member_lvalue_reference]
|
|
||||||
[heading Header]
|
|
||||||
``#include <boost/callable_traits/add_member_lvalue_reference.hpp>``
|
|
||||||
[heading Definition]
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef BOOST_CLBL_TRTS_DISABLE_REFERENCE_QUALIFIERS
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct add_member_lvalue_reference_t {
|
|
||||||
static_assert(std::is_same<T, detail::dummy>::value,
|
|
||||||
"Reference member qualifiers are not supported by this configuration.");
|
|
||||||
};
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
using add_member_lvalue_reference_t = //see below
|
|
||||||
//<-
|
|
||||||
#ifdef BOOST_CLBL_TRTS_DISABLE_ABOMINABLE_FUNCTIONS
|
|
||||||
|
|
||||||
detail::sfinae_try<
|
|
||||||
typename detail::traits<T>::add_member_lvalue_reference,
|
|
||||||
|
|
||||||
detail::fail_when_same<typename detail::traits<T>::add_member_lvalue_reference,
|
|
||||||
detail::abominable_functions_not_supported_on_this_compiler,
|
|
||||||
this_compiler_doesnt_support_abominable_function_types>,
|
|
||||||
|
|
||||||
detail::fail_if_invalid<
|
|
||||||
typename detail::traits<T>::add_member_lvalue_reference,
|
|
||||||
member_qualifiers_are_illegal_for_this_type>>;
|
|
||||||
#else
|
|
||||||
|
|
||||||
detail::try_but_fail_if_invalid<
|
|
||||||
typename detail::traits<T>::add_member_lvalue_reference,
|
|
||||||
member_qualifiers_are_illegal_for_this_type>;
|
|
||||||
|
|
||||||
#endif // #ifdef BOOST_CLBL_TRTS_DISABLE_ABOMINABLE_FUNCTIONS
|
|
||||||
#endif // #ifdef BOOST_CLBL_TRTS_DISABLE_REFERENCE_QUALIFIERS
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
template<typename T, typename = std::false_type>
|
|
||||||
struct add_member_lvalue_reference_impl {};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct add_member_lvalue_reference_impl <T, typename std::is_same<
|
|
||||||
add_member_lvalue_reference_t<T>, detail::dummy>::type>
|
|
||||||
{
|
|
||||||
using type = add_member_lvalue_reference_t<T>;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
//->
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct add_member_lvalue_reference
|
|
||||||
: detail::add_member_lvalue_reference_impl<T> {};
|
|
||||||
|
|
||||||
//<-
|
|
||||||
}} // namespace boost::callable_traits
|
|
||||||
//->
|
|
||||||
|
|
||||||
/*`
|
|
||||||
[heading Constraints]
|
|
||||||
* `T` must be a function type or a member function pointer type
|
|
||||||
* If `T` is a pointer, it may not be cv/ref qualified
|
|
||||||
|
|
||||||
[heading Behavior]
|
|
||||||
* A substitution failure occurs if the constraints are violated.
|
|
||||||
* Adds a member lvalue reference qualifier (`&`) to `T`, if not already present.
|
|
||||||
* If an rvalue reference qualifier is present, the lvalue reference qualifier replaces it (in accordance with reference collapsing rules).
|
|
||||||
|
|
||||||
[heading Input/Output Examples]
|
|
||||||
[table
|
|
||||||
[[`T`] [`add_member_lvalue_reference_t<T>`]]
|
|
||||||
[[`int()`] [`int() &`]]
|
|
||||||
[[`int(foo::*)()`] [`int(foo::*)() &`]]
|
|
||||||
[[`int(foo::*)() &`] [`int(foo::*)() &`]]
|
|
||||||
[[`int(foo::*)() &&`] [`int(foo::*)() &`]]
|
|
||||||
[[`int(foo::*)() const`] [`int(foo::*)() const &`]]
|
|
||||||
[[`int(foo::*)() transaction_safe`] [`int(foo::*)() & transaction_safe`]]
|
|
||||||
[[`int`] [(substitution failure)]]
|
|
||||||
[[`int (&)()`] [(substitution failure)]]
|
|
||||||
[[`int (*)()`] [(substitution failure)]]
|
|
||||||
[[`int foo::*`] [(substitution failure)]]
|
|
||||||
[[`int (foo::* const)()`] [(substitution failure)]]
|
|
||||||
]
|
|
||||||
|
|
||||||
[heading Example Program]
|
|
||||||
[import ../example/add_member_lvalue_reference.cpp]
|
|
||||||
[add_member_lvalue_reference]
|
|
||||||
[endsect]
|
|
||||||
*/
|
|
||||||
//]
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@@ -1,113 +0,0 @@
|
|||||||
/*
|
|
||||||
|
|
||||||
@Copyright Barrett Adair 2015-2017
|
|
||||||
Distributed under the Boost Software License, Version 1.0.
|
|
||||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef BOOST_CLBL_TRTS_ADD_MEMBER_RVALUE_REFERENCE_HPP
|
|
||||||
#define BOOST_CLBL_TRTS_ADD_MEMBER_RVALUE_REFERENCE_HPP
|
|
||||||
|
|
||||||
#include <boost/callable_traits/detail/core.hpp>
|
|
||||||
|
|
||||||
namespace boost { namespace callable_traits {
|
|
||||||
|
|
||||||
//[ add_member_rvalue_reference_hpp
|
|
||||||
/*`
|
|
||||||
[section:ref_add_member_rvalue_reference add_member_rvalue_reference]
|
|
||||||
[heading Header]
|
|
||||||
``#include <boost/callable_traits/add_member_rvalue_reference.hpp>``
|
|
||||||
[heading Definition]
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef BOOST_CLBL_TRTS_DISABLE_REFERENCE_QUALIFIERS
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct add_member_rvalue_reference_t {
|
|
||||||
static_assert(std::is_same<T, detail::dummy>::value,
|
|
||||||
"Reference member qualifiers are not supported by this configuration.");
|
|
||||||
};
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
using add_member_rvalue_reference_t = //see below
|
|
||||||
//<-
|
|
||||||
#ifdef BOOST_CLBL_TRTS_DISABLE_ABOMINABLE_FUNCTIONS
|
|
||||||
|
|
||||||
detail::sfinae_try<
|
|
||||||
typename detail::traits<T>::add_member_rvalue_reference,
|
|
||||||
|
|
||||||
detail::fail_when_same<typename detail::traits<T>::add_member_rvalue_reference,
|
|
||||||
detail::abominable_functions_not_supported_on_this_compiler,
|
|
||||||
this_compiler_doesnt_support_abominable_function_types>,
|
|
||||||
|
|
||||||
detail::fail_if_invalid<typename detail::traits<T>::add_member_rvalue_reference,
|
|
||||||
member_qualifiers_are_illegal_for_this_type>>;
|
|
||||||
#else
|
|
||||||
|
|
||||||
detail::try_but_fail_if_invalid<
|
|
||||||
typename detail::traits<T>::add_member_rvalue_reference,
|
|
||||||
member_qualifiers_are_illegal_for_this_type>;
|
|
||||||
|
|
||||||
#endif // #ifdef BOOST_CLBL_TRTS_DISABLE_ABOMINABLE_FUNCTIONS
|
|
||||||
#endif // #ifdef BOOST_CLBL_TRTS_DISABLE_REFERENCE_QUALIFIERS
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
template<typename T, typename = std::false_type>
|
|
||||||
struct add_member_rvalue_reference_impl {};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct add_member_rvalue_reference_impl <T, typename std::is_same<
|
|
||||||
add_member_rvalue_reference_t<T>, detail::dummy>::type>
|
|
||||||
{
|
|
||||||
using type = add_member_rvalue_reference_t<T>;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
//->
|
|
||||||
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct add_member_rvalue_reference
|
|
||||||
: detail::add_member_rvalue_reference_impl<T> {};
|
|
||||||
|
|
||||||
//<-
|
|
||||||
}} // namespace boost::callable_traits
|
|
||||||
//->
|
|
||||||
|
|
||||||
/*`
|
|
||||||
[heading Constraints]
|
|
||||||
* `T` must be a function type or a member function pointer type
|
|
||||||
* If `T` is a pointer, it may not be cv/ref qualified
|
|
||||||
|
|
||||||
[heading Behavior]
|
|
||||||
* A substitution failure occurs if the constraints are violated.
|
|
||||||
* Adds a member rvalue reference qualifier (`&&`) to `T`, if not already present.
|
|
||||||
* If an lvalue reference qualifier is present, the lvalue reference qualifier remains (in accordance with reference collapsing rules).
|
|
||||||
|
|
||||||
[heading Input/Output Examples]
|
|
||||||
[table
|
|
||||||
[[`T`] [`add_member_rvalue_reference_t<T>`]]
|
|
||||||
[[`int()`] [`int() &&`]]
|
|
||||||
[[`int(foo::*)()`] [`int(foo::*)() &&`]]
|
|
||||||
[[`int(foo::*)() &`] [`int(foo::*)() &`]]
|
|
||||||
[[`int(foo::*)() &&`] [`int(foo::*)() &&`]]
|
|
||||||
[[`int(foo::*)() const`] [`int(foo::*)() const &&`]]
|
|
||||||
[[`int(foo::*)() transaction_safe`] [`int(foo::*)() && transaction_safe`]]
|
|
||||||
[[`int`] [(substitution failure)]]
|
|
||||||
[[`int (&)()`] [(substitution failure)]]
|
|
||||||
[[`int (*)()`] [(substitution failure)]]
|
|
||||||
[[`int foo::*`] [(substitution failure)]]
|
|
||||||
[[`int (foo::* const)()`] [(substitution failure)]]
|
|
||||||
]
|
|
||||||
|
|
||||||
[heading Example Program]
|
|
||||||
[import ../example/add_member_rvalue_reference.cpp]
|
|
||||||
[add_member_rvalue_reference]
|
|
||||||
[endsect][/section:ref_add_member_rvalue_reference]
|
|
||||||
*/
|
|
||||||
//]
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,100 +0,0 @@
|
|||||||
/*
|
|
||||||
|
|
||||||
@Copyright Barrett Adair 2015-2017
|
|
||||||
Distributed under the Boost Software License, Version 1.0.
|
|
||||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef BOOST_CLBL_TRTS_ADD_MEMBER_VOLATILE_HPP
|
|
||||||
#define BOOST_CLBL_TRTS_ADD_MEMBER_VOLATILE_HPP
|
|
||||||
|
|
||||||
#include <boost/callable_traits/detail/core.hpp>
|
|
||||||
|
|
||||||
namespace boost { namespace callable_traits {
|
|
||||||
|
|
||||||
//[ add_member_volatile_hpp
|
|
||||||
/*`
|
|
||||||
[section:ref_add_member_volatile add_member_volatile]
|
|
||||||
[heading Header]
|
|
||||||
``#include <boost/callable_traits/add_member_volatile.hpp>``
|
|
||||||
[heading Definition]
|
|
||||||
*/
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
using add_member_volatile_t = //see below
|
|
||||||
//<-
|
|
||||||
#ifdef BOOST_CLBL_TRTS_DISABLE_ABOMINABLE_FUNCTIONS
|
|
||||||
|
|
||||||
detail::sfinae_try<
|
|
||||||
typename detail::traits<T>::add_member_volatile,
|
|
||||||
|
|
||||||
detail::fail_when_same<typename detail::traits<T>::add_member_volatile,
|
|
||||||
detail::abominable_functions_not_supported_on_this_compiler,
|
|
||||||
this_compiler_doesnt_support_abominable_function_types>,
|
|
||||||
|
|
||||||
detail::fail_if_invalid<
|
|
||||||
typename detail::traits<T>::add_member_volatile,
|
|
||||||
member_qualifiers_are_illegal_for_this_type>>;
|
|
||||||
#else
|
|
||||||
|
|
||||||
detail::try_but_fail_if_invalid<
|
|
||||||
typename detail::traits<T>::add_member_volatile,
|
|
||||||
member_qualifiers_are_illegal_for_this_type>;
|
|
||||||
|
|
||||||
#endif // #ifdef BOOST_CLBL_TRTS_DISABLE_ABOMINABLE_FUNCTIONS
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
template<typename T, typename = std::false_type>
|
|
||||||
struct add_member_volatile_impl {};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct add_member_volatile_impl <T, typename std::is_same<
|
|
||||||
add_member_volatile_t<T>, detail::dummy>::type>
|
|
||||||
{
|
|
||||||
using type = add_member_volatile_t<T>;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
//->
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct add_member_volatile : detail::add_member_volatile_impl<T> {};
|
|
||||||
|
|
||||||
//<-
|
|
||||||
}} // namespace boost::callable_traits
|
|
||||||
//->
|
|
||||||
|
|
||||||
/*`
|
|
||||||
[heading Constraints]
|
|
||||||
* `T` must be a function type or a member function pointer type
|
|
||||||
* If `T` is a pointer, it may not be cv/ref qualified
|
|
||||||
|
|
||||||
[heading Behavior]
|
|
||||||
* A substitution failure occurs if the constraints are violated.
|
|
||||||
* Adds a member volatile qualifier to `T`, if not already present.
|
|
||||||
|
|
||||||
[heading Input/Output Examples]
|
|
||||||
[table
|
|
||||||
[[`T`] [`add_member_volatile_t<T>`]]
|
|
||||||
[[`int()`] [`int() volatile`]]
|
|
||||||
[[`int(foo::*)()`] [`int(foo::*)() volatile`]]
|
|
||||||
[[`int(foo::*)() &`] [`int(foo::*)() volatile &`]]
|
|
||||||
[[`int(foo::*)() &&`] [`int(foo::*)() volatile &&`]]
|
|
||||||
[[`int(foo::*)() const`] [`int(foo::*)() const volatile`]]
|
|
||||||
[[`int(foo::*)() transaction_safe`] [`int(foo::*)() volatile transaction_safe`]]
|
|
||||||
[[`int`] [(substitution failure)]]
|
|
||||||
[[`int (&)()`] [(substitution failure)]]
|
|
||||||
[[`int (*)()`] [(substitution failure)]]
|
|
||||||
[[`int foo::*`] [(substitution failure)]]
|
|
||||||
[[`int (foo::* const)()`] [(substitution failure)]]
|
|
||||||
]
|
|
||||||
|
|
||||||
[heading Example Program]
|
|
||||||
[import ../example/add_member_volatile.cpp]
|
|
||||||
[add_member_volatile]
|
|
||||||
[endsect][/section:ref_add_member_volatile]
|
|
||||||
*/
|
|
||||||
//]
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,108 +0,0 @@
|
|||||||
/*
|
|
||||||
@file add_noexcept
|
|
||||||
|
|
||||||
@Copyright Barrett Adair 2015-2017
|
|
||||||
Distributed under the Boost Software License, Version 1.0.
|
|
||||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef BOOST_CLBL_TRTS_ADD_NOEXCEPT_HPP
|
|
||||||
#define BOOST_CLBL_TRTS_ADD_NOEXCEPT_HPP
|
|
||||||
|
|
||||||
#include <boost/callable_traits/detail/core.hpp>
|
|
||||||
|
|
||||||
namespace boost { namespace callable_traits {
|
|
||||||
|
|
||||||
BOOST_CLBL_TRTS_DEFINE_SFINAE_ERROR_ORIGIN(add_noexcept)
|
|
||||||
BOOST_CLBL_TRTS_SFINAE_MSG(add_noexcept, cannot_add_noexcept_to_this_type)
|
|
||||||
|
|
||||||
#ifndef BOOST_CLBL_TRTS_ENABLE_NOEXCEPT_TYPES
|
|
||||||
template<typename T>
|
|
||||||
struct add_noexcept_t {
|
|
||||||
static_assert(std::is_same<T, detail::dummy>::value,
|
|
||||||
"noexcept types not supported by this configuration.");
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct add_noexcept {
|
|
||||||
static_assert(std::is_same<T, detail::dummy>::value,
|
|
||||||
"noexcept types not supported by this configuration.");
|
|
||||||
};
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
//[ add_noexcept_hpp
|
|
||||||
/*`
|
|
||||||
[section:ref_add_noexcept add_noexcept]
|
|
||||||
[heading Header]
|
|
||||||
``#include <boost/callable_traits/add_noexcept.hpp>``
|
|
||||||
[heading Definition]
|
|
||||||
*/
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
using add_noexcept_t = //see below
|
|
||||||
//<-
|
|
||||||
detail::try_but_fail_if_invalid<
|
|
||||||
typename detail::traits<T>::add_noexcept,
|
|
||||||
cannot_add_noexcept_to_this_type>;
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
template<typename T, typename = std::false_type>
|
|
||||||
struct add_noexcept_impl {};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct add_noexcept_impl <T, typename std::is_same<
|
|
||||||
add_noexcept_t<T>, detail::dummy>::type>
|
|
||||||
{
|
|
||||||
using type = add_noexcept_t<T>;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
//->
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct add_noexcept : detail::add_noexcept_impl<T> {};
|
|
||||||
|
|
||||||
//<-
|
|
||||||
#endif // #ifdef BOOST_CLBL_TRTS_ENABLE_NOEXCEPT_TYPES
|
|
||||||
}} // namespace boost::callable_traits
|
|
||||||
//->
|
|
||||||
|
|
||||||
/*`
|
|
||||||
[heading Constraints]
|
|
||||||
* `T` must be one of the following:
|
|
||||||
* function type
|
|
||||||
* function pointer type
|
|
||||||
* function reference type
|
|
||||||
* member function pointer type
|
|
||||||
* If `T` is a pointer, it may not be cv/ref qualified
|
|
||||||
|
|
||||||
[heading Behavior]
|
|
||||||
* A substitution failure occurs if the constraints are violated.
|
|
||||||
* Adds a `noexcept` specifier to `T`, if not already present.
|
|
||||||
|
|
||||||
[heading Input/Output Examples]
|
|
||||||
[table
|
|
||||||
[[`T`] [`add_noexcept_t<T>`]]
|
|
||||||
[[`int()`] [`int() noexcept`]]
|
|
||||||
[[`int (&)()`] [`int(&)() noexcept`]]
|
|
||||||
[[`int (*)()`] [`int(*)() noexcept`]]
|
|
||||||
[[`int(foo::*)()`] [`int(foo::*)() noexcept`]]
|
|
||||||
[[`int(foo::*)() &`] [`int(foo::*)() & noexcept`]]
|
|
||||||
[[`int(foo::*)() &&`] [`int(foo::*)() && noexcept`]]
|
|
||||||
[[`int(foo::*)() const transaction_safe`] [`int(foo::*)() const transaction_safe noexcept`]]
|
|
||||||
[[`int(foo::*)() noexcept`] [`int(foo::*)() noexcept`]]
|
|
||||||
[[`int`] [(substitution failure)]]
|
|
||||||
[[`int foo::*`] [(substitution failure)]]
|
|
||||||
[[`int (*&)()`] [(substitution failure)]]
|
|
||||||
]
|
|
||||||
|
|
||||||
[heading Example Program]
|
|
||||||
[import ../example/add_noexcept.cpp]
|
|
||||||
[add_noexcept]
|
|
||||||
[endsect]
|
|
||||||
*/
|
|
||||||
//]
|
|
||||||
|
|
||||||
#endif // #ifndef BOOST_CLBL_TRTS_ADD_NOEXCEPT_HPP
|
|
||||||
@@ -1,110 +0,0 @@
|
|||||||
/*
|
|
||||||
@file add_transaction_safe
|
|
||||||
|
|
||||||
@Copyright Barrett Adair 2015-2017
|
|
||||||
Distributed under the Boost Software License, Version 1.0.
|
|
||||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef BOOST_CLBL_TRTS_ADD_TRANSACTION_SAFE_HPP
|
|
||||||
#define BOOST_CLBL_TRTS_ADD_TRANSACTION_SAFE_HPP
|
|
||||||
|
|
||||||
#include <boost/callable_traits/detail/core.hpp>
|
|
||||||
|
|
||||||
namespace boost { namespace callable_traits {
|
|
||||||
|
|
||||||
BOOST_CLBL_TRTS_DEFINE_SFINAE_ERROR_ORIGIN(add_transaction_safe)
|
|
||||||
BOOST_CLBL_TRTS_SFINAE_MSG(add_transaction_safe, cannot_add_transaction_safe_to_this_type)
|
|
||||||
|
|
||||||
#ifndef BOOST_CLBL_TRTS_ENABLE_TRANSACTION_SAFE
|
|
||||||
template<typename T>
|
|
||||||
struct add_transaction_safe_t {
|
|
||||||
static_assert(std::is_same<T, detail::dummy>::value,
|
|
||||||
"transaction_safe not supported by this configuration.");
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct add_transaction_safe {
|
|
||||||
static_assert(std::is_same<T, detail::dummy>::value,
|
|
||||||
"transaction_safe not supported by this configuration.");
|
|
||||||
};
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
//[ add_transaction_safe_hpp
|
|
||||||
/*`
|
|
||||||
[section:ref_add_transaction_safe add_transaction_safe]
|
|
||||||
[heading Header]
|
|
||||||
``#include <boost/callable_traits/add_transaction_safe.hpp>``
|
|
||||||
[heading Definition]
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
using add_transaction_safe_t = //see below
|
|
||||||
//<-
|
|
||||||
detail::try_but_fail_if_invalid<
|
|
||||||
typename detail::traits<T>::add_transaction_safe,
|
|
||||||
cannot_add_transaction_safe_to_this_type>;
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
template<typename T, typename = std::false_type>
|
|
||||||
struct add_transaction_safe_impl {};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct add_transaction_safe_impl <T, typename std::is_same<
|
|
||||||
add_transaction_safe_t<T>, detail::dummy>::type>
|
|
||||||
{
|
|
||||||
using type = add_transaction_safe_t<T>;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
//->
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct add_transaction_safe
|
|
||||||
: detail::add_transaction_safe_impl<T> {};
|
|
||||||
|
|
||||||
//<-
|
|
||||||
#endif // #ifndef BOOST_CLBL_TRTS_ENABLE_TRANSACTION_SAFE
|
|
||||||
}} // namespace boost::callable_traits
|
|
||||||
//->
|
|
||||||
|
|
||||||
/*`
|
|
||||||
[heading Constraints]
|
|
||||||
* `T` must be one of the following:
|
|
||||||
* function type
|
|
||||||
* function pointer type
|
|
||||||
* function reference type
|
|
||||||
* member function pointer type
|
|
||||||
* If `T` is a pointer, it may not be cv/ref qualified
|
|
||||||
|
|
||||||
[heading Behavior]
|
|
||||||
* A substitution failure occurs if the constraints are violated.
|
|
||||||
* Adds the `transaction_safe` specifier to `T`, if not already present.
|
|
||||||
|
|
||||||
[heading Input/Output Examples]
|
|
||||||
[table
|
|
||||||
[[`T`] [`add_transaction_safe_t<T>`]]
|
|
||||||
[[`int()`] [`int() transaction_safe`]]
|
|
||||||
[[`int (&)()`] [`int(&)() transaction_safe`]]
|
|
||||||
[[`int (*)()`] [`int(*)() transaction_safe`]]
|
|
||||||
[[`int(foo::*)()`] [`int(foo::*)() transaction_safe`]]
|
|
||||||
[[`int(foo::*)() &`] [`int(foo::*)() & transaction_safe`]]
|
|
||||||
[[`int(foo::*)() &&`] [`int(foo::*)() && transaction_safe`]]
|
|
||||||
[[`int(foo::*)() const`] [`int(foo::*)() const transaction_safe`]]
|
|
||||||
[[`int(foo::*)() transaction_safe`] [`int(foo::*)() transaction_safe`]]
|
|
||||||
[[`int`] [(substitution failure)]]
|
|
||||||
[[`int foo::*`] [(substitution failure)]]
|
|
||||||
[[`int (*&)()`] [(substitution failure)]]
|
|
||||||
]
|
|
||||||
|
|
||||||
[heading Example Program]
|
|
||||||
[import ../example/add_transaction_safe.cpp]
|
|
||||||
[add_transaction_safe]
|
|
||||||
[endsect]
|
|
||||||
*/
|
|
||||||
//]
|
|
||||||
|
|
||||||
#endif // #ifndef BOOST_CLBL_TRTS_ADD_TRANSACTION_SAFE_HPP
|
|
||||||
@@ -1,90 +0,0 @@
|
|||||||
/*
|
|
||||||
|
|
||||||
@Copyright Barrett Adair 2015-2017
|
|
||||||
Distributed under the Boost Software License, Version 1.0.
|
|
||||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef BOOST_CLBL_TRTS_ADD_VARARGS_HPP
|
|
||||||
#define BOOST_CLBL_TRTS_ADD_VARARGS_HPP
|
|
||||||
|
|
||||||
#include <boost/callable_traits/detail/core.hpp>
|
|
||||||
|
|
||||||
namespace boost { namespace callable_traits {
|
|
||||||
|
|
||||||
//[ add_varargs_hpp
|
|
||||||
/*`
|
|
||||||
[section:ref_add_varargs add_varargs]
|
|
||||||
[heading Header]
|
|
||||||
``#include <boost/callable_traits/add_varargs.hpp>``
|
|
||||||
[heading Definition]
|
|
||||||
*/
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
using add_varargs_t = //see below
|
|
||||||
//<-
|
|
||||||
detail::try_but_fail_if_invalid<
|
|
||||||
typename detail::traits<T>::add_varargs,
|
|
||||||
varargs_are_illegal_for_this_type>;
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
template<typename T, typename = std::false_type>
|
|
||||||
struct add_varargs_impl {};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct add_varargs_impl <T, typename std::is_same<
|
|
||||||
add_varargs_t<T>, detail::dummy>::type>
|
|
||||||
{
|
|
||||||
using type = add_varargs_t<T>;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
//->
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct add_varargs : detail::add_varargs_impl<T> {};
|
|
||||||
|
|
||||||
//<-
|
|
||||||
}} // namespace boost::callable_traits
|
|
||||||
//->
|
|
||||||
|
|
||||||
/*`
|
|
||||||
[heading Constraints]
|
|
||||||
* `T` must be one of the following:
|
|
||||||
* function type
|
|
||||||
* function pointer type
|
|
||||||
* function reference type
|
|
||||||
* member function pointer type
|
|
||||||
* If `T` is a pointer, it may not be cv/ref qualified
|
|
||||||
|
|
||||||
[heading Behavior]
|
|
||||||
* A substitution failure occurs if the constraints are violated.
|
|
||||||
* Adds C-style variadics (`...`) to the signature of `T`, if not already present.
|
|
||||||
|
|
||||||
[heading Input/Output Examples]
|
|
||||||
[table
|
|
||||||
[[`T`] [`add_varargs_t<T>`]]
|
|
||||||
[[`int()`] [`int(...)`]]
|
|
||||||
[[`int(int)`] [`int(int, ...)`]]
|
|
||||||
[[`int (&)()`] [`int(&)(...)`]]
|
|
||||||
[[`int (*)()`] [`int(*)(...)`]]
|
|
||||||
[[`int (*)(...)`] [`int(*)(...)`]]
|
|
||||||
[[`int(foo::*)()`] [`int(foo::*)(...)`]]
|
|
||||||
[[`int(foo::*)() &`] [`int(foo::*)(...) &`]]
|
|
||||||
[[`int(foo::*)() &&`] [`int(foo::*)(...) &&`]]
|
|
||||||
[[`int(foo::*)() const`] [`int(foo::*)(...) const`]]
|
|
||||||
[[`int(foo::*)() transaction_safe`] [`int(foo::*)(...) transaction_safe`]]
|
|
||||||
[[`int`] [(substitution failure)]]
|
|
||||||
[[`int foo::*`] [(substitution failure)]]
|
|
||||||
[[`int (*&)()`] [(substitution failure)]]
|
|
||||||
]
|
|
||||||
|
|
||||||
[heading Example Program]
|
|
||||||
[import ../example/add_varargs.cpp]
|
|
||||||
[add_varargs]
|
|
||||||
[endsect]
|
|
||||||
*/
|
|
||||||
//]
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,123 +0,0 @@
|
|||||||
/*
|
|
||||||
|
|
||||||
@Copyright Barrett Adair 2015-2017
|
|
||||||
Distributed under the Boost Software License, Version 1.0.
|
|
||||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef BOOST_CLBL_TRTS_APPLY_MEMBER_POINTER_HPP
|
|
||||||
#define BOOST_CLBL_TRTS_APPLY_MEMBER_POINTER_HPP
|
|
||||||
|
|
||||||
#include <boost/callable_traits/detail/core.hpp>
|
|
||||||
|
|
||||||
namespace boost { namespace callable_traits {
|
|
||||||
|
|
||||||
BOOST_CLBL_TRTS_DEFINE_SFINAE_ERROR_ORIGIN(apply_member_pointer)
|
|
||||||
BOOST_CLBL_TRTS_SFINAE_MSG(apply_member_pointer, members_cannot_have_a_type_of_void)
|
|
||||||
BOOST_CLBL_TRTS_SFINAE_MSG(apply_member_pointer, second_template_argument_must_be_a_class_or_struct)
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
template<typename T, typename C, bool = std::is_class<C>::value>
|
|
||||||
struct make_member_pointer;
|
|
||||||
|
|
||||||
template<typename T, typename C>
|
|
||||||
struct make_member_pointer<T, C, true> {
|
|
||||||
using type = typename std::remove_reference<T>::type C::*;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename C>
|
|
||||||
struct make_member_pointer<void, C, true> {
|
|
||||||
using type = invalid_type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T, typename C>
|
|
||||||
struct make_member_pointer<T, C, false> {
|
|
||||||
using type = error_type<T>;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T, typename C>
|
|
||||||
using make_member_pointer_t = typename make_member_pointer<T, C>::type;
|
|
||||||
}
|
|
||||||
|
|
||||||
//[ apply_member_pointer_hpp
|
|
||||||
/*`
|
|
||||||
[section:ref_apply_member_pointer apply_member_pointer]
|
|
||||||
[heading Header]
|
|
||||||
``#include <boost/callable_traits/apply_member_pointer.hpp>``
|
|
||||||
[heading Definition]
|
|
||||||
*/
|
|
||||||
|
|
||||||
template<typename T, typename C>
|
|
||||||
using apply_member_pointer_t = //see below
|
|
||||||
//<-
|
|
||||||
detail::sfinae_try<
|
|
||||||
detail::fallback_if_invalid<
|
|
||||||
typename detail::traits<T>::template apply_member_pointer<C>,
|
|
||||||
typename detail::make_member_pointer<T, C>::type>,
|
|
||||||
|
|
||||||
detail::fail_when_same<void, T, members_cannot_have_a_type_of_void>,
|
|
||||||
|
|
||||||
detail::fail_if<!std::is_class<C>::value,
|
|
||||||
second_template_argument_must_be_a_class_or_struct> >;
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
template<typename T, typename C, typename = std::false_type>
|
|
||||||
struct apply_member_pointer_impl {};
|
|
||||||
|
|
||||||
template<typename T, typename C>
|
|
||||||
struct apply_member_pointer_impl <T, C, typename std::is_same<
|
|
||||||
apply_member_pointer_t<T, C>, detail::dummy>::type>
|
|
||||||
{
|
|
||||||
using type = apply_member_pointer_t<T, C>;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
//->
|
|
||||||
|
|
||||||
template<typename T, typename C>
|
|
||||||
struct apply_member_pointer : detail::apply_member_pointer_impl<T, C> {};
|
|
||||||
|
|
||||||
//<-
|
|
||||||
}} // namespace boost::callable_traits
|
|
||||||
//->
|
|
||||||
|
|
||||||
/*`
|
|
||||||
[heading Constraints]
|
|
||||||
* `T` may be any type except `void`
|
|
||||||
* `C` must be a user-defined type
|
|
||||||
|
|
||||||
[heading Behavior]
|
|
||||||
* A substitution failure occurs if the constraints are violated.
|
|
||||||
* When `T` is a function, function pointer (unqualified), or function reference, then the aliased type is a member function pointer of `C` with the same parameters and return type.
|
|
||||||
* When `T` is a member function pointer (unqualified) of any type, the aliased type is a member function pointer of `C` with the same parameters and return type.
|
|
||||||
* Otherwise, the aliased type is a member data pointer equivalent to `std::remove_reference_t<T> C::*`.
|
|
||||||
|
|
||||||
[heading Input/Output Examples]
|
|
||||||
[table
|
|
||||||
[[`T`] [`apply_member_pointer_t<T, foo>`]]
|
|
||||||
[[`int()`] [`int(foo::*)()`]]
|
|
||||||
[[`int (&)()`] [`int(foo::*)()`]]
|
|
||||||
[[`int (*)()`] [`int(foo::*)()`]]
|
|
||||||
[[`int(bar::*)()`] [`int(foo::*)()`]]
|
|
||||||
[[`int(bar::*)() &`] [`int(foo::*)() &`]]
|
|
||||||
[[`int(bar::*)() &&`] [`int(foo::*)() &&`]]
|
|
||||||
[[`int(bar::*)() const`] [`int(foo::*)() const`]]
|
|
||||||
[[`int(bar::*)() transaction_safe`] [`int(foo::*)() transaction_safe`]]
|
|
||||||
[[`int bar::*`] [`int foo::*`]]
|
|
||||||
[[`int`] [`int foo::*`]]
|
|
||||||
[[`int &`] [`int foo::*`]]
|
|
||||||
[[`const int &`] [`const int foo::*`]]
|
|
||||||
[[`int (*const)()`] [`int (*const foo::*)()`]]
|
|
||||||
[[`void`] [(substitution failure)]]
|
|
||||||
]
|
|
||||||
|
|
||||||
[heading Example Program]
|
|
||||||
[import ../example/apply_member_pointer.cpp]
|
|
||||||
[apply_member_pointer]
|
|
||||||
[endsect]
|
|
||||||
*/
|
|
||||||
//]
|
|
||||||
#endif
|
|
||||||
@@ -1,109 +0,0 @@
|
|||||||
/*
|
|
||||||
|
|
||||||
@Copyright Barrett Adair 2015-2017
|
|
||||||
Distributed under the Boost Software License, Version 1.0.
|
|
||||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef BOOST_CLBL_TRTS_APPLY_RETURN_HPP
|
|
||||||
#define BOOST_CLBL_TRTS_APPLY_RETURN_HPP
|
|
||||||
|
|
||||||
#include <boost/callable_traits/detail/core.hpp>
|
|
||||||
|
|
||||||
namespace boost { namespace callable_traits {
|
|
||||||
|
|
||||||
BOOST_CLBL_TRTS_DEFINE_SFINAE_ERROR_ORIGIN(apply_return)
|
|
||||||
BOOST_CLBL_TRTS_SFINAE_MSG(apply_return, invalid_types_for_apply_return)
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
template<typename T, typename R>
|
|
||||||
struct apply_return_helper {
|
|
||||||
using type = typename detail::traits<T>::template apply_return<R>;
|
|
||||||
};
|
|
||||||
|
|
||||||
//special case
|
|
||||||
template<typename... Args, typename R>
|
|
||||||
struct apply_return_helper<std::tuple<Args...>, R> {
|
|
||||||
using type = R(Args...);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
//[ apply_return_hpp
|
|
||||||
/*`
|
|
||||||
[section:ref_apply_return apply_return]
|
|
||||||
[heading Header]
|
|
||||||
``#include <boost/callable_traits/apply_return.hpp>``
|
|
||||||
[heading Definition]
|
|
||||||
*/
|
|
||||||
|
|
||||||
template<typename T, typename R>
|
|
||||||
using apply_return_t = //see below
|
|
||||||
//<-
|
|
||||||
detail::try_but_fail_if_invalid<
|
|
||||||
typename detail::apply_return_helper<T, R>::type,
|
|
||||||
invalid_types_for_apply_return>;
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
template<typename T, typename R, typename = std::false_type>
|
|
||||||
struct apply_return_impl {};
|
|
||||||
|
|
||||||
template<typename T, typename R>
|
|
||||||
struct apply_return_impl <T, R, typename std::is_same<
|
|
||||||
apply_return_t<T, R>, detail::dummy>::type>
|
|
||||||
{
|
|
||||||
using type = apply_return_t<T, R>;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
//->
|
|
||||||
|
|
||||||
template<typename T, typename R>
|
|
||||||
struct apply_return : detail::apply_return_impl<T, R> {};
|
|
||||||
|
|
||||||
//<-
|
|
||||||
}} // namespace boost::callable_traits
|
|
||||||
//->
|
|
||||||
|
|
||||||
/*`
|
|
||||||
[heading Constraints]
|
|
||||||
* `T` must one of the following:
|
|
||||||
* `std::tuple` template instantiation
|
|
||||||
* function
|
|
||||||
* function pointer
|
|
||||||
* function reference
|
|
||||||
* member function pointer
|
|
||||||
* member data pointer
|
|
||||||
* If `T` is a pointer, it may not be cv/ref qualified
|
|
||||||
|
|
||||||
[heading Behavior]
|
|
||||||
* When `T` is `std::tuple<Args...>`, the aliased type is `R(Args...)`.
|
|
||||||
* When `T` is a function, function pointer, function reference, or member function pointer, the aliased type's return type is `R`, but is otherwise identical to `T`.
|
|
||||||
* When `T` is a member data pointer of class `foo` to a `U` type (such that `T` is `U foo::*`), the aliased type is `R foo::*`.
|
|
||||||
|
|
||||||
[heading Input/Output Examples]
|
|
||||||
[table
|
|
||||||
[[`T`] [`apply_return_t<T, float>`]]
|
|
||||||
[[`std::tuple<int, int>`] [`float(int, int)`]]
|
|
||||||
[[`int()`] [`float()`]]
|
|
||||||
[[`int (&)()`] [`float(&)()`]]
|
|
||||||
[[`int (*)()`] [`float(*)()`]]
|
|
||||||
[[`int (*)(...)`] [`float(*)()`]]
|
|
||||||
[[`int(foo::*)()`] [`float(foo::*)()`]]
|
|
||||||
[[`int(foo::*)() &`] [`float(foo::*)() &`]]
|
|
||||||
[[`int(foo::*)() &&`] [`float(foo::*)() &&`]]
|
|
||||||
[[`int(foo::*)() const`] [`float(foo::*)() const`]]
|
|
||||||
[[`int(foo::*)() transaction_safe`] [`float(foo::*)() transaction_safe`]]
|
|
||||||
[[`int foo::*`] [`float foo::*`]]
|
|
||||||
[[`int`] [(substitution failure)]]
|
|
||||||
[[`int (*const)()`] [(substitution failure)]]
|
|
||||||
]
|
|
||||||
|
|
||||||
[heading Example Program]
|
|
||||||
[/import ../example/apply_return.cpp]
|
|
||||||
[apply_return]
|
|
||||||
[endsect]
|
|
||||||
*/
|
|
||||||
//]
|
|
||||||
#endif
|
|
||||||
@@ -1,97 +0,0 @@
|
|||||||
/*
|
|
||||||
|
|
||||||
@Copyright Barrett Adair 2015-2017
|
|
||||||
Distributed under the Boost Software License, Version 1.0.
|
|
||||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef BOOST_CLBL_TRTS_ARGS_HPP
|
|
||||||
#define BOOST_CLBL_TRTS_ARGS_HPP
|
|
||||||
|
|
||||||
#include <boost/callable_traits/detail/core.hpp>
|
|
||||||
|
|
||||||
namespace boost { namespace callable_traits {
|
|
||||||
|
|
||||||
//[ args_hpp
|
|
||||||
/*`[section:ref_args args]
|
|
||||||
[heading Header]
|
|
||||||
``#include <boost/callable_traits/args.hpp>``
|
|
||||||
[heading Definition]
|
|
||||||
*/
|
|
||||||
|
|
||||||
template<typename T, template<class...> class Container = std::tuple>
|
|
||||||
using args_t = //see below
|
|
||||||
//<-
|
|
||||||
detail::try_but_fail_if_invalid<
|
|
||||||
typename detail::traits<
|
|
||||||
detail::shallow_decay<T>>::template expand_args<Container>,
|
|
||||||
cannot_expand_the_parameter_list_of_first_template_argument>;
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
template<typename T, template<class...> class Container,
|
|
||||||
typename = std::false_type>
|
|
||||||
struct args_impl {};
|
|
||||||
|
|
||||||
template<typename T, template<class...> class Container>
|
|
||||||
struct args_impl <T, Container, typename std::is_same<
|
|
||||||
args_t<T, Container>, detail::dummy>::type>
|
|
||||||
{
|
|
||||||
using type = args_t<T, Container>;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
//->
|
|
||||||
|
|
||||||
template<typename T,
|
|
||||||
template<class...> class Container = std::tuple>
|
|
||||||
struct args : detail::args_impl<T, Container> {};
|
|
||||||
|
|
||||||
//<-
|
|
||||||
}} // namespace boost::callable_traits
|
|
||||||
//->
|
|
||||||
|
|
||||||
/*`
|
|
||||||
[heading Constraints]
|
|
||||||
* `T` must be one of the following:
|
|
||||||
* function
|
|
||||||
* function pointer
|
|
||||||
* function reference
|
|
||||||
* member function pointer
|
|
||||||
* member data pointer
|
|
||||||
* user-defined type with a non-overloaded `operator()`
|
|
||||||
* type of a non-generic lambda
|
|
||||||
|
|
||||||
[heading Behavior]
|
|
||||||
* When the constraints are violated, a substitution failure occurs.
|
|
||||||
* When `T` is a function, function pointer, or function reference, the aliased type is `Container` instantiated with the function's parameter types.
|
|
||||||
* When `T` is a function object, the aliased type is `Container` instantiated with the `T::operator()` parameter types.
|
|
||||||
* When `T` is a member function pointer, the aliased type is a `Container` instantiation, where the first type argument is a reference to the parent class of `T`, qualified according to the member qualifiers on `T`, such that the first type is equivalent to `boost::callable_traits::qualified_class_of_t<T>`. The subsequent type arguments, if any, are the parameter types of the member function.
|
|
||||||
* When `T` is a member data pointer, the aliased type is `Container` with a single element, which is a `const` reference to the parent class of `T`.
|
|
||||||
|
|
||||||
[heading Input/Output Examples]
|
|
||||||
[table
|
|
||||||
[[`T`] [`args_t<T>`]]
|
|
||||||
[[`void(float, char, int)`] [`std::tuple<float, char, int>`]]
|
|
||||||
[[`void(*)(float, char, int)`] [`std::tuple<float, char, int`]]
|
|
||||||
[[`void(&)(float, char, int)`] [`std::tuple<float, char, int`]]
|
|
||||||
[[`void(float, char, int) const &&`][`std::tuple<float, char, int>`]]
|
|
||||||
[[`void(*)()`] [`std::tuple<>`]]
|
|
||||||
[[`void(foo::* const &)(float, char, int)`] [`std::tuple<foo&, float, char, int>`]]
|
|
||||||
[[`int(foo::*)(int) const`] [`std::tuple<const foo&, int>`]]
|
|
||||||
[[`void(foo::*)() volatile &&`] [`std::tuple<volatile foo &&>`]]
|
|
||||||
[[`int foo::*`] [`std::tuple<const foo&>`]]
|
|
||||||
[[`const int foo::*`] [`std::tuple<const foo&>`]]
|
|
||||||
[[`int`] [(substitution failure)]]
|
|
||||||
[[`int (*const)()`] [(substitution failure)]]
|
|
||||||
]
|
|
||||||
|
|
||||||
[heading Example Program]
|
|
||||||
[import ../example/args.cpp]
|
|
||||||
[args]
|
|
||||||
[endsect]
|
|
||||||
*/
|
|
||||||
//]
|
|
||||||
|
|
||||||
#endif // #ifndef BOOST_CLBL_TRTS_ARGS_HPP
|
|
||||||
@@ -1,75 +0,0 @@
|
|||||||
/*
|
|
||||||
|
|
||||||
@Copyright Barrett Adair 2015-2017
|
|
||||||
Distributed under the Boost Software License, Version 1.0.
|
|
||||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef BOOST_CLBL_TRTS_class_of_HPP
|
|
||||||
#define BOOST_CLBL_TRTS_class_of_HPP
|
|
||||||
|
|
||||||
#include <boost/callable_traits/detail/core.hpp>
|
|
||||||
|
|
||||||
namespace boost { namespace callable_traits {
|
|
||||||
|
|
||||||
//[ class_of_hpp
|
|
||||||
/*`
|
|
||||||
[section:ref_class_of class_of]
|
|
||||||
[heading Header]
|
|
||||||
``#include <boost/callable_traits/class_of.hpp>``
|
|
||||||
[heading Definition]
|
|
||||||
*/
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
using class_of_t = //see below
|
|
||||||
//<-
|
|
||||||
detail::try_but_fail_if_invalid<
|
|
||||||
typename detail::traits<detail::shallow_decay<T>>::class_type,
|
|
||||||
type_is_not_a_member_pointer>;
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
template<typename T, typename = std::false_type>
|
|
||||||
struct class_of_impl {};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct class_of_impl <T, typename std::is_same<
|
|
||||||
class_of_t<T>, detail::dummy>::type>
|
|
||||||
{
|
|
||||||
using type = class_of_t<T>;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
//->
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct class_of : detail::class_of_impl<T> {};
|
|
||||||
|
|
||||||
//<-
|
|
||||||
}} // namespace boost::callable_traits
|
|
||||||
//->
|
|
||||||
|
|
||||||
/*`
|
|
||||||
[heading Constraints]
|
|
||||||
* `T` must be a member pointer
|
|
||||||
|
|
||||||
[heading Behavior]
|
|
||||||
* A substitution failure occurs if the constraints are violated.
|
|
||||||
* The aliased type is the parent class of the member. In other words, if `T` is expanded to `U C::*`, the aliased type is `C`.
|
|
||||||
|
|
||||||
[heading Input/Output Examples]
|
|
||||||
[table
|
|
||||||
[[`T`] [`class_of_t<T>`]]
|
|
||||||
[[`int foo::*`] [`foo`]]
|
|
||||||
[[`void(foo::* const &)() const`] [`foo`]]
|
|
||||||
]
|
|
||||||
|
|
||||||
[heading Example Program]
|
|
||||||
[import ../example/class_of.cpp]
|
|
||||||
[class_of]
|
|
||||||
[endsect]
|
|
||||||
*/
|
|
||||||
//]
|
|
||||||
|
|
||||||
#endif // #ifndef BOOST_CLBL_TRTS_class_of_HPP
|
|
||||||
@@ -1,109 +0,0 @@
|
|||||||
/*
|
|
||||||
@Copyright Barrett Adair 2016-2017
|
|
||||||
|
|
||||||
Distributed under the Boost Software License, Version 1.0.
|
|
||||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef BOOST_CLBL_TRTS_DETAIL_CONFIG_HPP
|
|
||||||
#define BOOST_CLBL_TRTS_DETAIL_CONFIG_HPP
|
|
||||||
|
|
||||||
#include <type_traits>
|
|
||||||
#include <tuple>
|
|
||||||
#include <utility>
|
|
||||||
#include <cstdint>
|
|
||||||
|
|
||||||
#define BOOST_CLBL_TRTS_EMPTY_
|
|
||||||
#define BOOST_CLBL_TRTS_EMPTY BOOST_CLBL_TRTS_EMPTY_
|
|
||||||
|
|
||||||
#ifdef __cpp_transactional_memory
|
|
||||||
# define BOOST_CLBL_TRTS_ENABLE_TRANSACTION_SAFE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cpp_inline_variables
|
|
||||||
# define BOOST_CLBL_TRAITS_INLINE_VAR inline
|
|
||||||
#else
|
|
||||||
# define BOOST_CLBL_TRAITS_INLINE_VAR
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cpp_noexcept_function_type
|
|
||||||
# define BOOST_CLBL_TRTS_ENABLE_NOEXCEPT_TYPES
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef BOOST_CLBL_TRTS_ENABLE_TRANSACTION_SAFE
|
|
||||||
# define BOOST_CLBL_TRTS_TRANSACTION_SAFE_SPECIFIER transaction_safe
|
|
||||||
#else
|
|
||||||
# define BOOST_CLBL_TRTS_TRANSACTION_SAFE_SPECIFIER
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef __clang__
|
|
||||||
# if defined(__GNUC__)
|
|
||||||
# define BOOST_CLBL_TRTS_GCC
|
|
||||||
# if __GNUC__ >= 6
|
|
||||||
# define BOOST_CLBL_TRTS_GCC_AT_LEAST_6_0_0
|
|
||||||
# endif
|
|
||||||
# if __GNUC__ < 5
|
|
||||||
# define BOOST_CLBL_TRTS_GCC_OLDER_THAN_5_0_0
|
|
||||||
# endif
|
|
||||||
# if __GNUC__ >= 5
|
|
||||||
# define BOOST_CLBL_TRTS_GCC_AT_LEAST_4_9_2
|
|
||||||
# elif __GNUC__ == 4 && __GNUC_MINOR__ == 9 && __GNUC_PATCHLEVEL__ >= 2
|
|
||||||
# define BOOST_CLBL_TRTS_GCC_AT_LEAST_4_9_2
|
|
||||||
# else
|
|
||||||
# define BOOST_CLBL_TRTS_GCC_OLDER_THAN_4_9_2
|
|
||||||
# endif //#if __GNUC__ >= 5
|
|
||||||
# endif //#if defined __GNUC__
|
|
||||||
#endif // #ifndef __clang__
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
# ifdef __clang__
|
|
||||||
# define BOOST_CLBL_TRTS_CLANG_C2
|
|
||||||
# else
|
|
||||||
# define BOOST_CLBL_TRTS_MSVC
|
|
||||||
# endif // #ifdef __clang__
|
|
||||||
#endif // #ifdef _MSC_VER
|
|
||||||
|
|
||||||
#define BOOST_CLBL_TRTS_IX_SEQ(...) ::std::index_sequence< __VA_ARGS__ >
|
|
||||||
#define BOOST_CLBL_TRTS_MAKE_IX_SEQ(...) ::std::make_index_sequence< __VA_ARGS__ >
|
|
||||||
#define BOOST_CLBL_TRTS_DISJUNCTION(...) ::std::disjunction< __VA_ARGS__ >
|
|
||||||
|
|
||||||
#ifndef __cpp_variable_templates
|
|
||||||
# define BOOST_CLBL_TRTS_DISABLE_VARIABLE_TEMPLATES
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef __cpp_lib_logical_traits
|
|
||||||
# include <boost/callable_traits/detail/polyfills/disjunction.hpp>
|
|
||||||
#endif //__cpp_lib_logical_traits
|
|
||||||
|
|
||||||
#ifndef __cpp_lib_integer_sequence
|
|
||||||
# include <boost/callable_traits/detail/polyfills/make_index_sequence.hpp>
|
|
||||||
#endif // __cpp_lib_integer_sequence
|
|
||||||
|
|
||||||
#if defined(BOOST_CLBL_TRTS_MSVC) && !defined(BOOST_DISABLE_WIN32)
|
|
||||||
# define BOOST_CLBL_TRTS_DEFAULT_VARARGS_CC __cdecl
|
|
||||||
# define BOOST_CLBL_TRTS_PMF_VARGARGS_CDECL_DEFAULT
|
|
||||||
#else
|
|
||||||
# define BOOST_CLBL_TRTS_DEFAULT_VARARGS_CC
|
|
||||||
#endif // #if defined(BOOST_CLBL_TRTS_MSVC) && !defined(BOOST_DISABLE_WIN32))
|
|
||||||
|
|
||||||
#if (defined(BOOST_CLBL_TRTS_GCC) && !defined(BOOST_CLBL_TRTS_GCC_AT_LEAST_4_9_2)) || defined(__INTEL_COMPILER)
|
|
||||||
# define BOOST_CLBL_TRTS_DISABLE_REFERENCE_QUALIFIERS
|
|
||||||
# define BOOST_CLBL_TRTS_DISABLE_ABOMINABLE_FUNCTIONS
|
|
||||||
#endif // #if defined BOOST_CLBL_TRTS_GCC && !defined(BOOST_CLBL_TRTS_GCC_AT_LEAST_4_9_2)
|
|
||||||
|
|
||||||
#ifdef BOOST_CLBL_TRTS_DISABLE_ABOMINABLE_FUNCTIONS
|
|
||||||
# define BOOST_CLBL_TRTS_ABOMINABLE_CONST BOOST_CLBL_TRTS_EMPTY
|
|
||||||
# define BOOST_CLBL_TRTS_ABOMINABLE_VOLATILE BOOST_CLBL_TRTS_EMPTY
|
|
||||||
#else
|
|
||||||
# define BOOST_CLBL_TRTS_ABOMINABLE_CONST const
|
|
||||||
# define BOOST_CLBL_TRTS_ABOMINABLE_VOLATILE volatile
|
|
||||||
#endif // #ifdef BOOST_CLBL_TRTS_DISABLE_ABOMINABLE_FUNCTIONS
|
|
||||||
|
|
||||||
#ifdef BOOST_CLBL_TRTS_ENABLE_NOEXCEPT_TYPES
|
|
||||||
# define BOOST_CLBL_TRTS_NOEXCEPT_SPECIFIER noexcept
|
|
||||||
#else
|
|
||||||
# define BOOST_CLBL_TRTS_NOEXCEPT_SPECIFIER BOOST_CLBL_TRTS_EMPTY
|
|
||||||
#endif // #ifdef BOOST_CLBL_TRTS_ENABLE_NOEXCEPT_TYPES
|
|
||||||
|
|
||||||
#endif // #ifndef BOOST_CLBL_TRTS_DETAIL_CONFIG_HPP
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
/*
|
|
||||||
|
|
||||||
@Copyright Barrett Adair 2016-2017
|
|
||||||
Distributed under the Boost Software License, Version 1.0.
|
|
||||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef BOOST_CLBL_TRTS_DETAIL_CORE_HPP
|
|
||||||
#define BOOST_CLBL_TRTS_DETAIL_CORE_HPP
|
|
||||||
|
|
||||||
#include <boost/callable_traits/detail/utility.hpp>
|
|
||||||
#include <boost/callable_traits/detail/traits.hpp>
|
|
||||||
#include <boost/callable_traits/detail/function_object.hpp>
|
|
||||||
#include <boost/callable_traits/detail/function.hpp>
|
|
||||||
#include <boost/callable_traits/detail/pmf.hpp>
|
|
||||||
#include <boost/callable_traits/detail/pmd.hpp>
|
|
||||||
|
|
||||||
#endif // #ifndef BOOST_CLBL_TRTS_DETAIL_CORE_HPP
|
|
||||||
@@ -1,207 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright Barrett Adair 2016-2017
|
|
||||||
|
|
||||||
Distributed under the Boost Software License, Version 1.0.
|
|
||||||
(See accompanying file LICENSE.md or copy at http ://boost.org/LICENSE_1_0.txt)
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef BOOST_CLBL_TRTS_DETAIL_DEFAULT_BOOST_CLBL_TRTS_HPP
|
|
||||||
#define BOOST_CLBL_TRTS_DETAIL_DEFAULT_BOOST_CLBL_TRTS_HPP
|
|
||||||
|
|
||||||
namespace boost { namespace callable_traits { namespace detail {
|
|
||||||
|
|
||||||
template<typename T = void>
|
|
||||||
struct default_callable_traits {
|
|
||||||
|
|
||||||
// value is used by all traits classes to participate
|
|
||||||
// in the <callable_traits/detail/traits.hpp> disjunction.
|
|
||||||
static constexpr bool value = false;
|
|
||||||
|
|
||||||
// used facilitate the disjunction in
|
|
||||||
// <callable_traits/detail/traits.hpp>
|
|
||||||
using traits = default_callable_traits;
|
|
||||||
|
|
||||||
using error_t = error_type<T>;
|
|
||||||
|
|
||||||
// represents the type under consideration
|
|
||||||
using type = error_t;
|
|
||||||
|
|
||||||
// std::true_type for callables with C-style variadics
|
|
||||||
using has_varargs = std::false_type;
|
|
||||||
|
|
||||||
using return_type = error_t;
|
|
||||||
|
|
||||||
// arg_types is a std::tuple of argument types for
|
|
||||||
// callables that are not overloaded/templated function objects.
|
|
||||||
// arg_types IS defined in terms of INVOKE, which means
|
|
||||||
// a PMF's arg_types tuple will use a reference to its
|
|
||||||
// parent class as the first argument, with qualifiers added to
|
|
||||||
// match the PMF's own qualifiers.
|
|
||||||
using arg_types = error_t;
|
|
||||||
|
|
||||||
// arg_types without the decltype(*this) parameter for member functions
|
|
||||||
using non_invoke_arg_types = error_t;
|
|
||||||
|
|
||||||
// An "approximation" of a callable type, in the form
|
|
||||||
// of a plain function type. Defined in terms of INVOKE.
|
|
||||||
// An identity alias for qualified/unqualified plain function
|
|
||||||
// types.
|
|
||||||
using function_type = error_t;
|
|
||||||
|
|
||||||
// Used to smoothen the edges between PMFs and function objects
|
|
||||||
using function_object_signature = error_t;
|
|
||||||
|
|
||||||
// An identity alias for qualified/unqualified plain function
|
|
||||||
// types. Equivalent to remove_member_pointer for PMFs. Same
|
|
||||||
// as function_type for other callable types.
|
|
||||||
using qualified_function_type = error_t;
|
|
||||||
|
|
||||||
// Removes C-style variadics from a signature, if present.
|
|
||||||
// Aliases error_t for function objects and PMDs.
|
|
||||||
using remove_varargs = error_t;
|
|
||||||
|
|
||||||
// Adds C-style variadics to a signature. Aliases
|
|
||||||
// error_t for function objects and PMDs.
|
|
||||||
using add_varargs = error_t;
|
|
||||||
|
|
||||||
// std::true_type when the signature includes noexcept, when
|
|
||||||
// the feature is available
|
|
||||||
using is_noexcept = std::false_type;
|
|
||||||
|
|
||||||
// adds noexcept to a signature if the feature is available
|
|
||||||
using add_noexcept = error_t;
|
|
||||||
|
|
||||||
// removes noexcept from a signature if present
|
|
||||||
using remove_noexcept = error_t;
|
|
||||||
|
|
||||||
// std::true_type when the signature includes transaction_safe, when
|
|
||||||
// the feature is available
|
|
||||||
using is_transaction_safe = std::false_type;
|
|
||||||
|
|
||||||
// adds transaction_safe to a signature if the feature is available
|
|
||||||
using add_transaction_safe = error_t;
|
|
||||||
|
|
||||||
// removes transaction_safe from a signature if present
|
|
||||||
using remove_transaction_safe = error_t;
|
|
||||||
|
|
||||||
// The class of a PMD or PMF. error_t for other types
|
|
||||||
using class_type = error_t;
|
|
||||||
|
|
||||||
// The qualified reference type of class_type. error_t
|
|
||||||
// for non-member-pointers.
|
|
||||||
using invoke_type = error_t;
|
|
||||||
|
|
||||||
// Removes reference qualifiers from a signature.
|
|
||||||
using remove_reference = error_t;
|
|
||||||
|
|
||||||
// Adds an lvalue qualifier to a signature, in arbitrary
|
|
||||||
// accordance with C++11 reference collapsing rules.
|
|
||||||
using add_member_lvalue_reference = error_t;
|
|
||||||
|
|
||||||
// Adds an rvalue qualifier to a signature, in arbitrary
|
|
||||||
// accordance with C++11 reference collapsing rules.
|
|
||||||
using add_member_rvalue_reference = error_t;
|
|
||||||
|
|
||||||
// Adds a const qualifier to a signature.
|
|
||||||
using add_member_const = error_t;
|
|
||||||
|
|
||||||
// Adds a volatile qualifier to a signature.
|
|
||||||
using add_member_volatile = error_t;
|
|
||||||
|
|
||||||
// Adds both const and volatile qualifiers to a signature.
|
|
||||||
using add_member_cv = error_t;
|
|
||||||
|
|
||||||
// Removes a const qualifier from a signature, if present.
|
|
||||||
using remove_member_const = error_t;
|
|
||||||
|
|
||||||
// Removes a volatile qualifier from a signature, if present.
|
|
||||||
using remove_member_volatile = error_t;
|
|
||||||
|
|
||||||
// Removes both const and volatile qualifiers from a
|
|
||||||
// signature, if any.
|
|
||||||
using remove_member_cv = error_t;
|
|
||||||
|
|
||||||
// Removes the member pointer from PMDs and PMFs. An identity
|
|
||||||
// alias for other callable types.
|
|
||||||
using remove_member_pointer = error_t;
|
|
||||||
|
|
||||||
// Changes the parent class type for PMDs and PMFs. Turns
|
|
||||||
// function pointers, function references, and
|
|
||||||
// qualified/unqualified function types into PMFs. Turns
|
|
||||||
// everything else into member data pointers.
|
|
||||||
template<typename C,
|
|
||||||
typename U = T,
|
|
||||||
typename K = typename std::remove_reference<U>::type,
|
|
||||||
typename L = typename std::conditional<
|
|
||||||
std::is_same<void, K>::value, error_t, K>::type,
|
|
||||||
typename Class = typename std::conditional<
|
|
||||||
std::is_class<C>::value, C, error_t>::type>
|
|
||||||
using apply_member_pointer = typename std::conditional<
|
|
||||||
std::is_same<L, error_t>::value || std::is_same<Class, error_t>::value,
|
|
||||||
error_t, L Class::*>::type;
|
|
||||||
|
|
||||||
// Changes the return type of PMFs, function pointers, function
|
|
||||||
// references, and qualified/unqualified function types. Changes
|
|
||||||
// the data type of PMDs. error_t for function objects.
|
|
||||||
template<typename>
|
|
||||||
using apply_return = error_t;
|
|
||||||
|
|
||||||
// Expands the argument types into a template
|
|
||||||
template<template<class...> class Container>
|
|
||||||
using expand_args = error_t;
|
|
||||||
|
|
||||||
template<template<class...> class Container, typename... RightArgs>
|
|
||||||
using expand_args_left = error_t;
|
|
||||||
|
|
||||||
template<template<class...> class Container, typename... LeftArgs>
|
|
||||||
using expand_args_right = error_t;
|
|
||||||
|
|
||||||
using clear_args = error_t;
|
|
||||||
|
|
||||||
template<typename... NewArgs>
|
|
||||||
using push_front = error_t;
|
|
||||||
|
|
||||||
template<typename... NewArgs>
|
|
||||||
using push_back = error_t;
|
|
||||||
|
|
||||||
template<std::size_t ElementCount>
|
|
||||||
using pop_front = error_t;
|
|
||||||
|
|
||||||
template<std::size_t ElementCount>
|
|
||||||
using pop_back = error_t;
|
|
||||||
|
|
||||||
template<std::size_t Index, typename... NewArgs>
|
|
||||||
using insert_args = error_t;
|
|
||||||
|
|
||||||
template<std::size_t Index, std::size_t Count>
|
|
||||||
using remove_args = error_t;
|
|
||||||
|
|
||||||
template<std::size_t Index, typename... NewArgs>
|
|
||||||
using replace_args = error_t;
|
|
||||||
|
|
||||||
static constexpr qualifier_flags cv_flags = cv_of<T>::value;
|
|
||||||
static constexpr qualifier_flags ref_flags = ref_of<T>::value;
|
|
||||||
static constexpr qualifier_flags q_flags = cv_flags | ref_flags;
|
|
||||||
|
|
||||||
using has_member_qualifiers = std::integral_constant<bool, q_flags != default_>;
|
|
||||||
using is_const_member = std::integral_constant<bool, 0 < (cv_flags & const_)>;
|
|
||||||
using is_volatile_member = std::integral_constant<bool, 0 < (cv_flags & volatile_)>;
|
|
||||||
using is_cv_member = std::integral_constant<bool, cv_flags == (const_ | volatile_)>;
|
|
||||||
|
|
||||||
#ifdef BOOST_CLBL_TRTS_DISABLE_REFERENCE_QUALIFIERS
|
|
||||||
using is_reference_member = std::false_type;
|
|
||||||
using is_lvalue_reference_member = std::false_type;
|
|
||||||
using is_rvalue_reference_member = std::false_type;
|
|
||||||
#else
|
|
||||||
using is_reference_member = std::integral_constant<bool, 0 < ref_flags>;
|
|
||||||
using is_lvalue_reference_member = std::integral_constant<bool, ref_flags == lref_>;
|
|
||||||
using is_rvalue_reference_member = std::integral_constant<bool, ref_flags == rref_>;
|
|
||||||
#endif //#ifdef BOOST_CLBL_TRTS_DISABLE_REFERENCE_QUALIFIERS
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
}}} // namespace boost::callable_traits::detail
|
|
||||||
|
|
||||||
#endif // BOOST_CLBL_TRTS_DETAIL_DEFAULT_BOOST_CLBL_TRTS_HPP
|
|
||||||
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
#ifndef BOOST_CLBL_TRTS_DETAIL_FORWARD_DECLARATIONS
|
|
||||||
#define BOOST_CLBL_TRTS_DETAIL_FORWARD_DECLARATIONS
|
|
||||||
#include <boost/callable_traits/detail/config.hpp>
|
|
||||||
#include <boost/callable_traits/detail/default_callable_traits.hpp>
|
|
||||||
|
|
||||||
namespace boost { namespace callable_traits { namespace detail {
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct function;
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct has_normal_call_operator
|
|
||||||
{
|
|
||||||
template<typename N, N Value>
|
|
||||||
struct check { check(std::nullptr_t) {} };
|
|
||||||
|
|
||||||
template<typename U>
|
|
||||||
static std::int8_t test(
|
|
||||||
check<decltype(&U::operator()), &U::operator()>);
|
|
||||||
|
|
||||||
template<typename>
|
|
||||||
static std::int16_t test(...);
|
|
||||||
|
|
||||||
static constexpr bool value =
|
|
||||||
sizeof(test<T>(nullptr)) == sizeof(std::int8_t);
|
|
||||||
};
|
|
||||||
|
|
||||||
struct callable_dummy {
|
|
||||||
void operator()() {}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
using default_to_function_object = typename std::conditional<
|
|
||||||
has_normal_call_operator<T>::value,
|
|
||||||
T, callable_dummy>::type;
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct pmf;
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct pmd;
|
|
||||||
|
|
||||||
template<typename F, typename T = typename std::remove_reference<F>::type>
|
|
||||||
using function_object_base = typename std::conditional<
|
|
||||||
has_normal_call_operator<T>::value,
|
|
||||||
pmf<decltype(&default_to_function_object<T>::operator())>,
|
|
||||||
default_callable_traits<T>>::type;
|
|
||||||
|
|
||||||
template<typename T, typename Base = function_object_base<T>>
|
|
||||||
struct function_object;
|
|
||||||
|
|
||||||
}}} // namespace boost::callable_traits::detail
|
|
||||||
|
|
||||||
#endif // #ifndef BOOST_CLBL_TRTS_DETAIL_FORWARD_DECLARATIONS
|
|
||||||
@@ -1,192 +0,0 @@
|
|||||||
/*
|
|
||||||
|
|
||||||
@Copyright Barrett Adair 2015-2017
|
|
||||||
Distributed under the Boost Software License, Version 1.0.
|
|
||||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef BOOST_CLBL_TRTS_DETAIL_FUNCTION_HPP
|
|
||||||
#define BOOST_CLBL_TRTS_DETAIL_FUNCTION_HPP
|
|
||||||
|
|
||||||
#include <boost/callable_traits/detail/config.hpp>
|
|
||||||
#include <boost/callable_traits/detail/qualifier_flags.hpp>
|
|
||||||
#include <boost/callable_traits/detail/forward_declarations.hpp>
|
|
||||||
#include <boost/callable_traits/detail/set_function_qualifiers.hpp>
|
|
||||||
#include <boost/callable_traits/detail/default_callable_traits.hpp>
|
|
||||||
|
|
||||||
namespace boost { namespace callable_traits { namespace detail {
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct function : default_callable_traits<T> {};
|
|
||||||
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
#include <boost/callable_traits/detail/unguarded/function.hpp>
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
|
|
||||||
#ifndef BOOST_CLBL_TRTS_DISABLE_ABOMINABLE_FUNCTIONS
|
|
||||||
|
|
||||||
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS const
|
|
||||||
#include <boost/callable_traits/detail/unguarded/function.hpp>
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
|
|
||||||
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS volatile
|
|
||||||
#include <boost/callable_traits/detail/unguarded/function.hpp>
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
|
|
||||||
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS const volatile
|
|
||||||
#include <boost/callable_traits/detail/unguarded/function.hpp>
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
|
|
||||||
#ifndef BOOST_CLBL_TRTS_DISABLE_REFERENCE_QUALIFIERS
|
|
||||||
|
|
||||||
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS &
|
|
||||||
#include <boost/callable_traits/detail/unguarded/function.hpp>
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
|
|
||||||
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS &&
|
|
||||||
#include <boost/callable_traits/detail/unguarded/function.hpp>
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
|
|
||||||
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS const &
|
|
||||||
#include <boost/callable_traits/detail/unguarded/function.hpp>
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
|
|
||||||
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS const &&
|
|
||||||
#include <boost/callable_traits/detail/unguarded/function.hpp>
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
|
|
||||||
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS volatile &
|
|
||||||
#include <boost/callable_traits/detail/unguarded/function.hpp>
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
|
|
||||||
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS volatile &&
|
|
||||||
#include <boost/callable_traits/detail/unguarded/function.hpp>
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
|
|
||||||
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS const volatile &
|
|
||||||
#include <boost/callable_traits/detail/unguarded/function.hpp>
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
|
|
||||||
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS const volatile &&
|
|
||||||
#include <boost/callable_traits/detail/unguarded/function.hpp>
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
|
|
||||||
#endif // #ifndef BOOST_CLBL_TRTS_DISABLE_REFERENCE_QUALIFIERS
|
|
||||||
#endif // #ifndef BOOST_CLBL_TRTS_DISABLE_ABOMINABLE_FUNCTIONS
|
|
||||||
|
|
||||||
// function pointers
|
|
||||||
|
|
||||||
#define BOOST_CLBL_TRTS_CC_TAG dummy
|
|
||||||
#define BOOST_CLBL_TRTS_VARARGS_CC BOOST_CLBL_TRTS_DEFAULT_VARARGS_CC
|
|
||||||
#define BOOST_CLBL_TRTS_CC
|
|
||||||
#define BOOST_CLBL_TRTS_ST
|
|
||||||
#include <boost/callable_traits/detail/unguarded/function_ptr.hpp>
|
|
||||||
#include <boost/callable_traits/detail/unguarded/function_ptr_varargs.hpp>
|
|
||||||
#undef BOOST_CLBL_TRTS_ST
|
|
||||||
#undef BOOST_CLBL_TRTS_CC
|
|
||||||
#undef BOOST_CLBL_TRTS_CC_TAG
|
|
||||||
#undef BOOST_CLBL_TRTS_VARARGS_CC
|
|
||||||
|
|
||||||
/* ?
|
|
||||||
#ifdef BOOST_CLBL_TRTS_ENABLE_CDECL
|
|
||||||
#define BOOST_CLBL_TRTS_CC_TAG cdecl_tag
|
|
||||||
#define BOOST_CLBL_TRTS_VARARGS_CC __cdecl
|
|
||||||
#define BOOST_CLBL_TRTS_CC __cdecl
|
|
||||||
#define BOOST_CLBL_TRTS_ST
|
|
||||||
#include <boost/callable_traits/detail/unguarded/function_ptr.hpp>
|
|
||||||
#undef BOOST_CLBL_TRTS_ST
|
|
||||||
#undef BOOST_CLBL_TRTS_CC
|
|
||||||
#undef BOOST_CLBL_TRTS_CC_TAG
|
|
||||||
#undef BOOST_CLBL_TRTS_VARARGS_CC
|
|
||||||
#endif*/
|
|
||||||
|
|
||||||
#ifdef BOOST_CLBL_TRTS_ENABLE_STDCALL
|
|
||||||
#define BOOST_CLBL_TRTS_CC_TAG stdcall_tag
|
|
||||||
#define BOOST_CLBL_TRTS_VARARGS_CC BOOST_CLBL_TRTS_DEFAULT_VARARGS_CC
|
|
||||||
#define BOOST_CLBL_TRTS_CC __stdcall
|
|
||||||
#define BOOST_CLBL_TRTS_ST
|
|
||||||
#include <boost/callable_traits/detail/unguarded/function_ptr.hpp>
|
|
||||||
#undef BOOST_CLBL_TRTS_ST
|
|
||||||
#undef BOOST_CLBL_TRTS_CC
|
|
||||||
#undef BOOST_CLBL_TRTS_CC_TAG
|
|
||||||
#undef BOOST_CLBL_TRTS_VARARGS_CC
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef BOOST_CLBL_TRTS_ENABLE_FASTCALL
|
|
||||||
#define BOOST_CLBL_TRTS_CC_TAG fastcall_tag
|
|
||||||
#define BOOST_CLBL_TRTS_VARARGS_CC BOOST_CLBL_TRTS_DEFAULT_VARARGS_CC
|
|
||||||
#define BOOST_CLBL_TRTS_CC __fastcall
|
|
||||||
#define BOOST_CLBL_TRTS_ST
|
|
||||||
#include <boost/callable_traits/detail/unguarded/function_ptr.hpp>
|
|
||||||
#undef BOOST_CLBL_TRTS_CC
|
|
||||||
#undef BOOST_CLBL_TRTS_ST
|
|
||||||
#undef BOOST_CLBL_TRTS_CC_TAG
|
|
||||||
#undef BOOST_CLBL_TRTS_VARARGS_CC
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef BOOST_CLBL_TRTS_ENABLE_PASCAL
|
|
||||||
#define BOOST_CLBL_TRTS_CC_TAG pascal_tag
|
|
||||||
#define BOOST_CLBL_TRTS_VARARGS_CC BOOST_CLBL_TRTS_DEFAULT_VARARGS_CC
|
|
||||||
#define BOOST_CLBL_TRTS_CC
|
|
||||||
#define BOOST_CLBL_TRTS_ST pascal
|
|
||||||
#include <boost/callable_traits/detail/unguarded/function_ptr.hpp>
|
|
||||||
#undef BOOST_CLBL_TRTS_CC
|
|
||||||
#undef BOOST_CLBL_TRTS_ST
|
|
||||||
#undef BOOST_CLBL_TRTS_CC_TAG
|
|
||||||
#undef BOOST_CLBL_TRTS_VARARGS_CC
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct function<T&> : std::conditional<function<T>::value,
|
|
||||||
function<T>, default_callable_traits<T&>>::type {
|
|
||||||
|
|
||||||
static constexpr const bool value = !std::is_pointer<T>::value;
|
|
||||||
|
|
||||||
using traits = function;
|
|
||||||
using base = function<T>;
|
|
||||||
using type = T&;
|
|
||||||
using remove_varargs = typename base::remove_varargs&;
|
|
||||||
using add_varargs = typename base::add_varargs&;
|
|
||||||
|
|
||||||
using remove_member_reference = reference_error;
|
|
||||||
using add_member_lvalue_reference = reference_error;
|
|
||||||
using add_member_rvalue_reference = reference_error;
|
|
||||||
using add_member_const = reference_error;
|
|
||||||
using add_member_volatile = reference_error;
|
|
||||||
using add_member_cv = reference_error;
|
|
||||||
using remove_member_const = reference_error;
|
|
||||||
using remove_member_volatile = reference_error;
|
|
||||||
using remove_member_cv = reference_error;
|
|
||||||
|
|
||||||
template<typename NewReturn>
|
|
||||||
using apply_return = typename base::template apply_return<NewReturn>&;
|
|
||||||
|
|
||||||
using clear_args = typename base::clear_args&;
|
|
||||||
|
|
||||||
template<typename... NewArgs>
|
|
||||||
using push_front = typename base::template push_front<NewArgs...>&;
|
|
||||||
|
|
||||||
template<typename... NewArgs>
|
|
||||||
using push_back = typename base::template push_back<NewArgs...>&;
|
|
||||||
|
|
||||||
template<std::size_t Count>
|
|
||||||
using pop_back = typename base::template pop_back<Count>&;
|
|
||||||
|
|
||||||
template<std::size_t Count>
|
|
||||||
using pop_front = typename base::template pop_front<Count>&;
|
|
||||||
|
|
||||||
template<std::size_t Index, typename... NewArgs>
|
|
||||||
using insert_args = typename base::template insert_args<Index, NewArgs...>&;
|
|
||||||
|
|
||||||
template<std::size_t Index, std::size_t Count>
|
|
||||||
using remove_args = typename base::template remove_args<Index, Count>&;
|
|
||||||
|
|
||||||
template<std::size_t Index, typename... NewArgs>
|
|
||||||
using replace_args = typename base::template replace_args<Index, NewArgs...>&;
|
|
||||||
};
|
|
||||||
|
|
||||||
}}} // namespace boost::callable_traits::detail
|
|
||||||
|
|
||||||
#endif // #ifndef BOOST_CLBL_TRTS_DETAIL_FUNCTION_HPP
|
|
||||||
@@ -1,107 +0,0 @@
|
|||||||
/*
|
|
||||||
|
|
||||||
@Copyright Barrett Adair 2015-2017
|
|
||||||
Distributed under the Boost Software License, Version 1.0.
|
|
||||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef BOOST_CLBL_TRTS_DETAIL_FUNCTION_OBJECT_HPP
|
|
||||||
#define BOOST_CLBL_TRTS_DETAIL_FUNCTION_OBJECT_HPP
|
|
||||||
|
|
||||||
#include <boost/callable_traits/detail/pmf.hpp>
|
|
||||||
#include <boost/callable_traits/detail/default_callable_traits.hpp>
|
|
||||||
#include <boost/callable_traits/detail/forward_declarations.hpp>
|
|
||||||
#include <boost/callable_traits/detail/utility.hpp>
|
|
||||||
|
|
||||||
namespace boost { namespace callable_traits { namespace detail {
|
|
||||||
|
|
||||||
template<typename T, typename Base>
|
|
||||||
struct function_object : Base {
|
|
||||||
|
|
||||||
using type = T;
|
|
||||||
using error_t = error_type<T>;
|
|
||||||
using function_type = typename Base::function_object_signature;
|
|
||||||
using arg_types = typename Base::non_invoke_arg_types;
|
|
||||||
using non_invoke_arg_types = arg_types;
|
|
||||||
|
|
||||||
static constexpr const bool value = std::is_class<
|
|
||||||
typename std::remove_reference<T>::type>::value;
|
|
||||||
|
|
||||||
using traits = function_object;
|
|
||||||
using class_type = error_t;
|
|
||||||
using invoke_type = error_t;
|
|
||||||
using remove_varargs = error_t;
|
|
||||||
using add_varargs = error_t;
|
|
||||||
using is_noexcept = typename Base::is_noexcept;
|
|
||||||
using add_noexcept = error_t;
|
|
||||||
using remove_noexcept = error_t;
|
|
||||||
using is_transaction_safe = typename Base::is_transaction_safe;
|
|
||||||
using add_transaction_safe = error_t;
|
|
||||||
using remove_transaction_safe = error_t;
|
|
||||||
using clear_args = error_t;
|
|
||||||
|
|
||||||
template<template<class...> class Container>
|
|
||||||
using expand_args = typename function<function_type>::template
|
|
||||||
expand_args<Container>;
|
|
||||||
|
|
||||||
template<template<class...> class Container, typename... RightArgs>
|
|
||||||
using expand_args_left = typename function<function_type>::template
|
|
||||||
expand_args_left<Container, RightArgs...>;
|
|
||||||
|
|
||||||
template<template<class...> class Container, typename... LeftArgs>
|
|
||||||
using expand_args_right = typename function<function_type>::template
|
|
||||||
expand_args_right<Container, LeftArgs...>;
|
|
||||||
|
|
||||||
template<typename C, typename U = T>
|
|
||||||
using apply_member_pointer =
|
|
||||||
typename std::remove_reference<U>::type C::*;
|
|
||||||
|
|
||||||
template<typename>
|
|
||||||
using apply_return = error_t;
|
|
||||||
|
|
||||||
template<typename...>
|
|
||||||
using push_front = error_t;
|
|
||||||
|
|
||||||
template<typename...>
|
|
||||||
using push_back = error_t;
|
|
||||||
|
|
||||||
template<std::size_t ElementCount>
|
|
||||||
using pop_args_front = error_t;
|
|
||||||
|
|
||||||
template<std::size_t ElementCount>
|
|
||||||
using pop_args_back = error_t;
|
|
||||||
|
|
||||||
template<std::size_t Index, typename... NewArgs>
|
|
||||||
using insert_args = error_t;
|
|
||||||
|
|
||||||
template<std::size_t Index, std::size_t Count>
|
|
||||||
using remove_args = error_t;
|
|
||||||
|
|
||||||
template<std::size_t Index, typename... NewArgs>
|
|
||||||
using replace_args = error_t;
|
|
||||||
|
|
||||||
template<std::size_t Count>
|
|
||||||
using pop_front = error_t;
|
|
||||||
|
|
||||||
template<std::size_t Count>
|
|
||||||
using pop_back = error_t;
|
|
||||||
|
|
||||||
using remove_member_reference = error_t;
|
|
||||||
using add_member_lvalue_reference = error_t;
|
|
||||||
using add_member_rvalue_reference = error_t;
|
|
||||||
using add_member_const = error_t;
|
|
||||||
using add_member_volatile = error_t;
|
|
||||||
using add_member_cv = error_t;
|
|
||||||
using remove_member_const = error_t;
|
|
||||||
using remove_member_volatile = error_t;
|
|
||||||
using remove_member_cv = error_t;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T, typename U, typename Base>
|
|
||||||
struct function_object <T U::*, Base>
|
|
||||||
: default_callable_traits<> {};
|
|
||||||
|
|
||||||
}}} // namespace boost::callable_traits::detail
|
|
||||||
|
|
||||||
#endif // #ifndef BOOST_CLBL_TRTS_DETAIL_FUNCTION_OBJECT_HPP
|
|
||||||
@@ -1,148 +0,0 @@
|
|||||||
/*!
|
|
||||||
@file
|
|
||||||
|
|
||||||
@Copyright Barrett Adair 2015-2017
|
|
||||||
Distributed under the Boost Software License, Version 1.0.
|
|
||||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef BOOST_CLBL_TRTS_IS_INVOCABLE_IMPL_HPP
|
|
||||||
#define BOOST_CLBL_TRTS_IS_INVOCABLE_IMPL_HPP
|
|
||||||
|
|
||||||
#include <boost/callable_traits/detail/config.hpp>
|
|
||||||
#include <boost/callable_traits/detail/forward_declarations.hpp>
|
|
||||||
#include <boost/callable_traits/detail/utility.hpp>
|
|
||||||
#include <type_traits>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
namespace boost { namespace callable_traits { namespace detail {
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct can_dereference_t
|
|
||||||
{
|
|
||||||
template<typename>
|
|
||||||
struct check {};
|
|
||||||
|
|
||||||
template<typename U>
|
|
||||||
static std::int8_t test(
|
|
||||||
check<typename std::remove_reference<decltype(*std::declval<U>())>::type>*
|
|
||||||
);
|
|
||||||
|
|
||||||
template<typename>
|
|
||||||
static std::int16_t test(...);
|
|
||||||
|
|
||||||
static constexpr const bool value =
|
|
||||||
sizeof(test<T>(nullptr)) == sizeof(std::int8_t);
|
|
||||||
};
|
|
||||||
|
|
||||||
//returns std::true_type for pointers and smart pointers
|
|
||||||
template<typename T>
|
|
||||||
using can_dereference = std::integral_constant<bool,
|
|
||||||
can_dereference_t<T>::value>;
|
|
||||||
|
|
||||||
|
|
||||||
template<typename T, typename = std::true_type>
|
|
||||||
struct generalize_t {
|
|
||||||
using type = T;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct generalize_t<T, std::integral_constant<bool,
|
|
||||||
can_dereference<T>::value && !is_reference_wrapper<T>::value
|
|
||||||
>>{
|
|
||||||
using type = decltype(*std::declval<T>());
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct generalize_t<T, is_reference_wrapper<T>> {
|
|
||||||
using type = decltype(std::declval<T>().get());
|
|
||||||
};
|
|
||||||
|
|
||||||
// When T is a pointer, generalize<T> is the resulting type of the
|
|
||||||
// pointer dereferenced. When T is an std::reference_wrapper, generalize<T>
|
|
||||||
// is the underlying reference type. Otherwise, generalize<T> is T.
|
|
||||||
template<typename T>
|
|
||||||
using generalize = typename generalize_t<T>::type;
|
|
||||||
|
|
||||||
// handles the member pointer rules of INVOKE
|
|
||||||
template<typename Base, typename T,
|
|
||||||
typename IsBaseOf = std::is_base_of<Base, shallow_decay<T>>,
|
|
||||||
typename IsSame = std::is_same<Base, shallow_decay<T>>>
|
|
||||||
using generalize_if_dissimilar = typename std::conditional<
|
|
||||||
IsBaseOf::value || IsSame::value, T, generalize<T>>::type;
|
|
||||||
|
|
||||||
template<typename Traits, bool = Traits::is_const_member::value
|
|
||||||
|| Traits::is_volatile_member::value
|
|
||||||
|| Traits::is_lvalue_reference_member::value
|
|
||||||
|| Traits::is_rvalue_reference_member::value>
|
|
||||||
struct test_invoke {
|
|
||||||
|
|
||||||
template<typename... Rgs,
|
|
||||||
typename U = typename Traits::type>
|
|
||||||
auto operator()(Rgs&&... rgs) const ->
|
|
||||||
success<decltype(std::declval<U>()(static_cast<Rgs&&>(rgs)...))>;
|
|
||||||
|
|
||||||
auto operator()(...) const -> substitution_failure;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename F>
|
|
||||||
struct test_invoke<function<F>, true /*abominable*/> {
|
|
||||||
auto operator()(...) const -> substitution_failure;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Pmf, bool Ignored>
|
|
||||||
struct test_invoke<pmf<Pmf>, Ignored> {
|
|
||||||
|
|
||||||
using class_t = typename pmf<Pmf>::class_type;
|
|
||||||
|
|
||||||
template<typename U, typename... Rgs,
|
|
||||||
typename Obj = generalize_if_dissimilar<class_t, U&&>>
|
|
||||||
auto operator()(U&& u, Rgs&&... rgs) const ->
|
|
||||||
success<decltype((std::declval<Obj>().*std::declval<Pmf>())(static_cast<Rgs&&>(rgs)...))>;
|
|
||||||
|
|
||||||
auto operator()(...) const -> substitution_failure;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Pmd, bool Ignored>
|
|
||||||
struct test_invoke<pmd<Pmd>, Ignored> {
|
|
||||||
|
|
||||||
using class_t = typename pmd<Pmd>::class_type;
|
|
||||||
|
|
||||||
template<typename U,
|
|
||||||
typename Obj = generalize_if_dissimilar<class_t, U&&>>
|
|
||||||
auto operator()(U&& u) const ->
|
|
||||||
success<decltype(std::declval<Obj>().*std::declval<Pmd>())>;
|
|
||||||
|
|
||||||
auto operator()(...) const -> substitution_failure;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T, typename... Args>
|
|
||||||
struct is_invocable_impl {
|
|
||||||
using traits = detail::traits<T>;
|
|
||||||
using test = detail::test_invoke<traits>;
|
|
||||||
using result = decltype(test{}(::std::declval<Args>()...));
|
|
||||||
using type = std::integral_constant<bool, result::value>;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename... Args>
|
|
||||||
struct is_invocable_impl<void, Args...> {
|
|
||||||
using type = std::false_type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename IsInvocable, typename Ret, typename T, typename... Args>
|
|
||||||
struct is_invocable_r_impl {
|
|
||||||
using traits = detail::traits<T>;
|
|
||||||
using test = detail::test_invoke<traits>;
|
|
||||||
using result = decltype(test{}(::std::declval<Args>()...));
|
|
||||||
using type = typename std::is_convertible<typename result::_::type, Ret>::type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Ret, typename T, typename... Args>
|
|
||||||
struct is_invocable_r_impl<std::false_type, Ret, T, Args...> {
|
|
||||||
using type = std::false_type;
|
|
||||||
};
|
|
||||||
|
|
||||||
}}} // namespace boost::callable_traits::detail
|
|
||||||
|
|
||||||
#endif // #ifndef BOOST_CLBL_TRTS_IS_INVOCABLE_IMPL_HPP
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
#ifndef BOOST_CLBL_TRTS_PARAMETER_INDEX_HELPER_HPP
|
|
||||||
#define BOOST_CLBL_TRTS_PARAMETER_INDEX_HELPER_HPP
|
|
||||||
|
|
||||||
#include <boost/callable_traits/detail/config.hpp>
|
|
||||||
|
|
||||||
namespace boost { namespace callable_traits { namespace detail {
|
|
||||||
|
|
||||||
template<std::size_t I, typename T, bool IgnoreThisPointer = false,
|
|
||||||
bool AllowPlus1 = false, std::size_t Count = 0>
|
|
||||||
struct parameter_index_helper {
|
|
||||||
|
|
||||||
using error_t = error_type<T>;
|
|
||||||
|
|
||||||
using args_tuple = typename std::conditional<IgnoreThisPointer,
|
|
||||||
typename detail::traits<T>::non_invoke_arg_types,
|
|
||||||
typename detail::traits<T>::arg_types>::type;
|
|
||||||
|
|
||||||
static constexpr bool has_parameter_list =
|
|
||||||
!std::is_same<args_tuple, invalid_type>::value
|
|
||||||
&& !std::is_same<args_tuple, reference_error>::value;
|
|
||||||
|
|
||||||
using temp_tuple = typename std::conditional<has_parameter_list,
|
|
||||||
args_tuple, std::tuple<error_t>>::type;
|
|
||||||
|
|
||||||
static constexpr std::size_t parameter_list_size =
|
|
||||||
std::tuple_size<temp_tuple>::value;
|
|
||||||
|
|
||||||
static constexpr bool is_out_of_range = has_parameter_list &&
|
|
||||||
I >= parameter_list_size + static_cast<std::size_t>(AllowPlus1);
|
|
||||||
|
|
||||||
static constexpr bool is_count_out_of_range = has_parameter_list &&
|
|
||||||
I + Count > parameter_list_size + static_cast<std::size_t>(AllowPlus1);
|
|
||||||
|
|
||||||
static constexpr std::size_t index =
|
|
||||||
has_parameter_list && !is_out_of_range ? I : 0;
|
|
||||||
|
|
||||||
static constexpr std::size_t count =
|
|
||||||
has_parameter_list && !is_count_out_of_range ? Count : 0;
|
|
||||||
|
|
||||||
using permissive_tuple = typename std::conditional<
|
|
||||||
has_parameter_list && !is_out_of_range,
|
|
||||||
args_tuple, std::tuple<error_t>>::type;
|
|
||||||
|
|
||||||
using permissive_function = typename std::conditional<
|
|
||||||
has_parameter_list && !is_out_of_range,
|
|
||||||
T, error_t(error_t)>::type;
|
|
||||||
};
|
|
||||||
|
|
||||||
}}} // namespace boost::callable_traits::detail
|
|
||||||
|
|
||||||
#endif // #ifndef BOOST_CLBL_TRTS_PARAMETER_INDEX_HELPER_HPP
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
/*
|
|
||||||
|
|
||||||
@Copyright Barrett Adair 2015-2017
|
|
||||||
Distributed under the Boost Software License, Version 1.0.
|
|
||||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef BOOST_CLBL_TRTS_DETAIL_PMD_HPP
|
|
||||||
#define BOOST_CLBL_TRTS_DETAIL_PMD_HPP
|
|
||||||
|
|
||||||
#include <boost/callable_traits/detail/forward_declarations.hpp>
|
|
||||||
#include <boost/callable_traits/detail/function.hpp>
|
|
||||||
#include <boost/callable_traits/detail/traits.hpp>
|
|
||||||
#include <boost/callable_traits/detail/default_callable_traits.hpp>
|
|
||||||
#include <boost/callable_traits/detail/utility.hpp>
|
|
||||||
|
|
||||||
namespace boost { namespace callable_traits { namespace detail {
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct pmd : default_callable_traits<T> {};
|
|
||||||
|
|
||||||
template<typename D, typename T>
|
|
||||||
struct pmd<D T::*> : default_callable_traits<> {
|
|
||||||
|
|
||||||
static constexpr bool value = true;
|
|
||||||
|
|
||||||
using traits = pmd;
|
|
||||||
using class_type = T;
|
|
||||||
using invoke_type = T const &;
|
|
||||||
using type = D T::*;
|
|
||||||
using function_type = typename std::add_lvalue_reference<D>::type(invoke_type);
|
|
||||||
using qualified_function_type = D(invoke_type);
|
|
||||||
using arg_types = std::tuple<invoke_type>;
|
|
||||||
using non_invoke_arg_types = std::tuple<>;
|
|
||||||
|
|
||||||
using return_type = typename std::add_lvalue_reference<D>::type;
|
|
||||||
|
|
||||||
template<typename C>
|
|
||||||
using apply_member_pointer = D C::*;
|
|
||||||
|
|
||||||
template<typename R>
|
|
||||||
using apply_return = R T::*;
|
|
||||||
|
|
||||||
template<template<class...> class Container>
|
|
||||||
using expand_args = Container<invoke_type>;
|
|
||||||
|
|
||||||
using is_member_pointer = std::true_type;
|
|
||||||
};
|
|
||||||
|
|
||||||
}}} // namespace boost::callable_traits::detail
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,97 +0,0 @@
|
|||||||
/*
|
|
||||||
|
|
||||||
@Copyright Barrett Adair 2015-2017
|
|
||||||
Distributed under the Boost Software License, Version 1.0.
|
|
||||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef BOOST_CLBL_TRTS_DETAIL_PMF_HPP
|
|
||||||
#define BOOST_CLBL_TRTS_DETAIL_PMF_HPP
|
|
||||||
|
|
||||||
#include <boost/callable_traits/detail/forward_declarations.hpp>
|
|
||||||
#include <boost/callable_traits/detail/set_function_qualifiers.hpp>
|
|
||||||
#include <boost/callable_traits/detail/qualifier_flags.hpp>
|
|
||||||
#include <boost/callable_traits/detail/default_callable_traits.hpp>
|
|
||||||
#include <boost/callable_traits/detail/utility.hpp>
|
|
||||||
|
|
||||||
namespace boost { namespace callable_traits { namespace detail {
|
|
||||||
|
|
||||||
template<qualifier_flags Applied, bool IsTransactionSafe, bool IsNoExcept,
|
|
||||||
typename CallingConvention, typename T, typename Return,
|
|
||||||
typename... Args>
|
|
||||||
struct set_member_function_qualifiers_t;
|
|
||||||
|
|
||||||
template<qualifier_flags Applied, bool IsTransactionSafe, bool IsNoexcept,
|
|
||||||
typename CallingConvention, typename T, typename Return,
|
|
||||||
typename... Args>
|
|
||||||
struct set_varargs_member_function_qualifiers_t;
|
|
||||||
|
|
||||||
template<qualifier_flags Flags, bool IsTransactionSafe, bool IsNoexcept,
|
|
||||||
typename... Ts>
|
|
||||||
using set_member_function_qualifiers =
|
|
||||||
typename set_member_function_qualifiers_t<Flags, IsTransactionSafe,
|
|
||||||
IsNoexcept, Ts...>::type;
|
|
||||||
|
|
||||||
template<qualifier_flags Flags, bool IsTransactionSafe, bool IsNoexcept,
|
|
||||||
typename... Ts>
|
|
||||||
using set_varargs_member_function_qualifiers =
|
|
||||||
typename set_varargs_member_function_qualifiers_t<Flags,
|
|
||||||
IsTransactionSafe, IsNoexcept, Ts...>::type;
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct pmf : default_callable_traits<T> {};
|
|
||||||
|
|
||||||
#define BOOST_CLBL_TRTS_CC_TAG dummy
|
|
||||||
#define BOOST_CLBL_TRTS_VARARGS_CC BOOST_CLBL_TRTS_DEFAULT_VARARGS_CC
|
|
||||||
#define BOOST_CLBL_TRTS_CC
|
|
||||||
#include <boost/callable_traits/detail/unguarded/pmf.hpp>
|
|
||||||
#undef BOOST_CLBL_TRTS_CC
|
|
||||||
#undef BOOST_CLBL_TRTS_CC_TAG
|
|
||||||
#undef BOOST_CLBL_TRTS_VARARGS_CC
|
|
||||||
|
|
||||||
#define BOOST_CLBL_TRTS_CC_TAG dummy
|
|
||||||
#define BOOST_CLBL_TRTS_VARARGS_CC BOOST_CLBL_TRTS_DEFAULT_VARARGS_CC
|
|
||||||
#define BOOST_CLBL_TRTS_CC
|
|
||||||
#include <boost/callable_traits/detail/unguarded/pmf_varargs.hpp>
|
|
||||||
#undef BOOST_CLBL_TRTS_CC
|
|
||||||
#undef BOOST_CLBL_TRTS_CC_TAG
|
|
||||||
#undef BOOST_CLBL_TRTS_VARARGS_CC
|
|
||||||
|
|
||||||
#ifdef BOOST_CLBL_TRTS_ENABLE_CDECL
|
|
||||||
#define BOOST_CLBL_TRTS_CC_TAG cdecl_tag
|
|
||||||
#define BOOST_CLBL_TRTS_VARARGS_CC __cdecl
|
|
||||||
#define BOOST_CLBL_TRTS_CC __cdecl
|
|
||||||
#include <boost/callable_traits/detail/unguarded/pmf.hpp>
|
|
||||||
#undef BOOST_CLBL_TRTS_CC
|
|
||||||
#undef BOOST_CLBL_TRTS_CC_TAG
|
|
||||||
#undef BOOST_CLBL_TRTS_VARARGS_CC
|
|
||||||
#endif // #ifdef BOOST_CLBL_TRTS_ENABLE_CDECL
|
|
||||||
|
|
||||||
// Defining this macro enables undocumented features, likely broken.
|
|
||||||
// Too much work to maintain, but knock yourself out
|
|
||||||
#ifdef BOOST_CLBL_TRTS_ENABLE_STDCALL
|
|
||||||
#define BOOST_CLBL_TRTS_CC_TAG stdcall_tag
|
|
||||||
#define BOOST_CLBL_TRTS_VARARGS_CC BOOST_CLBL_TRTS_DEFAULT_VARARGS_CC
|
|
||||||
#define BOOST_CLBL_TRTS_CC __stdcall
|
|
||||||
#include <boost/callable_traits/detail/unguarded/pmf.hpp>
|
|
||||||
#undef BOOST_CLBL_TRTS_CC
|
|
||||||
#undef BOOST_CLBL_TRTS_CC_TAG
|
|
||||||
#undef BOOST_CLBL_TRTS_VARARGS_CC
|
|
||||||
#endif // #ifdef BOOST_CLBL_TRTS_ENABLE_STDCALL
|
|
||||||
|
|
||||||
// Defining this macro enables undocumented features, likely broken.
|
|
||||||
// Too much work to officially maintain, but knock yourself out
|
|
||||||
#ifdef BOOST_CLBL_TRTS_ENABLE_FASTCALL
|
|
||||||
#define BOOST_CLBL_TRTS_CC_TAG fastcall_tag
|
|
||||||
#define BOOST_CLBL_TRTS_VARARGS_CC BOOST_CLBL_TRTS_DEFAULT_VARARGS_CC
|
|
||||||
#define BOOST_CLBL_TRTS_CC __fastcall
|
|
||||||
#include <boost/callable_traits/detail/unguarded/pmf.hpp>
|
|
||||||
#undef BOOST_CLBL_TRTS_CC
|
|
||||||
#undef BOOST_CLBL_TRTS_CC_TAG
|
|
||||||
#undef BOOST_CLBL_TRTS_VARARGS_CC
|
|
||||||
#endif // #ifdef BOOST_CLBL_TRTS_ENABLE_FASTCALL
|
|
||||||
|
|
||||||
}}} // namespace boost::callable_traits::detail
|
|
||||||
|
|
||||||
#endif // #ifndef BOOST_CLBL_TRTS_DETAIL_PMF_HPP
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright Barrett Adair 2015-2017
|
|
||||||
|
|
||||||
Distributed under the Boost Software License, Version 1.0.
|
|
||||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef BOOST_CLBL_TRTS_DETAIL_POLYFILLS_DISJUNCTION_HPP
|
|
||||||
#define BOOST_CLBL_TRTS_DETAIL_POLYFILLS_DISJUNCTION_HPP
|
|
||||||
|
|
||||||
#undef BOOST_CLBL_TRTS_DISJUNCTION
|
|
||||||
#define BOOST_CLBL_TRTS_DISJUNCTION(...) \
|
|
||||||
::boost::callable_traits::detail::disjunction<__VA_ARGS__>
|
|
||||||
|
|
||||||
namespace boost { namespace callable_traits { namespace detail {
|
|
||||||
|
|
||||||
//polyfill for C++17 std::disjunction
|
|
||||||
template<typename...>
|
|
||||||
struct disjunction : std::false_type {};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct disjunction<T> : T {};
|
|
||||||
|
|
||||||
template<typename T, typename... Ts>
|
|
||||||
struct disjunction<T, Ts...>
|
|
||||||
: std::conditional<T::value != false, T, disjunction<Ts...>>::type {};
|
|
||||||
|
|
||||||
}}} // namespace boost::callable_traits::detail
|
|
||||||
|
|
||||||
#endif // #ifndef BOOST_CLBL_TRTS_DETAIL_POLYFILLS_DISJUNCTION_HPP
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright Barrett Adair 2016-2017
|
|
||||||
|
|
||||||
Distributed under the Boost Software License, Version 1.0.
|
|
||||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef BOOST_CLBL_TRTS_DETAIL_POLYFILLS_MAKE_INDEX_SEQUENCE_HPP
|
|
||||||
#define BOOST_CLBL_TRTS_DETAIL_POLYFILLS_MAKE_INDEX_SEQUENCE_HPP
|
|
||||||
|
|
||||||
#undef BOOST_CLBL_TRTS_IX_SEQ
|
|
||||||
#define BOOST_CLBL_TRTS_IX_SEQ(...) \
|
|
||||||
::boost::callable_traits::detail::index_sequence<__VA_ARGS__>
|
|
||||||
|
|
||||||
#undef BOOST_CLBL_TRTS_MAKE_IX_SEQ
|
|
||||||
#define BOOST_CLBL_TRTS_MAKE_IX_SEQ(...) \
|
|
||||||
::boost::callable_traits::detail::make_index_sequence<__VA_ARGS__>
|
|
||||||
|
|
||||||
namespace boost { namespace callable_traits { namespace detail {
|
|
||||||
|
|
||||||
template<std::size_t...>
|
|
||||||
struct index_sequence { using type = index_sequence; };
|
|
||||||
|
|
||||||
template<typename, typename>
|
|
||||||
struct concat;
|
|
||||||
|
|
||||||
template<std::size_t... I1, std::size_t... I2>
|
|
||||||
struct concat<index_sequence<I1...>, index_sequence<I2...>>
|
|
||||||
: index_sequence<I1..., (sizeof...(I1)+I2)...> {};
|
|
||||||
|
|
||||||
template<std::size_t N>
|
|
||||||
struct make_index_sequence_t;
|
|
||||||
|
|
||||||
template<std::size_t N>
|
|
||||||
struct make_index_sequence_t : concat<
|
|
||||||
typename make_index_sequence_t<N/2>::type,
|
|
||||||
typename make_index_sequence_t<N - N/2>::type >::type {};
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct make_index_sequence_t<0> : index_sequence<> {};
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct make_index_sequence_t<1> : index_sequence<0> {};
|
|
||||||
|
|
||||||
template<std::size_t... I>
|
|
||||||
using make_index_sequence = typename make_index_sequence_t<I...>::type;
|
|
||||||
|
|
||||||
}}} // namespace boost::callable_traits::detail
|
|
||||||
|
|
||||||
#endif // #ifndef BOOST_CLBL_TRTS_DETAIL_POLYFILLS_MAKE_INDEX_SEQUENCE_HPP
|
|
||||||
@@ -1,123 +0,0 @@
|
|||||||
/*
|
|
||||||
Defines `qualifier_flags`
|
|
||||||
|
|
||||||
@Copyright Barrett Adair 2015-2017
|
|
||||||
Distributed under the Boost Software License, Version 1.0.
|
|
||||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef BOOST_CLBL_TRTS_QUALIFIER_FLAGS_HPP
|
|
||||||
#define BOOST_CLBL_TRTS_QUALIFIER_FLAGS_HPP
|
|
||||||
|
|
||||||
#include <boost/callable_traits/detail/config.hpp>
|
|
||||||
|
|
||||||
namespace boost { namespace callable_traits { namespace detail {
|
|
||||||
|
|
||||||
//bit qualifier_flags used to signify cv/ref qualifiers
|
|
||||||
using qualifier_flags = std::uint32_t;
|
|
||||||
|
|
||||||
/*
|
|
||||||
| && & V C |
|
|
||||||
--------------------------------------------
|
|
||||||
0 | 0 0 0 0 | default
|
|
||||||
1 | 0 0 0 1 | const
|
|
||||||
2 | 0 0 1 0 | volatile
|
|
||||||
3 | 0 0 1 1 | const volatile
|
|
||||||
--------------------------------------------
|
|
||||||
4 | 0 1 0 0 | &
|
|
||||||
5 | 0 1 0 1 | const &
|
|
||||||
6 | 0 1 1 0 | volatile &
|
|
||||||
7 | 0 1 1 1 | const volatile &
|
|
||||||
--------------------------------------------
|
|
||||||
8 | 1 0 0 0 | &&
|
|
||||||
9 | 1 0 0 1 | const &&
|
|
||||||
10 | 1 0 1 0 | volatile &&
|
|
||||||
11 | 1 0 1 1 | const volatile &&
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Flag representing the default qualifiers on a type
|
|
||||||
// or member function overload.
|
|
||||||
constexpr qualifier_flags default_ = 0;
|
|
||||||
|
|
||||||
// Flag representing a const qualifier on a type or
|
|
||||||
// member function overload.
|
|
||||||
constexpr qualifier_flags const_ = 1;
|
|
||||||
|
|
||||||
// Flag representing a volatile qualifier on a type
|
|
||||||
// or member function overload.
|
|
||||||
constexpr qualifier_flags volatile_ = 2;
|
|
||||||
|
|
||||||
#ifdef BOOST_CLBL_TRTS_DISABLE_REFERENCE_QUALIFIERS
|
|
||||||
|
|
||||||
constexpr qualifier_flags lref_ = default_;
|
|
||||||
constexpr qualifier_flags rref_ = default_;
|
|
||||||
#else
|
|
||||||
|
|
||||||
// Flag representing an lvalue reference type, or
|
|
||||||
// an lvalue-reference-qualified member function
|
|
||||||
// overload.
|
|
||||||
constexpr qualifier_flags lref_ = 4;
|
|
||||||
|
|
||||||
// Flag representing an lvalue reference type, or
|
|
||||||
// an rvalue-reference-qualified member function
|
|
||||||
// overload.
|
|
||||||
constexpr qualifier_flags rref_ = 8;
|
|
||||||
|
|
||||||
#endif //#ifdef BOOST_CLBL_TRTS_DISABLE_REFERENCE_QUALIFIERS
|
|
||||||
|
|
||||||
constexpr qualifier_flags cv_ = 3;
|
|
||||||
|
|
||||||
template<qualifier_flags Flags>
|
|
||||||
using remove_const_flag = std::integral_constant<
|
|
||||||
qualifier_flags, Flags & ~const_>;
|
|
||||||
|
|
||||||
template<qualifier_flags Flags>
|
|
||||||
using is_const = std::integral_constant<bool,
|
|
||||||
(Flags & const_) != 0>;
|
|
||||||
|
|
||||||
template<qualifier_flags Flags>
|
|
||||||
using remove_volatile_flag = std::integral_constant<
|
|
||||||
qualifier_flags, Flags & ~volatile_>;
|
|
||||||
|
|
||||||
template<typename U, typename T = typename std::remove_reference<U>::type>
|
|
||||||
using cv_of = std::integral_constant<qualifier_flags,
|
|
||||||
(std::is_const<T>::value ? const_ : default_)
|
|
||||||
| (std::is_volatile<T>::value ? volatile_ : default_)>;
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
using ref_of = std::integral_constant<qualifier_flags,
|
|
||||||
std::is_rvalue_reference<T>::value ? rref_
|
|
||||||
: (std::is_lvalue_reference<T>::value ? lref_
|
|
||||||
: default_)>;
|
|
||||||
|
|
||||||
//bit-flag implementation of C++11 reference collapsing rules
|
|
||||||
template<qualifier_flags Existing,
|
|
||||||
qualifier_flags Other,
|
|
||||||
bool AlreadyHasRef = (Existing & (lref_ | rref_)) != 0,
|
|
||||||
bool AlreadyHasLRef = (Existing & lref_) == lref_,
|
|
||||||
bool IsAddingLRef = (Other & lref_) == lref_
|
|
||||||
>
|
|
||||||
using collapse_flags = std::integral_constant<qualifier_flags,
|
|
||||||
!AlreadyHasRef ? (Existing | Other)
|
|
||||||
: (AlreadyHasLRef ? (Existing | (Other & ~rref_))
|
|
||||||
: (IsAddingLRef ? ((Existing & ~rref_) | Other )
|
|
||||||
: (Existing | Other)))>;
|
|
||||||
|
|
||||||
template<typename T> struct flag_map { static constexpr qualifier_flags value = default_; };
|
|
||||||
template<typename T> struct flag_map<T &> { static constexpr qualifier_flags value = lref_; };
|
|
||||||
template<typename T> struct flag_map<T &&> { static constexpr qualifier_flags value = rref_; };
|
|
||||||
template<typename T> struct flag_map<T const> { static constexpr qualifier_flags value = const_; };
|
|
||||||
template<typename T> struct flag_map<T const &> { static constexpr qualifier_flags value = const_ | lref_; };
|
|
||||||
template<typename T> struct flag_map<T const &&> { static constexpr qualifier_flags value = const_ | rref_; };
|
|
||||||
template<typename T> struct flag_map<T volatile> { static constexpr qualifier_flags value = volatile_; };
|
|
||||||
template<typename T> struct flag_map<T volatile &> { static constexpr qualifier_flags value = volatile_ | lref_; };
|
|
||||||
template<typename T> struct flag_map<T volatile &&> { static constexpr qualifier_flags value = volatile_ | rref_; };
|
|
||||||
template<typename T> struct flag_map<T const volatile> { static constexpr qualifier_flags value = const_ | volatile_; };
|
|
||||||
template<typename T> struct flag_map<T const volatile &> { static constexpr qualifier_flags value = const_ | volatile_ | lref_; };
|
|
||||||
template<typename T> struct flag_map<T const volatile &&> { static constexpr qualifier_flags value = const_ | volatile_ | rref_; };
|
|
||||||
|
|
||||||
}}} // namespace boost::callable_traits::detail
|
|
||||||
|
|
||||||
#endif // #ifndef BOOST_CLBL_TRTS_QUALIFIER_FLAGS_HPP
|
|
||||||
@@ -1,120 +0,0 @@
|
|||||||
/*
|
|
||||||
|
|
||||||
@Copyright Barrett Adair 2015-2017
|
|
||||||
Distributed under the Boost Software License, Version 1.0.
|
|
||||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef BOOST_CLBL_TRTS_DETAIL_SET_FUNCTION_QUALIFIERS_HPP
|
|
||||||
#define BOOST_CLBL_TRTS_DETAIL_SET_FUNCTION_QUALIFIERS_HPP
|
|
||||||
|
|
||||||
#include <boost/callable_traits/detail/qualifier_flags.hpp>
|
|
||||||
|
|
||||||
#define BOOST_CLBL_TRTS_SET_FUNCTION_QUALIFIERS(QUAL) \
|
|
||||||
template<typename Return, typename... Args> \
|
|
||||||
struct set_function_qualifiers_t < \
|
|
||||||
flag_map<int QUAL>::value, false, false, Return, Args...> { \
|
|
||||||
using type = Return(Args...) QUAL; \
|
|
||||||
}; \
|
|
||||||
\
|
|
||||||
template<typename Return, typename... Args> \
|
|
||||||
struct set_function_qualifiers_t < \
|
|
||||||
flag_map<int QUAL>::value, true, false, Return, Args...> { \
|
|
||||||
using type = Return(Args...) QUAL \
|
|
||||||
BOOST_CLBL_TRTS_TRANSACTION_SAFE_SPECIFIER; \
|
|
||||||
}; \
|
|
||||||
\
|
|
||||||
template<typename Return, typename... Args> \
|
|
||||||
struct set_function_qualifiers_t < \
|
|
||||||
flag_map<int QUAL>::value, false, true, Return, Args...> { \
|
|
||||||
using type = Return(Args...) QUAL \
|
|
||||||
BOOST_CLBL_TRTS_NOEXCEPT_SPECIFIER; \
|
|
||||||
}; \
|
|
||||||
\
|
|
||||||
template<typename Return, typename... Args> \
|
|
||||||
struct set_function_qualifiers_t < \
|
|
||||||
flag_map<int QUAL>::value, true, true, Return, Args...> { \
|
|
||||||
using type = Return(Args...) QUAL \
|
|
||||||
BOOST_CLBL_TRTS_TRANSACTION_SAFE_SPECIFIER \
|
|
||||||
BOOST_CLBL_TRTS_NOEXCEPT_SPECIFIER; \
|
|
||||||
}; \
|
|
||||||
\
|
|
||||||
template<typename Return, typename... Args> \
|
|
||||||
struct set_varargs_function_qualifiers_t < \
|
|
||||||
flag_map<int QUAL>::value, false, false, Return, Args...> { \
|
|
||||||
using type = Return(Args..., ...) QUAL; \
|
|
||||||
}; \
|
|
||||||
\
|
|
||||||
template<typename Return, typename... Args> \
|
|
||||||
struct set_varargs_function_qualifiers_t < \
|
|
||||||
flag_map<int QUAL>::value, true, false, Return, Args...> { \
|
|
||||||
using type = Return(Args..., ...) QUAL \
|
|
||||||
BOOST_CLBL_TRTS_TRANSACTION_SAFE_SPECIFIER; \
|
|
||||||
}; \
|
|
||||||
\
|
|
||||||
template<typename Return, typename... Args> \
|
|
||||||
struct set_varargs_function_qualifiers_t < \
|
|
||||||
flag_map<int QUAL>::value, false, true, Return, Args...> { \
|
|
||||||
using type = Return(Args..., ...) QUAL \
|
|
||||||
BOOST_CLBL_TRTS_NOEXCEPT_SPECIFIER; \
|
|
||||||
}; \
|
|
||||||
\
|
|
||||||
template<typename Return, typename... Args> \
|
|
||||||
struct set_varargs_function_qualifiers_t < \
|
|
||||||
flag_map<int QUAL>::value, true, true, Return, Args...> { \
|
|
||||||
using type = Return(Args..., ...) QUAL \
|
|
||||||
BOOST_CLBL_TRTS_TRANSACTION_SAFE_SPECIFIER \
|
|
||||||
BOOST_CLBL_TRTS_NOEXCEPT_SPECIFIER; \
|
|
||||||
} \
|
|
||||||
/**/
|
|
||||||
|
|
||||||
namespace boost { namespace callable_traits { namespace detail {
|
|
||||||
|
|
||||||
template<qualifier_flags Applied, bool IsTransactionSafe,
|
|
||||||
bool IsNoexcept, typename Return, typename... Args>
|
|
||||||
struct set_function_qualifiers_t {
|
|
||||||
using type = Return(Args...);
|
|
||||||
};
|
|
||||||
|
|
||||||
template<qualifier_flags Applied, bool IsTransactionSafe,
|
|
||||||
bool IsNoexcept, typename Return, typename... Args>
|
|
||||||
struct set_varargs_function_qualifiers_t {
|
|
||||||
using type = Return(Args..., ...);
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifndef BOOST_CLBL_TRTS_DISABLE_ABOMINABLE_FUNCTIONS
|
|
||||||
|
|
||||||
BOOST_CLBL_TRTS_SET_FUNCTION_QUALIFIERS(const);
|
|
||||||
BOOST_CLBL_TRTS_SET_FUNCTION_QUALIFIERS(volatile);
|
|
||||||
BOOST_CLBL_TRTS_SET_FUNCTION_QUALIFIERS(const volatile);
|
|
||||||
|
|
||||||
#ifndef BOOST_CLBL_TRTS_DISABLE_REFERENCE_QUALIFIERS
|
|
||||||
|
|
||||||
BOOST_CLBL_TRTS_SET_FUNCTION_QUALIFIERS(&);
|
|
||||||
BOOST_CLBL_TRTS_SET_FUNCTION_QUALIFIERS(&&);
|
|
||||||
BOOST_CLBL_TRTS_SET_FUNCTION_QUALIFIERS(const &);
|
|
||||||
BOOST_CLBL_TRTS_SET_FUNCTION_QUALIFIERS(const &&);
|
|
||||||
BOOST_CLBL_TRTS_SET_FUNCTION_QUALIFIERS(volatile &);
|
|
||||||
BOOST_CLBL_TRTS_SET_FUNCTION_QUALIFIERS(volatile &&);
|
|
||||||
BOOST_CLBL_TRTS_SET_FUNCTION_QUALIFIERS(const volatile &);
|
|
||||||
BOOST_CLBL_TRTS_SET_FUNCTION_QUALIFIERS(const volatile &&);
|
|
||||||
|
|
||||||
#endif // #ifndef BOOST_CLBL_TRTS_DISABLE_REFERENCE_QUALIFIERS
|
|
||||||
#endif // #ifndef BOOST_CLBL_TRTS_DISABLE_ABOMINABLE_FUNCTIONS
|
|
||||||
|
|
||||||
template<qualifier_flags Flags, bool IsTransactionSafe, bool IsNoexcept,
|
|
||||||
typename... Ts>
|
|
||||||
using set_function_qualifiers =
|
|
||||||
typename set_function_qualifiers_t<Flags, IsTransactionSafe, IsNoexcept,
|
|
||||||
Ts...>::type;
|
|
||||||
|
|
||||||
template<qualifier_flags Flags, bool IsTransactionSafe, bool IsNoexcept,
|
|
||||||
typename... Ts>
|
|
||||||
using set_varargs_function_qualifiers =
|
|
||||||
typename set_varargs_function_qualifiers_t<Flags, IsTransactionSafe,
|
|
||||||
IsNoexcept, Ts...>::type;
|
|
||||||
|
|
||||||
}}} // namespace boost::callable_traits::detail
|
|
||||||
|
|
||||||
#endif //BOOST_CLBL_TRTS_DETAIL_SET_FUNCTION_QUALIFIERS_HPP
|
|
||||||
@@ -1,89 +0,0 @@
|
|||||||
/*
|
|
||||||
@Copyright Barrett Adair 2016-2017
|
|
||||||
|
|
||||||
Distributed under the Boost Software License, Version 1.0.
|
|
||||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef BOOST_CLBL_TRTS_SFINAE_ERRORS_HPP
|
|
||||||
#define BOOST_CLBL_TRTS_SFINAE_ERRORS_HPP
|
|
||||||
|
|
||||||
#include <boost/callable_traits/detail/config.hpp>
|
|
||||||
|
|
||||||
namespace boost { namespace callable_traits { namespace detail {
|
|
||||||
|
|
||||||
struct sfinae_error{};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct success {
|
|
||||||
static constexpr bool value = true;
|
|
||||||
struct _ { using type = T; };
|
|
||||||
};
|
|
||||||
|
|
||||||
template<bool B, typename T>
|
|
||||||
struct fail_if : T {
|
|
||||||
static_assert(std::is_base_of<sfinae_error, T>::value,
|
|
||||||
"incorrect usage of fail_if");
|
|
||||||
|
|
||||||
static constexpr bool value = B;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T, typename... FailIfs>
|
|
||||||
using sfinae_try = typename BOOST_CLBL_TRTS_DISJUNCTION(
|
|
||||||
FailIfs..., success<T>)::_::type;
|
|
||||||
|
|
||||||
template<typename FailMsg, typename ForceTwoPhaseLookup>
|
|
||||||
struct fail {
|
|
||||||
using type = typename std::conditional<std::is_same<ForceTwoPhaseLookup, std::false_type>::value,
|
|
||||||
FailMsg, FailMsg>::type::_::type;
|
|
||||||
};
|
|
||||||
|
|
||||||
}}} // namespace boost::callable_traits::detail
|
|
||||||
|
|
||||||
#define BOOST_CLBL_TRTS_PP_CAT_(x, y) x ## y
|
|
||||||
#define BOOST_CLBL_TRTS_PP_CAT(x, y) BOOST_CLBL_TRTS_PP_CAT_(x, y)
|
|
||||||
|
|
||||||
#define BOOST_CLBL_TRTS_DEFINE_SFINAE_ERROR_ORIGIN(origin) \
|
|
||||||
namespace error { \
|
|
||||||
template<typename ErrorMessage> \
|
|
||||||
struct origin : \
|
|
||||||
::boost::callable_traits::detail::sfinae_error \
|
|
||||||
{ struct _ {}; }; \
|
|
||||||
} \
|
|
||||||
/**/
|
|
||||||
|
|
||||||
#define BOOST_CLBL_TRTS_SFINAE_MSG(origin, name) \
|
|
||||||
struct BOOST_CLBL_TRTS_PP_CAT(name, _ ){}; \
|
|
||||||
struct name : error::origin< \
|
|
||||||
BOOST_CLBL_TRTS_PP_CAT(name, _ )>{}; \
|
|
||||||
/**/
|
|
||||||
|
|
||||||
namespace boost { namespace callable_traits {
|
|
||||||
|
|
||||||
BOOST_CLBL_TRTS_DEFINE_SFINAE_ERROR_ORIGIN(parameters)
|
|
||||||
BOOST_CLBL_TRTS_SFINAE_MSG(parameters, index_out_of_range_for_parameter_list)
|
|
||||||
BOOST_CLBL_TRTS_SFINAE_MSG(parameters, cannot_determine_parameters_for_this_type)
|
|
||||||
|
|
||||||
BOOST_CLBL_TRTS_DEFINE_SFINAE_ERROR_ORIGIN(varargs)
|
|
||||||
BOOST_CLBL_TRTS_SFINAE_MSG(varargs, varargs_are_illegal_for_this_type)
|
|
||||||
|
|
||||||
BOOST_CLBL_TRTS_DEFINE_SFINAE_ERROR_ORIGIN(member_qualifiers)
|
|
||||||
BOOST_CLBL_TRTS_SFINAE_MSG(member_qualifiers, member_qualifiers_are_illegal_for_this_type)
|
|
||||||
BOOST_CLBL_TRTS_SFINAE_MSG(member_qualifiers, this_compiler_doesnt_support_abominable_function_types)
|
|
||||||
|
|
||||||
BOOST_CLBL_TRTS_DEFINE_SFINAE_ERROR_ORIGIN(transaction_safe_)
|
|
||||||
BOOST_CLBL_TRTS_SFINAE_MSG(transaction_safe_, transaction_safe_is_not_supported_by_this_configuration)
|
|
||||||
|
|
||||||
BOOST_CLBL_TRTS_DEFINE_SFINAE_ERROR_ORIGIN(expand_args)
|
|
||||||
BOOST_CLBL_TRTS_SFINAE_MSG(expand_args, cannot_expand_the_parameter_list_of_first_template_argument)
|
|
||||||
|
|
||||||
BOOST_CLBL_TRTS_DEFINE_SFINAE_ERROR_ORIGIN(member_pointer_required)
|
|
||||||
BOOST_CLBL_TRTS_SFINAE_MSG(member_pointer_required, type_is_not_a_member_pointer)
|
|
||||||
|
|
||||||
BOOST_CLBL_TRTS_DEFINE_SFINAE_ERROR_ORIGIN(reference_error)
|
|
||||||
BOOST_CLBL_TRTS_SFINAE_MSG(reference_error, reference_type_not_supported_by_this_metafunction)
|
|
||||||
|
|
||||||
}} // namespace boost::callable_traits
|
|
||||||
|
|
||||||
#endif // #ifndef BOOST_CLBL_TRTS_SFINAE_ERRORS_HPP
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
/*
|
|
||||||
|
|
||||||
@Copyright Barrett Adair 2015-2017
|
|
||||||
Distributed under the Boost Software License, Version 1.0.
|
|
||||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef BOOST_CLBL_TRTS_DETAIL_TRAITS_HPP
|
|
||||||
#define BOOST_CLBL_TRTS_DETAIL_TRAITS_HPP
|
|
||||||
|
|
||||||
#include <boost/callable_traits/detail/forward_declarations.hpp>
|
|
||||||
#include <boost/callable_traits/detail/utility.hpp>
|
|
||||||
|
|
||||||
namespace boost { namespace callable_traits { namespace detail {
|
|
||||||
|
|
||||||
// Here is where the magic happens
|
|
||||||
template<typename T>
|
|
||||||
using traits = typename BOOST_CLBL_TRTS_DISJUNCTION(
|
|
||||||
function_object<unwrap_reference<T>>,
|
|
||||||
function<T>,
|
|
||||||
pmf<T>,
|
|
||||||
pmd<T>,
|
|
||||||
default_callable_traits<T>
|
|
||||||
)::traits;
|
|
||||||
|
|
||||||
}}} // namespace boost::callable_traits::detail
|
|
||||||
|
|
||||||
#endif // #ifndef BOOST_CLBL_TRTS_DETAIL_TRAITS_HPP
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2016 Barrett Adair
|
|
||||||
|
|
||||||
Distributed under the Boost Software License, Version 1.0.
|
|
||||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
|
||||||
|
|
||||||
HEADER GUARDS INTENTIONALLY OMITTED
|
|
||||||
DO NOT INCLUDE THIS HEADER DIRECTLY
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
|
|
||||||
#define BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE std::false_type
|
|
||||||
#include <boost/callable_traits/detail/unguarded/function_2.hpp>
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
|
|
||||||
#undef BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE
|
|
||||||
|
|
||||||
#ifdef BOOST_CLBL_TRTS_ENABLE_TRANSACTION_SAFE
|
|
||||||
#define BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE std::true_type
|
|
||||||
#define BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE transaction_safe
|
|
||||||
#include <boost/callable_traits/detail/unguarded/function_2.hpp>
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
|
|
||||||
#undef BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE
|
|
||||||
#endif // #ifdef BOOST_CLBL_TRTS_ENABLE_TRANSACTION_SAFE
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2016 Barrett Adair
|
|
||||||
|
|
||||||
Distributed under the Boost Software License, Version 1.0.
|
|
||||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
|
||||||
|
|
||||||
HEADER GUARDS INTENTIONALLY OMITTED
|
|
||||||
DO NOT INCLUDE THIS HEADER DIRECTLY
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define BOOST_CLBL_TRTS_NOEXCEPT_SPEC
|
|
||||||
#define BOOST_CLBL_TRTS_IS_NOEXCEPT std::false_type
|
|
||||||
#include <boost/callable_traits/detail/unguarded/function_3.hpp>
|
|
||||||
#undef BOOST_CLBL_TRTS_NOEXCEPT_SPEC
|
|
||||||
#undef BOOST_CLBL_TRTS_IS_NOEXCEPT
|
|
||||||
|
|
||||||
#ifdef BOOST_CLBL_TRTS_ENABLE_NOEXCEPT_TYPES
|
|
||||||
#define BOOST_CLBL_TRTS_NOEXCEPT_SPEC noexcept
|
|
||||||
#define BOOST_CLBL_TRTS_IS_NOEXCEPT std::true_type
|
|
||||||
#include <boost/callable_traits/detail/unguarded/function_3.hpp>
|
|
||||||
#undef BOOST_CLBL_TRTS_NOEXCEPT_SPEC
|
|
||||||
#undef BOOST_CLBL_TRTS_IS_NOEXCEPT
|
|
||||||
#endif // #ifdef BOOST_CLBL_TRTS_ENABLE_NOEXCEPT_TYPES
|
|
||||||
@@ -1,260 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2016 Barrett Adair
|
|
||||||
|
|
||||||
Distributed under the Boost Software License, Version 1.0.
|
|
||||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
|
||||||
|
|
||||||
HEADER GUARDS INTENTIONALLY OMITTED
|
|
||||||
DO NOT INCLUDE THIS HEADER DIRECTLY
|
|
||||||
|
|
||||||
macros used:
|
|
||||||
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS - the function-level qualifiers for the
|
|
||||||
current inclusion (combinations of `const` `volatile` `&` `&&`, or nothing)
|
|
||||||
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE - the transaction_safe specifier for
|
|
||||||
the current include (`transaction_safe` or nothing)
|
|
||||||
|
|
||||||
BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE - `std::true_type` or `std::false_type`,
|
|
||||||
tied on whether BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE is `transaction_safe`
|
|
||||||
|
|
||||||
BOOST_CLBL_TRTS_TRANSACTION_SAFE_SPECIFIER - `transaction_safe` when
|
|
||||||
BOOST_CLBL_TRTS_ENABLE_TRANSACTION_SAFE is enabled, otherwise nothing
|
|
||||||
|
|
||||||
BOOST_CLBL_TRTS_NOEXCEPT_SPEC - the noexcept specifier for
|
|
||||||
the current include (`noexcept` or nothing)
|
|
||||||
|
|
||||||
BOOST_CLBL_TRTS_IS_NOEXCEPT - `std::true_type` or `std::false_type`,
|
|
||||||
tied on whether BOOST_CLBL_TRTS_NOEXCEPT_SPEC is `noexcept`
|
|
||||||
|
|
||||||
BOOST_CLBL_TRTS_NOEXCEPT_SPECIFIER - `noexcept` if
|
|
||||||
BOOST_CLBL_TRTS_ENABLE_NOEXCEPT_TYPES is defined, otherwise nothing
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
template<typename Return, typename... Args>
|
|
||||||
struct function<Return(Args...)
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
|
|
||||||
BOOST_CLBL_TRTS_NOEXCEPT_SPEC>
|
|
||||||
: default_callable_traits<dummy BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS> {
|
|
||||||
|
|
||||||
static constexpr bool value = true;
|
|
||||||
|
|
||||||
using traits = function;
|
|
||||||
|
|
||||||
using return_type = Return;
|
|
||||||
|
|
||||||
using arg_types = std::tuple<Args...>;
|
|
||||||
using non_invoke_arg_types = arg_types;
|
|
||||||
|
|
||||||
using type = Return(Args...)
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
|
|
||||||
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
|
|
||||||
|
|
||||||
using function_type = Return(Args...);
|
|
||||||
|
|
||||||
using qualified_function_type = Return(Args...)
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
|
|
||||||
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
|
|
||||||
|
|
||||||
using remove_varargs = type;
|
|
||||||
|
|
||||||
using add_varargs = Return (Args..., ...)
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
|
|
||||||
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
|
|
||||||
|
|
||||||
using is_noexcept = BOOST_CLBL_TRTS_IS_NOEXCEPT;
|
|
||||||
|
|
||||||
using remove_noexcept = Return(Args...)
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE;
|
|
||||||
|
|
||||||
using add_noexcept = Return(Args...)
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
|
|
||||||
BOOST_CLBL_TRTS_NOEXCEPT_SPECIFIER;
|
|
||||||
|
|
||||||
using is_transaction_safe = BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE;
|
|
||||||
|
|
||||||
using remove_transaction_safe = Return(Args...)
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
|
|
||||||
|
|
||||||
using add_transaction_safe = Return(Args...)
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
BOOST_CLBL_TRTS_TRANSACTION_SAFE_SPECIFIER
|
|
||||||
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
|
|
||||||
|
|
||||||
using qualifiers = default_callable_traits<dummy BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS>;
|
|
||||||
|
|
||||||
template<qualifier_flags Flags>
|
|
||||||
using set_qualifiers = set_function_qualifiers<Flags, is_transaction_safe::value,
|
|
||||||
is_noexcept::value, Return, Args...>;
|
|
||||||
|
|
||||||
#ifdef BOOST_CLBL_TRTS_DISABLE_ABOMINABLE_FUNCTIONS
|
|
||||||
|
|
||||||
using add_member_lvalue_reference = abominable_functions_not_supported_on_this_compiler;
|
|
||||||
using add_member_rvalue_reference = abominable_functions_not_supported_on_this_compiler;
|
|
||||||
using add_member_const = abominable_functions_not_supported_on_this_compiler;
|
|
||||||
using add_member_volatile = abominable_functions_not_supported_on_this_compiler;
|
|
||||||
using add_member_cv = abominable_functions_not_supported_on_this_compiler;
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
using add_member_lvalue_reference = set_qualifiers<
|
|
||||||
collapse_flags<qualifiers::q_flags, lref_>::value>;
|
|
||||||
|
|
||||||
using add_member_rvalue_reference = set_qualifiers<
|
|
||||||
collapse_flags<qualifiers::q_flags, rref_>::value>;
|
|
||||||
|
|
||||||
using add_member_const = set_qualifiers<qualifiers::q_flags | const_>;
|
|
||||||
|
|
||||||
using add_member_volatile = set_qualifiers<qualifiers::q_flags | volatile_>;
|
|
||||||
|
|
||||||
using add_member_cv = set_qualifiers<qualifiers::q_flags | cv_>;
|
|
||||||
|
|
||||||
#endif // #ifdef BOOST_CLBL_TRTS_DISABLE_ABOMINABLE_FUNCTIONS
|
|
||||||
|
|
||||||
using remove_member_reference = set_qualifiers<qualifiers::cv_flags>;
|
|
||||||
|
|
||||||
using remove_member_const = set_qualifiers<
|
|
||||||
qualifiers::ref_flags | remove_const_flag<qualifiers::cv_flags>::value>;
|
|
||||||
|
|
||||||
using remove_member_volatile = set_qualifiers<
|
|
||||||
qualifiers::ref_flags | remove_volatile_flag<qualifiers::cv_flags>::value>;
|
|
||||||
|
|
||||||
using remove_member_cv = set_qualifiers<qualifiers::ref_flags>;
|
|
||||||
|
|
||||||
template<typename U>
|
|
||||||
using apply_member_pointer = add_member_pointer<type, U>;
|
|
||||||
|
|
||||||
template<typename NewReturn>
|
|
||||||
using apply_return = NewReturn(Args...)
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
|
|
||||||
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
|
|
||||||
|
|
||||||
template<template<class...> class Container>
|
|
||||||
using expand_args = Container<Args...>;
|
|
||||||
|
|
||||||
using is_member_pointer = std::false_type;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
template<typename Return, typename... Args>
|
|
||||||
struct function<Return (Args..., ...)
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
|
|
||||||
BOOST_CLBL_TRTS_NOEXCEPT_SPEC>
|
|
||||||
: default_callable_traits<dummy BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS> {
|
|
||||||
|
|
||||||
static constexpr bool value = true;
|
|
||||||
|
|
||||||
using has_varargs = std::true_type;
|
|
||||||
using traits = function;
|
|
||||||
using return_type = Return;
|
|
||||||
using arg_types = std::tuple<Args...>;
|
|
||||||
|
|
||||||
using type = Return (Args..., ...)
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
|
|
||||||
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
|
|
||||||
|
|
||||||
using function_type = Return(Args..., ...);
|
|
||||||
|
|
||||||
using qualified_function_type = Return(Args..., ...)
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
|
|
||||||
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
|
|
||||||
|
|
||||||
using remove_varargs = Return (Args...)
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
|
|
||||||
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
|
|
||||||
|
|
||||||
using add_varargs = type;
|
|
||||||
|
|
||||||
using is_noexcept = BOOST_CLBL_TRTS_IS_NOEXCEPT;
|
|
||||||
|
|
||||||
using remove_noexcept = Return(Args..., ...)
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE;
|
|
||||||
|
|
||||||
using add_noexcept = Return(Args..., ...)
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
|
|
||||||
BOOST_CLBL_TRTS_NOEXCEPT_SPECIFIER;
|
|
||||||
|
|
||||||
using is_transaction_safe = BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE;
|
|
||||||
|
|
||||||
using remove_transaction_safe = Return(Args..., ...)
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
|
|
||||||
|
|
||||||
using add_transaction_safe = Return(Args..., ...)
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
BOOST_CLBL_TRTS_TRANSACTION_SAFE_SPECIFIER
|
|
||||||
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
|
|
||||||
|
|
||||||
using qualifiers = default_callable_traits<dummy BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS>;
|
|
||||||
|
|
||||||
template<qualifier_flags Flags>
|
|
||||||
using set_qualifiers = set_varargs_function_qualifiers<Flags, is_transaction_safe::value,
|
|
||||||
is_noexcept::value, Return, Args...>;
|
|
||||||
|
|
||||||
#ifdef BOOST_CLBL_TRTS_DISABLE_ABOMINABLE_FUNCTIONS
|
|
||||||
|
|
||||||
using add_member_lvalue_reference = abominable_functions_not_supported_on_this_compiler;
|
|
||||||
using add_member_rvalue_reference = abominable_functions_not_supported_on_this_compiler;
|
|
||||||
using add_member_const = abominable_functions_not_supported_on_this_compiler;
|
|
||||||
using add_member_volatile = abominable_functions_not_supported_on_this_compiler;
|
|
||||||
using add_member_cv = abominable_functions_not_supported_on_this_compiler;
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
using add_member_lvalue_reference = set_qualifiers<
|
|
||||||
collapse_flags<qualifiers::q_flags, lref_>::value>;
|
|
||||||
|
|
||||||
using add_member_rvalue_reference = set_qualifiers<
|
|
||||||
collapse_flags<qualifiers::q_flags, rref_>::value>;
|
|
||||||
|
|
||||||
using add_member_const = set_qualifiers<qualifiers::q_flags | const_>;
|
|
||||||
|
|
||||||
using add_member_volatile = set_qualifiers<qualifiers::q_flags | volatile_>;
|
|
||||||
|
|
||||||
using add_member_cv = set_qualifiers<qualifiers::q_flags | cv_>;
|
|
||||||
|
|
||||||
#endif // #ifdef BOOST_CLBL_TRTS_DISABLE_ABOMINABLE_FUNCTIONS
|
|
||||||
|
|
||||||
using remove_member_reference = set_qualifiers<qualifiers::cv_flags>;
|
|
||||||
|
|
||||||
using remove_member_const = set_qualifiers<
|
|
||||||
qualifiers::ref_flags | remove_const_flag<qualifiers::cv_flags>::value>;
|
|
||||||
|
|
||||||
using remove_member_volatile = set_qualifiers<
|
|
||||||
qualifiers::ref_flags | remove_volatile_flag<qualifiers::cv_flags>::value>;
|
|
||||||
|
|
||||||
using remove_member_cv = set_qualifiers<qualifiers::ref_flags>;
|
|
||||||
|
|
||||||
template<typename U>
|
|
||||||
using apply_member_pointer =
|
|
||||||
Return( BOOST_CLBL_TRTS_DEFAULT_VARARGS_CC U::*)(Args..., ...)
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
|
|
||||||
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
|
|
||||||
|
|
||||||
template<typename NewReturn>
|
|
||||||
using apply_return = NewReturn(Args..., ...)
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
|
|
||||||
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
|
|
||||||
|
|
||||||
template<template<class...> class Container>
|
|
||||||
using expand_args = Container<Args...>;
|
|
||||||
|
|
||||||
using is_member_pointer = std::false_type;
|
|
||||||
};
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2016 Modified Work Barrett Adair
|
|
||||||
|
|
||||||
Distributed under the Boost Software License, Version 1.0.
|
|
||||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
|
||||||
|
|
||||||
HEADER GUARDS INTENTIONALLY OMITTED
|
|
||||||
DO NOT INCLUDE THIS HEADER DIRECTLY
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
|
|
||||||
#define BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE std::false_type
|
|
||||||
#include <boost/callable_traits/detail/unguarded/function_ptr_2.hpp>
|
|
||||||
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
|
|
||||||
#undef BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE
|
|
||||||
|
|
||||||
#ifdef BOOST_CLBL_TRTS_ENABLE_TRANSACTION_SAFE
|
|
||||||
#define BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE std::true_type
|
|
||||||
#define BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE transaction_safe
|
|
||||||
#include <boost/callable_traits/detail/unguarded/function_ptr_2.hpp>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
|
|
||||||
#undef BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2016 Barrett Adair
|
|
||||||
|
|
||||||
Distributed under the Boost Software License, Version 1.0.
|
|
||||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
|
||||||
|
|
||||||
HEADER GUARDS INTENTIONALLY OMITTED
|
|
||||||
DO NOT INCLUDE THIS HEADER DIRECTLY
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define BOOST_CLBL_TRTS_NOEXCEPT_SPEC
|
|
||||||
#define BOOST_CLBL_TRTS_IS_NOEXCEPT std::false_type
|
|
||||||
#include <boost/callable_traits/detail/unguarded/function_ptr_3.hpp>
|
|
||||||
#undef BOOST_CLBL_TRTS_NOEXCEPT_SPEC
|
|
||||||
#undef BOOST_CLBL_TRTS_IS_NOEXCEPT
|
|
||||||
|
|
||||||
#ifdef BOOST_CLBL_TRTS_ENABLE_NOEXCEPT_TYPES
|
|
||||||
#define BOOST_CLBL_TRTS_NOEXCEPT_SPEC noexcept
|
|
||||||
#define BOOST_CLBL_TRTS_IS_NOEXCEPT std::true_type
|
|
||||||
#include <boost/callable_traits/detail/unguarded/function_ptr_3.hpp>
|
|
||||||
#undef BOOST_CLBL_TRTS_NOEXCEPT_SPEC
|
|
||||||
#undef BOOST_CLBL_TRTS_IS_NOEXCEPT
|
|
||||||
#endif // #ifdef BOOST_CLBL_TRTS_ENABLE_NOEXCEPT_TYPES
|
|
||||||
@@ -1,94 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2016 Modified Work Barrett Adair
|
|
||||||
|
|
||||||
Distributed under the Boost Software License, Version 1.0.
|
|
||||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
|
||||||
|
|
||||||
HEADER GUARDS INTENTIONALLY OMITTED
|
|
||||||
DO NOT INCLUDE THIS HEADER DIRECTLY
|
|
||||||
|
|
||||||
macros used:
|
|
||||||
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE - the transaction_safe specifier for
|
|
||||||
the current include (`transaction_safe` or nothing)
|
|
||||||
|
|
||||||
BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE - `std::true_type` or `std::false_type`,
|
|
||||||
tied on whether BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE is `transaction_safe`
|
|
||||||
|
|
||||||
BOOST_CLBL_TRTS_TRANSACTION_SAFE_SPECIFIER - `transaction_safe` when
|
|
||||||
BOOST_CLBL_TRTS_ENABLE_TRANSACTION_SAFE is enabled, otherwise nothing
|
|
||||||
|
|
||||||
BOOST_CLBL_TRTS_NOEXCEPT_SPEC - the noexcept specifier for
|
|
||||||
the current include (`noexcept` or nothing)
|
|
||||||
|
|
||||||
BOOST_CLBL_TRTS_IS_NOEXCEPT - `std::true_type` or `std::false_type`,
|
|
||||||
tied on whether BOOST_CLBL_TRTS_NOEXCEPT_SPEC is `noexcept`
|
|
||||||
|
|
||||||
BOOST_CLBL_TRTS_NOEXCEPT_SPECIFIER - `noexcept` if
|
|
||||||
BOOST_CLBL_TRTS_ENABLE_NOEXCEPT_TYPES is defined, otherwise nothing
|
|
||||||
*/
|
|
||||||
|
|
||||||
template<typename Return, typename... Args>
|
|
||||||
struct function<
|
|
||||||
BOOST_CLBL_TRTS_ST Return(BOOST_CLBL_TRTS_CC *)(Args...)
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
|
|
||||||
BOOST_CLBL_TRTS_NOEXCEPT_SPEC>
|
|
||||||
: default_callable_traits<> {
|
|
||||||
|
|
||||||
static constexpr bool value = true;
|
|
||||||
|
|
||||||
using traits = function;
|
|
||||||
|
|
||||||
using return_type = Return;
|
|
||||||
|
|
||||||
using arg_types = std::tuple<Args...>;
|
|
||||||
using non_invoke_arg_types = arg_types;
|
|
||||||
|
|
||||||
using type = BOOST_CLBL_TRTS_ST Return(BOOST_CLBL_TRTS_CC *)(Args...)
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE;
|
|
||||||
|
|
||||||
using function_type = Return(Args...);
|
|
||||||
using qualified_function_type = function_type;
|
|
||||||
using remove_varargs = type;
|
|
||||||
|
|
||||||
using add_varargs =
|
|
||||||
BOOST_CLBL_TRTS_ST Return (BOOST_CLBL_TRTS_VARARGS_CC *)(Args..., ...)
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
|
|
||||||
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
|
|
||||||
|
|
||||||
using is_noexcept = BOOST_CLBL_TRTS_IS_NOEXCEPT;
|
|
||||||
|
|
||||||
using remove_noexcept = Return(BOOST_CLBL_TRTS_CC *)(Args...)
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE;
|
|
||||||
|
|
||||||
using add_noexcept = Return(BOOST_CLBL_TRTS_CC *)(Args...)
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
|
|
||||||
BOOST_CLBL_TRTS_NOEXCEPT_SPECIFIER;
|
|
||||||
|
|
||||||
using is_transaction_safe = BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE;
|
|
||||||
|
|
||||||
using remove_transaction_safe = Return(BOOST_CLBL_TRTS_CC *)(Args...)
|
|
||||||
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
|
|
||||||
|
|
||||||
using add_transaction_safe = Return(BOOST_CLBL_TRTS_CC *)(Args...)
|
|
||||||
BOOST_CLBL_TRTS_TRANSACTION_SAFE_SPECIFIER
|
|
||||||
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
|
|
||||||
|
|
||||||
template<typename U>
|
|
||||||
using apply_member_pointer =
|
|
||||||
BOOST_CLBL_TRTS_ST Return(BOOST_CLBL_TRTS_CC U::*)(Args...)
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
|
|
||||||
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
|
|
||||||
|
|
||||||
template<typename NewReturn>
|
|
||||||
using apply_return =
|
|
||||||
BOOST_CLBL_TRTS_ST NewReturn(BOOST_CLBL_TRTS_CC *)(Args...)
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
|
|
||||||
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
|
|
||||||
|
|
||||||
template<template<class...> class Container>
|
|
||||||
using expand_args = Container<Args...>;
|
|
||||||
|
|
||||||
using is_member_pointer = std::false_type;
|
|
||||||
};
|
|
||||||
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2016 Modified Work Barrett Adair
|
|
||||||
|
|
||||||
Distributed under the Boost Software License, Version 1.0.
|
|
||||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
|
||||||
|
|
||||||
HEADER GUARDS INTENTIONALLY OMITTED
|
|
||||||
DO NOT INCLUDE THIS HEADER DIRECTLY
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
|
|
||||||
#define BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE std::false_type
|
|
||||||
#include <boost/callable_traits/detail/unguarded/function_ptr_varargs_2.hpp>
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
|
|
||||||
#undef BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE
|
|
||||||
|
|
||||||
#ifdef BOOST_CLBL_TRTS_ENABLE_TRANSACTION_SAFE
|
|
||||||
#define BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE std::true_type
|
|
||||||
#define BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE transaction_safe
|
|
||||||
#include <boost/callable_traits/detail/unguarded/function_ptr_varargs_2.hpp>
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
|
|
||||||
#undef BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE
|
|
||||||
#endif // #ifdef BOOST_CLBL_TRTS_ENABLE_TRANSACTION_SAFE
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2016 Barrett Adair
|
|
||||||
|
|
||||||
Distributed under the Boost Software License, Version 1.0.
|
|
||||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
|
||||||
|
|
||||||
HEADER GUARDS INTENTIONALLY OMITTED
|
|
||||||
DO NOT INCLUDE THIS HEADER DIRECTLY
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define BOOST_CLBL_TRTS_NOEXCEPT_SPEC
|
|
||||||
#define BOOST_CLBL_TRTS_IS_NOEXCEPT std::false_type
|
|
||||||
#include <boost/callable_traits/detail/unguarded/function_ptr_varargs_3.hpp>
|
|
||||||
#undef BOOST_CLBL_TRTS_NOEXCEPT_SPEC
|
|
||||||
#undef BOOST_CLBL_TRTS_IS_NOEXCEPT
|
|
||||||
|
|
||||||
#ifdef BOOST_CLBL_TRTS_ENABLE_NOEXCEPT_TYPES
|
|
||||||
#define BOOST_CLBL_TRTS_NOEXCEPT_SPEC noexcept
|
|
||||||
#define BOOST_CLBL_TRTS_IS_NOEXCEPT std::true_type
|
|
||||||
#include <boost/callable_traits/detail/unguarded/function_ptr_varargs_3.hpp>
|
|
||||||
#undef BOOST_CLBL_TRTS_NOEXCEPT_SPEC
|
|
||||||
#undef BOOST_CLBL_TRTS_IS_NOEXCEPT
|
|
||||||
#endif // #ifdef BOOST_CLBL_TRTS_ENABLE_NOEXCEPT_TYPES
|
|
||||||
@@ -1,98 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2016 Modified Work Barrett Adair
|
|
||||||
|
|
||||||
Distributed under the Boost Software License, Version 1.0.
|
|
||||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
|
||||||
|
|
||||||
HEADER GUARDS INTENTIONALLY OMITTED
|
|
||||||
DO NOT INCLUDE THIS HEADER DIRECTLY
|
|
||||||
|
|
||||||
macros used:
|
|
||||||
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE - the transaction_safe specifier for
|
|
||||||
the current include (`transaction_safe` or nothing)
|
|
||||||
|
|
||||||
BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE - `std::true_type` or `std::false_type`,
|
|
||||||
tied on whether BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE is `transaction_safe`
|
|
||||||
|
|
||||||
BOOST_CLBL_TRTS_TRANSACTION_SAFE_SPECIFIER - `transaction_safe` when
|
|
||||||
BOOST_CLBL_TRTS_ENABLE_TRANSACTION_SAFE is enabled, otherwise nothing
|
|
||||||
|
|
||||||
BOOST_CLBL_TRTS_NOEXCEPT_SPEC - the noexcept specifier for
|
|
||||||
the current include (`noexcept` or nothing)
|
|
||||||
|
|
||||||
BOOST_CLBL_TRTS_IS_NOEXCEPT - `std::true_type` or `std::false_type`,
|
|
||||||
tied on whether BOOST_CLBL_TRTS_NOEXCEPT_SPEC is `noexcept`
|
|
||||||
|
|
||||||
BOOST_CLBL_TRTS_NOEXCEPT_SPECIFIER - `noexcept` if
|
|
||||||
BOOST_CLBL_TRTS_ENABLE_NOEXCEPT_TYPES is defined, otherwise nothing
|
|
||||||
*/
|
|
||||||
|
|
||||||
template<typename Return, typename... Args>
|
|
||||||
struct function<BOOST_CLBL_TRTS_ST Return(BOOST_CLBL_TRTS_VARARGS_CC *)(Args..., ...)
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
|
|
||||||
BOOST_CLBL_TRTS_NOEXCEPT_SPEC>
|
|
||||||
: default_callable_traits<> {
|
|
||||||
|
|
||||||
static constexpr bool value = true;
|
|
||||||
|
|
||||||
using has_varargs = std::true_type;
|
|
||||||
|
|
||||||
using traits = function;
|
|
||||||
|
|
||||||
using return_type = Return;
|
|
||||||
|
|
||||||
using arg_types = std::tuple<Args...>;
|
|
||||||
using non_invoke_arg_types = arg_types;
|
|
||||||
|
|
||||||
using type =
|
|
||||||
BOOST_CLBL_TRTS_ST Return(BOOST_CLBL_TRTS_VARARGS_CC *)(Args..., ...)
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
|
|
||||||
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
|
|
||||||
|
|
||||||
using function_type = Return(Args..., ...);
|
|
||||||
|
|
||||||
using qualified_function_type = function_type;
|
|
||||||
|
|
||||||
using remove_varargs =
|
|
||||||
BOOST_CLBL_TRTS_ST Return(BOOST_CLBL_TRTS_CC *)(Args...)
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE;
|
|
||||||
|
|
||||||
using add_varargs = type;
|
|
||||||
|
|
||||||
using is_noexcept = BOOST_CLBL_TRTS_IS_NOEXCEPT;
|
|
||||||
|
|
||||||
using remove_noexcept = BOOST_CLBL_TRTS_ST Return(BOOST_CLBL_TRTS_CC *)(Args..., ...)
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE;
|
|
||||||
|
|
||||||
using add_noexcept = BOOST_CLBL_TRTS_ST Return(BOOST_CLBL_TRTS_CC *)(Args..., ...)
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
|
|
||||||
BOOST_CLBL_TRTS_NOEXCEPT_SPECIFIER;
|
|
||||||
|
|
||||||
using is_transaction_safe = BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE;
|
|
||||||
|
|
||||||
using remove_transaction_safe = Return(BOOST_CLBL_TRTS_VARARGS_CC *)(Args..., ...)
|
|
||||||
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
|
|
||||||
|
|
||||||
using add_transaction_safe = Return(BOOST_CLBL_TRTS_VARARGS_CC *)(Args..., ...)
|
|
||||||
BOOST_CLBL_TRTS_TRANSACTION_SAFE_SPECIFIER
|
|
||||||
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
|
|
||||||
|
|
||||||
template<typename U>
|
|
||||||
using apply_member_pointer =
|
|
||||||
BOOST_CLBL_TRTS_ST Return(BOOST_CLBL_TRTS_VARARGS_CC U::*)(Args..., ...)
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
|
|
||||||
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
|
|
||||||
|
|
||||||
template<typename NewReturn>
|
|
||||||
using apply_return =
|
|
||||||
BOOST_CLBL_TRTS_ST NewReturn(BOOST_CLBL_TRTS_VARARGS_CC *)(Args..., ...)
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
|
|
||||||
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
|
|
||||||
|
|
||||||
template<template<class...> class Container>
|
|
||||||
using expand_args = Container<Args...>;
|
|
||||||
|
|
||||||
using is_member_pointer = std::false_type;
|
|
||||||
};
|
|
||||||
|
|
||||||
@@ -1,94 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2001 Peter Dimov and Multi Media Ltd.
|
|
||||||
Copyright (c) 2016 Modified Work Barrett Adair
|
|
||||||
|
|
||||||
Distributed under the Boost Software License, Version 1.0.
|
|
||||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
|
||||||
|
|
||||||
HEADER GUARDS INTENTIONALLY OMITTED
|
|
||||||
DO NOT INCLUDE THIS HEADER DIRECTLY
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
|
|
||||||
|
|
||||||
|
|
||||||
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
#define BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
|
|
||||||
#include <boost/callable_traits/detail/unguarded/pmf_2.hpp>
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
|
|
||||||
|
|
||||||
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS const
|
|
||||||
#define BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS \
|
|
||||||
BOOST_CLBL_TRTS_ABOMINABLE_CONST
|
|
||||||
#include <boost/callable_traits/detail/unguarded/pmf_2.hpp>
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
|
|
||||||
|
|
||||||
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS volatile
|
|
||||||
#define BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS \
|
|
||||||
BOOST_CLBL_TRTS_ABOMINABLE_VOLATILE
|
|
||||||
#include <boost/callable_traits/detail/unguarded/pmf_2.hpp>
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
|
|
||||||
|
|
||||||
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS const volatile
|
|
||||||
#define BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS \
|
|
||||||
BOOST_CLBL_TRTS_ABOMINABLE_CONST BOOST_CLBL_TRTS_ABOMINABLE_VOLATILE
|
|
||||||
#include <boost/callable_traits/detail/unguarded/pmf_2.hpp>
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
|
|
||||||
|
|
||||||
#ifndef BOOST_CLBL_TRTS_DISABLE_REFERENCE_QUALIFIERS
|
|
||||||
|
|
||||||
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS &
|
|
||||||
#define BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS &
|
|
||||||
#include <boost/callable_traits/detail/unguarded/pmf_2.hpp>
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
|
|
||||||
|
|
||||||
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS &&
|
|
||||||
#define BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS &&
|
|
||||||
#include <boost/callable_traits/detail/unguarded/pmf_2.hpp>
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
|
|
||||||
|
|
||||||
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS const &
|
|
||||||
#define BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS const &
|
|
||||||
#include <boost/callable_traits/detail/unguarded/pmf_2.hpp>
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
|
|
||||||
|
|
||||||
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS volatile &
|
|
||||||
#define BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS volatile &
|
|
||||||
#include <boost/callable_traits/detail/unguarded/pmf_2.hpp>
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
|
|
||||||
|
|
||||||
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS const volatile &
|
|
||||||
#define BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS const volatile &
|
|
||||||
#include <boost/callable_traits/detail/unguarded/pmf_2.hpp>
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
|
|
||||||
|
|
||||||
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS const &&
|
|
||||||
#define BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS const &&
|
|
||||||
#include <boost/callable_traits/detail/unguarded/pmf_2.hpp>
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
|
|
||||||
|
|
||||||
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS volatile &&
|
|
||||||
#define BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS volatile &&
|
|
||||||
#include <boost/callable_traits/detail/unguarded/pmf_2.hpp>
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
|
|
||||||
|
|
||||||
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS const volatile &&
|
|
||||||
#define BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS const volatile &&
|
|
||||||
#include <boost/callable_traits/detail/unguarded/pmf_2.hpp>
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
|
|
||||||
|
|
||||||
#endif // #ifndef BOOST_CLBL_TRTS_DISABLE_REFERENCE_QUALIFIERS
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2016 Barrett Adair
|
|
||||||
|
|
||||||
Distributed under the Boost Software License, Version 1.0.
|
|
||||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
|
||||||
|
|
||||||
HEADER GUARDS INTENTIONALLY OMITTED
|
|
||||||
DO NOT INCLUDE THIS HEADER DIRECTLY
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
template<typename Return, typename T, typename... Args>
|
|
||||||
struct set_member_function_qualifiers_t<
|
|
||||||
flag_map<int BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS>::value,
|
|
||||||
false, // IsTransactionSafe
|
|
||||||
false, // IsNoexcept
|
|
||||||
BOOST_CLBL_TRTS_CC_TAG, T, Return, Args...> {
|
|
||||||
|
|
||||||
using type = Return(BOOST_CLBL_TRTS_CC T::*)(Args...)
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Return, typename T, typename... Args>
|
|
||||||
struct set_member_function_qualifiers_t<
|
|
||||||
flag_map<int BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS>::value,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
BOOST_CLBL_TRTS_CC_TAG, T, Return, Args...> {
|
|
||||||
|
|
||||||
using type = Return(BOOST_CLBL_TRTS_CC T::*)(Args...)
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
BOOST_CLBL_TRTS_NOEXCEPT_SPECIFIER;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Return, typename T, typename... Args>
|
|
||||||
struct set_member_function_qualifiers_t<
|
|
||||||
flag_map<int BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS>::value,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
BOOST_CLBL_TRTS_CC_TAG, T, Return, Args...> {
|
|
||||||
|
|
||||||
using type = Return(BOOST_CLBL_TRTS_CC T::*)(Args...)
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
BOOST_CLBL_TRTS_TRANSACTION_SAFE_SPECIFIER;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Return, typename T, typename... Args>
|
|
||||||
struct set_member_function_qualifiers_t<
|
|
||||||
flag_map<int BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS>::value,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
BOOST_CLBL_TRTS_CC_TAG, T, Return, Args...> {
|
|
||||||
|
|
||||||
using type = Return(BOOST_CLBL_TRTS_CC T::*)(Args...)
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
BOOST_CLBL_TRTS_TRANSACTION_SAFE_SPECIFIER
|
|
||||||
BOOST_CLBL_TRTS_NOEXCEPT_SPECIFIER;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
|
|
||||||
#define BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE std::false_type
|
|
||||||
#include <boost/callable_traits/detail/unguarded/pmf_3.hpp>
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
|
|
||||||
#undef BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE
|
|
||||||
|
|
||||||
#ifdef BOOST_CLBL_TRTS_ENABLE_TRANSACTION_SAFE
|
|
||||||
|
|
||||||
#define BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE std::true_type
|
|
||||||
#define BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE transaction_safe
|
|
||||||
#include <boost/callable_traits/detail/unguarded/pmf_3.hpp>
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
|
|
||||||
#undef BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2016 Barrett Adair
|
|
||||||
|
|
||||||
Distributed under the Boost Software License, Version 1.0.
|
|
||||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
|
||||||
|
|
||||||
HEADER GUARDS INTENTIONALLY OMITTED
|
|
||||||
DO NOT INCLUDE THIS HEADER DIRECTLY
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define BOOST_CLBL_TRTS_NOEXCEPT_SPEC
|
|
||||||
#define BOOST_CLBL_TRTS_IS_NOEXCEPT std::false_type
|
|
||||||
#include <boost/callable_traits/detail/unguarded/pmf_4.hpp>
|
|
||||||
#undef BOOST_CLBL_TRTS_NOEXCEPT_SPEC
|
|
||||||
#undef BOOST_CLBL_TRTS_IS_NOEXCEPT
|
|
||||||
|
|
||||||
#ifdef BOOST_CLBL_TRTS_ENABLE_NOEXCEPT_TYPES
|
|
||||||
#define BOOST_CLBL_TRTS_NOEXCEPT_SPEC noexcept
|
|
||||||
#define BOOST_CLBL_TRTS_IS_NOEXCEPT std::true_type
|
|
||||||
#include <boost/callable_traits/detail/unguarded/pmf_4.hpp>
|
|
||||||
#undef BOOST_CLBL_TRTS_NOEXCEPT_SPEC
|
|
||||||
#undef BOOST_CLBL_TRTS_IS_NOEXCEPT
|
|
||||||
#endif // #ifdef BOOST_CLBL_TRTS_ENABLE_NOEXCEPT_TYPES
|
|
||||||
@@ -1,147 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2016 Barrett Adair
|
|
||||||
|
|
||||||
Distributed under the Boost Software License, Version 1.0.
|
|
||||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
|
||||||
|
|
||||||
HEADER GUARDS INTENTIONALLY OMITTED
|
|
||||||
DO NOT INCLUDE THIS HEADER DIRECTLY
|
|
||||||
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS - the function-level qualifiers for the
|
|
||||||
current inclusion (combinations of `const` `volatile` `&` `&&`, or nothing)
|
|
||||||
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE - the transaction_safe specifier for
|
|
||||||
the current include (`transaction_safe` or nothing)
|
|
||||||
|
|
||||||
BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE - `std::true_type` or `std::false_type`,
|
|
||||||
tied on whether BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE is `transaction_safe`
|
|
||||||
|
|
||||||
BOOST_CLBL_TRTS_TRANSACTION_SAFE_SPECIFIER - `transaction_safe` when
|
|
||||||
BOOST_CLBL_TRTS_ENABLE_TRANSACTION_SAFE is defined, otherwise nothing
|
|
||||||
|
|
||||||
BOOST_CLBL_TRTS_NOEXCEPT_SPEC - the noexcept specifier for
|
|
||||||
the current include (`noexcept` or nothing)
|
|
||||||
|
|
||||||
BOOST_CLBL_TRTS_IS_NOEXCEPT - `std::true_type` or `std::false_type`,
|
|
||||||
tied on whether BOOST_CLBL_TRTS_NOEXCEPT_SPEC is `noexcept`
|
|
||||||
|
|
||||||
BOOST_CLBL_TRTS_NOEXCEPT_SPECIFIER - `noexcept` if
|
|
||||||
BOOST_CLBL_TRTS_ENABLE_NOEXCEPT_TYPES is defined, otherwise nothing
|
|
||||||
*/
|
|
||||||
|
|
||||||
template<typename Return, typename T, typename... Args>
|
|
||||||
struct pmf<Return(BOOST_CLBL_TRTS_CC T::*)(Args...)
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
|
|
||||||
BOOST_CLBL_TRTS_NOEXCEPT_SPEC>
|
|
||||||
: default_callable_traits<dummy BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS> {
|
|
||||||
|
|
||||||
static constexpr bool value = true;
|
|
||||||
|
|
||||||
using traits = pmf;
|
|
||||||
|
|
||||||
using return_type = Return;
|
|
||||||
|
|
||||||
using type = Return(BOOST_CLBL_TRTS_CC T::*)(Args...)
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
|
|
||||||
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
|
|
||||||
|
|
||||||
using invoke_type = typename std::conditional<
|
|
||||||
std::is_rvalue_reference<T BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS>::value,
|
|
||||||
T BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS,
|
|
||||||
typename std::add_lvalue_reference<T BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS>::type
|
|
||||||
>::type;
|
|
||||||
|
|
||||||
using arg_types = std::tuple<invoke_type, Args...>;
|
|
||||||
using non_invoke_arg_types = std::tuple<Args...>;
|
|
||||||
|
|
||||||
using function_object_signature = Return(Args...);
|
|
||||||
|
|
||||||
using function_type = Return(invoke_type, Args...);
|
|
||||||
|
|
||||||
using qualified_function_type = Return(Args...)
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
|
|
||||||
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
|
|
||||||
|
|
||||||
using remove_varargs = type;
|
|
||||||
|
|
||||||
using add_varargs =
|
|
||||||
Return(BOOST_CLBL_TRTS_VARARGS_CC T::*)(Args..., ...)
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
|
|
||||||
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
|
|
||||||
|
|
||||||
using is_noexcept = BOOST_CLBL_TRTS_IS_NOEXCEPT;
|
|
||||||
|
|
||||||
using remove_noexcept = Return(BOOST_CLBL_TRTS_CC T::*)(Args...)
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE;
|
|
||||||
|
|
||||||
using add_noexcept = Return(BOOST_CLBL_TRTS_CC T::*)(Args...)
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
|
|
||||||
BOOST_CLBL_TRTS_NOEXCEPT_SPECIFIER;
|
|
||||||
|
|
||||||
using is_transaction_safe = BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE;
|
|
||||||
|
|
||||||
using remove_transaction_safe = Return(BOOST_CLBL_TRTS_CC T::*)(Args...)
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
|
|
||||||
|
|
||||||
using add_transaction_safe = Return(BOOST_CLBL_TRTS_CC T::*)(Args...)
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
BOOST_CLBL_TRTS_TRANSACTION_SAFE_SPECIFIER
|
|
||||||
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
|
|
||||||
|
|
||||||
using class_type = T;
|
|
||||||
|
|
||||||
using qualifiers = default_callable_traits<dummy BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS>;
|
|
||||||
|
|
||||||
template<qualifier_flags Flags>
|
|
||||||
using set_qualifiers = set_member_function_qualifiers<
|
|
||||||
Flags, is_transaction_safe::value, is_noexcept::value,
|
|
||||||
BOOST_CLBL_TRTS_CC_TAG, T, Return, Args...>;
|
|
||||||
|
|
||||||
using remove_member_reference = set_qualifiers<qualifiers::cv_flags>;
|
|
||||||
|
|
||||||
using add_member_lvalue_reference = set_qualifiers<
|
|
||||||
collapse_flags<qualifiers::q_flags, lref_>::value>;
|
|
||||||
|
|
||||||
using add_member_rvalue_reference = set_qualifiers<
|
|
||||||
collapse_flags<qualifiers::q_flags, rref_>::value>;
|
|
||||||
|
|
||||||
using add_member_const = set_qualifiers<qualifiers::q_flags | const_>;
|
|
||||||
|
|
||||||
using add_member_volatile = set_qualifiers<qualifiers::q_flags | volatile_>;
|
|
||||||
|
|
||||||
using add_member_cv = set_qualifiers<qualifiers::q_flags | cv_>;
|
|
||||||
|
|
||||||
using remove_member_const = set_qualifiers<
|
|
||||||
qualifiers::ref_flags | remove_const_flag<qualifiers::cv_flags>::value>;
|
|
||||||
|
|
||||||
using remove_member_volatile = set_qualifiers<
|
|
||||||
qualifiers::ref_flags | remove_volatile_flag<qualifiers::cv_flags>::value>;
|
|
||||||
|
|
||||||
using remove_member_cv = set_qualifiers<qualifiers::ref_flags>;
|
|
||||||
|
|
||||||
template<typename U>
|
|
||||||
using apply_member_pointer =
|
|
||||||
Return(BOOST_CLBL_TRTS_CC U::*)(Args...)
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
|
|
||||||
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
|
|
||||||
|
|
||||||
template<typename NewReturn>
|
|
||||||
using apply_return =
|
|
||||||
NewReturn(BOOST_CLBL_TRTS_CC T::*)(Args...)
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
|
|
||||||
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
|
|
||||||
|
|
||||||
template<template<class...> class Container>
|
|
||||||
using expand_args = Container<invoke_type, Args...>;
|
|
||||||
|
|
||||||
using is_member_pointer = std::true_type;
|
|
||||||
};
|
|
||||||
@@ -1,89 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2016 Barrett Adair
|
|
||||||
|
|
||||||
Distributed under the Boost Software License, Version 1.0.
|
|
||||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
|
||||||
|
|
||||||
HEADER GUARDS INTENTIONALLY OMITTED
|
|
||||||
DO NOT INCLUDE THIS HEADER DIRECTLY
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
#define BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
|
|
||||||
#include <boost/callable_traits/detail/unguarded/pmf_varargs_2.hpp>
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
|
|
||||||
|
|
||||||
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS const
|
|
||||||
#define BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS \
|
|
||||||
BOOST_CLBL_TRTS_ABOMINABLE_CONST
|
|
||||||
#include <boost/callable_traits/detail/unguarded/pmf_varargs_2.hpp>
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
|
|
||||||
|
|
||||||
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS volatile
|
|
||||||
#define BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS \
|
|
||||||
BOOST_CLBL_TRTS_ABOMINABLE_VOLATILE
|
|
||||||
#include <boost/callable_traits/detail/unguarded/pmf_varargs_2.hpp>
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
|
|
||||||
|
|
||||||
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS const volatile
|
|
||||||
#define BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS \
|
|
||||||
BOOST_CLBL_TRTS_ABOMINABLE_CONST BOOST_CLBL_TRTS_ABOMINABLE_VOLATILE
|
|
||||||
#include <boost/callable_traits/detail/unguarded/pmf_varargs_2.hpp>
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
|
|
||||||
|
|
||||||
#ifndef BOOST_CLBL_TRTS_DISABLE_REFERENCE_QUALIFIERS
|
|
||||||
|
|
||||||
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS &
|
|
||||||
#define BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS &
|
|
||||||
#include <boost/callable_traits/detail/unguarded/pmf_varargs_2.hpp>
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
|
|
||||||
|
|
||||||
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS &&
|
|
||||||
#define BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS &&
|
|
||||||
#include <boost/callable_traits/detail/unguarded/pmf_varargs_2.hpp>
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
|
|
||||||
|
|
||||||
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS const &
|
|
||||||
#define BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS const &
|
|
||||||
#include <boost/callable_traits/detail/unguarded/pmf_varargs_2.hpp>
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
|
|
||||||
|
|
||||||
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS volatile &
|
|
||||||
#define BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS volatile &
|
|
||||||
#include <boost/callable_traits/detail/unguarded/pmf_varargs_2.hpp>
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
|
|
||||||
|
|
||||||
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS const volatile &
|
|
||||||
#define BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS const volatile &
|
|
||||||
#include <boost/callable_traits/detail/unguarded/pmf_varargs_2.hpp>
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
|
|
||||||
|
|
||||||
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS const &&
|
|
||||||
#define BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS const &&
|
|
||||||
#include <boost/callable_traits/detail/unguarded/pmf_varargs_2.hpp>
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
|
|
||||||
|
|
||||||
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS volatile &&
|
|
||||||
#define BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS volatile &&
|
|
||||||
#include <boost/callable_traits/detail/unguarded/pmf_varargs_2.hpp>
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
|
|
||||||
|
|
||||||
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS const volatile &&
|
|
||||||
#define BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS const volatile &&
|
|
||||||
#include <boost/callable_traits/detail/unguarded/pmf_varargs_2.hpp>
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
|
|
||||||
|
|
||||||
#endif // #ifndef BOOST_CLBL_TRTS_DISABLE_REFERENCE_QUALIFIERS
|
|
||||||
@@ -1,78 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2016 Barrett Adair
|
|
||||||
|
|
||||||
Distributed under the Boost Software License, Version 1.0.
|
|
||||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
|
||||||
|
|
||||||
HEADER GUARDS INTENTIONALLY OMITTED
|
|
||||||
DO NOT INCLUDE THIS HEADER DIRECTLY
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
template<typename T, typename Return, typename... Args>
|
|
||||||
struct set_varargs_member_function_qualifiers_t <
|
|
||||||
flag_map<int BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS>::value,
|
|
||||||
false, // IsTransactionSafe
|
|
||||||
false, // IsNoexcept
|
|
||||||
BOOST_CLBL_TRTS_CC_TAG, T, Return, Args...> {
|
|
||||||
|
|
||||||
using type =
|
|
||||||
Return(BOOST_CLBL_TRTS_VARARGS_CC T::*)(Args..., ...)
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T, typename Return, typename... Args>
|
|
||||||
struct set_varargs_member_function_qualifiers_t <
|
|
||||||
flag_map<int BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS>::value,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
BOOST_CLBL_TRTS_CC_TAG, T, Return, Args...> {
|
|
||||||
|
|
||||||
using type =
|
|
||||||
Return(BOOST_CLBL_TRTS_VARARGS_CC T::*)(Args..., ...)
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS BOOST_CLBL_TRTS_NOEXCEPT_SPECIFIER;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T, typename Return, typename... Args>
|
|
||||||
struct set_varargs_member_function_qualifiers_t <
|
|
||||||
flag_map<int BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS>::value,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
BOOST_CLBL_TRTS_CC_TAG, T, Return, Args...> {
|
|
||||||
|
|
||||||
using type =
|
|
||||||
Return(BOOST_CLBL_TRTS_VARARGS_CC T::*)(Args..., ...)
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
BOOST_CLBL_TRTS_TRANSACTION_SAFE_SPECIFIER;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T, typename Return, typename... Args>
|
|
||||||
struct set_varargs_member_function_qualifiers_t <
|
|
||||||
flag_map<int BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS>::value,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
BOOST_CLBL_TRTS_CC_TAG, T, Return, Args...> {
|
|
||||||
|
|
||||||
using type =
|
|
||||||
Return(BOOST_CLBL_TRTS_VARARGS_CC T::*)(Args..., ...)
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
BOOST_CLBL_TRTS_TRANSACTION_SAFE_SPECIFIER
|
|
||||||
BOOST_CLBL_TRTS_NOEXCEPT_SPECIFIER;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
|
|
||||||
#define BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE std::false_type
|
|
||||||
#include <boost/callable_traits/detail/unguarded/pmf_varargs_3.hpp>
|
|
||||||
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
|
|
||||||
#undef BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE
|
|
||||||
|
|
||||||
#ifdef BOOST_CLBL_TRTS_ENABLE_TRANSACTION_SAFE
|
|
||||||
|
|
||||||
#define BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE std::true_type
|
|
||||||
#define BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE transaction_safe
|
|
||||||
#include <boost/callable_traits/detail/unguarded/pmf_varargs_3.hpp>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#undef BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
|
|
||||||
#undef BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2016 Barrett Adair
|
|
||||||
|
|
||||||
Distributed under the Boost Software License, Version 1.0.
|
|
||||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
|
||||||
|
|
||||||
HEADER GUARDS INTENTIONALLY OMITTED
|
|
||||||
DO NOT INCLUDE THIS HEADER DIRECTLY
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define BOOST_CLBL_TRTS_NOEXCEPT_SPEC
|
|
||||||
#define BOOST_CLBL_TRTS_IS_NOEXCEPT std::false_type
|
|
||||||
#include <boost/callable_traits/detail/unguarded/pmf_varargs_4.hpp>
|
|
||||||
#undef BOOST_CLBL_TRTS_NOEXCEPT_SPEC
|
|
||||||
#undef BOOST_CLBL_TRTS_IS_NOEXCEPT
|
|
||||||
|
|
||||||
#ifdef BOOST_CLBL_TRTS_ENABLE_NOEXCEPT_TYPES
|
|
||||||
#define BOOST_CLBL_TRTS_NOEXCEPT_SPEC noexcept
|
|
||||||
#define BOOST_CLBL_TRTS_IS_NOEXCEPT std::true_type
|
|
||||||
#include <boost/callable_traits/detail/unguarded/pmf_varargs_4.hpp>
|
|
||||||
#undef BOOST_CLBL_TRTS_NOEXCEPT_SPEC
|
|
||||||
#undef BOOST_CLBL_TRTS_IS_NOEXCEPT
|
|
||||||
#endif // #ifdef BOOST_CLBL_TRTS_ENABLE_NOEXCEPT_TYPES
|
|
||||||
@@ -1,149 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2016 Barrett Adair
|
|
||||||
|
|
||||||
Distributed under the Boost Software License, Version 1.0.
|
|
||||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
|
||||||
|
|
||||||
HEADER GUARDS INTENTIONALLY OMITTED
|
|
||||||
DO NOT INCLUDE THIS HEADER DIRECTLY
|
|
||||||
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS - the function-level qualifiers for the
|
|
||||||
current inclusion (combinations of `const` `volatile` `&` `&&`, or nothing)
|
|
||||||
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE - the transaction_safe specifier for
|
|
||||||
the current include (`transaction_safe` or nothing)
|
|
||||||
|
|
||||||
BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE - `std::true_type` or `std::false_type`,
|
|
||||||
tied on whether BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE is `transaction_safe`
|
|
||||||
|
|
||||||
BOOST_CLBL_TRTS_TRANSACTION_SAFE_SPECIFIER - `transaction_safe` when
|
|
||||||
BOOST_CLBL_TRTS_ENABLE_TRANSACTION_SAFE is enabled, otherwise nothing
|
|
||||||
|
|
||||||
BOOST_CLBL_TRTS_NOEXCEPT_SPEC - the noexcept specifier for
|
|
||||||
the current include (`noexcept` or nothing)
|
|
||||||
|
|
||||||
BOOST_CLBL_TRTS_IS_NOEXCEPT - `std::true_type` or `std::false_type`,
|
|
||||||
tied on whether BOOST_CLBL_TRTS_NOEXCEPT_SPEC is `noexcept`
|
|
||||||
|
|
||||||
BOOST_CLBL_TRTS_NOEXCEPT_SPECIFIER - `noexcept` if
|
|
||||||
BOOST_CLBL_TRTS_ENABLE_NOEXCEPT_TYPES is defined, otherwise nothing
|
|
||||||
*/
|
|
||||||
|
|
||||||
template<typename Return, typename T, typename... Args>
|
|
||||||
struct pmf<Return(BOOST_CLBL_TRTS_VARARGS_CC T::*)(Args..., ...)
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
|
|
||||||
BOOST_CLBL_TRTS_NOEXCEPT_SPEC>
|
|
||||||
: default_callable_traits<dummy BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS> {
|
|
||||||
|
|
||||||
static constexpr bool value = true;
|
|
||||||
|
|
||||||
using has_varargs = std::true_type;
|
|
||||||
|
|
||||||
using traits = pmf;
|
|
||||||
|
|
||||||
using return_type = Return;
|
|
||||||
|
|
||||||
using type = Return(BOOST_CLBL_TRTS_VARARGS_CC T::*)(Args..., ...)
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
|
|
||||||
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
|
|
||||||
|
|
||||||
using invoke_type = typename std::conditional<
|
|
||||||
std::is_rvalue_reference<T BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS>::value,
|
|
||||||
T BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS,
|
|
||||||
typename std::add_lvalue_reference<T BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS>::type
|
|
||||||
>::type;
|
|
||||||
|
|
||||||
using arg_types = std::tuple<invoke_type, Args...>;
|
|
||||||
using non_invoke_arg_types = std::tuple<Args...>;
|
|
||||||
|
|
||||||
using function_object_signature = Return(Args..., ...);
|
|
||||||
|
|
||||||
using function_type = Return(invoke_type, Args..., ...);
|
|
||||||
|
|
||||||
using qualified_function_type = Return(Args..., ...)
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
|
|
||||||
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
|
|
||||||
|
|
||||||
using remove_varargs =
|
|
||||||
Return(BOOST_CLBL_TRTS_CC T::*)(Args...)
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
|
|
||||||
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
|
|
||||||
|
|
||||||
using add_varargs = type;
|
|
||||||
|
|
||||||
using is_noexcept = BOOST_CLBL_TRTS_IS_NOEXCEPT;
|
|
||||||
|
|
||||||
using remove_noexcept = Return(BOOST_CLBL_TRTS_CC T::*)(Args..., ...)
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE;
|
|
||||||
|
|
||||||
using add_noexcept = Return(BOOST_CLBL_TRTS_CC T::*)(Args..., ...)
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
|
|
||||||
BOOST_CLBL_TRTS_NOEXCEPT_SPECIFIER;
|
|
||||||
|
|
||||||
using is_transaction_safe = BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE;
|
|
||||||
|
|
||||||
using remove_transaction_safe = Return(BOOST_CLBL_TRTS_VARARGS_CC T::*)(Args..., ...)
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
|
|
||||||
|
|
||||||
using add_transaction_safe = Return(BOOST_CLBL_TRTS_VARARGS_CC T::*)(Args..., ...)
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
BOOST_CLBL_TRTS_TRANSACTION_SAFE_SPECIFIER
|
|
||||||
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
|
|
||||||
|
|
||||||
using class_type = T;
|
|
||||||
|
|
||||||
using qualifiers = default_callable_traits<dummy BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS>;
|
|
||||||
|
|
||||||
template<qualifier_flags Flags>
|
|
||||||
using set_qualifiers = set_varargs_member_function_qualifiers<
|
|
||||||
Flags, is_transaction_safe::value, is_noexcept::value,
|
|
||||||
BOOST_CLBL_TRTS_CC_TAG, T, Return, Args...>;
|
|
||||||
|
|
||||||
using remove_member_reference = set_qualifiers<qualifiers::cv_flags>;
|
|
||||||
|
|
||||||
using add_member_lvalue_reference = set_qualifiers<
|
|
||||||
collapse_flags<qualifiers::q_flags, lref_>::value>;
|
|
||||||
|
|
||||||
using add_member_rvalue_reference = set_qualifiers<
|
|
||||||
collapse_flags<qualifiers::q_flags, rref_>::value>;
|
|
||||||
|
|
||||||
using add_member_const = set_qualifiers<qualifiers::q_flags | const_>;
|
|
||||||
|
|
||||||
using add_member_volatile = set_qualifiers<qualifiers::q_flags | volatile_>;
|
|
||||||
|
|
||||||
using add_member_cv = set_qualifiers<qualifiers::q_flags | cv_>;
|
|
||||||
|
|
||||||
using remove_member_const = set_qualifiers<
|
|
||||||
qualifiers::ref_flags | remove_const_flag<qualifiers::cv_flags>::value>;
|
|
||||||
|
|
||||||
using remove_member_volatile = set_qualifiers<
|
|
||||||
qualifiers::ref_flags | remove_volatile_flag<qualifiers::cv_flags>::value>;
|
|
||||||
|
|
||||||
using remove_member_cv = set_qualifiers<qualifiers::ref_flags>;
|
|
||||||
|
|
||||||
template<typename U>
|
|
||||||
using apply_member_pointer =
|
|
||||||
Return(BOOST_CLBL_TRTS_VARARGS_CC U::*)(Args..., ...)
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
|
|
||||||
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
|
|
||||||
|
|
||||||
template<typename NewReturn>
|
|
||||||
using apply_return =
|
|
||||||
NewReturn(BOOST_CLBL_TRTS_VARARGS_CC T::*)(Args..., ...)
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
|
|
||||||
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
|
|
||||||
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
|
|
||||||
|
|
||||||
template<template<class...> class Container>
|
|
||||||
using expand_args = Container<invoke_type, Args...>;
|
|
||||||
|
|
||||||
using is_member_pointer = std::true_type;
|
|
||||||
};
|
|
||||||
@@ -1,111 +0,0 @@
|
|||||||
/*
|
|
||||||
|
|
||||||
@Copyright Barrett Adair 2015-2017
|
|
||||||
Distributed under the Boost Software License, Version 1.0.
|
|
||||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef BOOST_CLBL_TRTS_DETAIL_UTILITY_HPP
|
|
||||||
#define BOOST_CLBL_TRTS_DETAIL_UTILITY_HPP
|
|
||||||
|
|
||||||
#include <boost/callable_traits/detail/config.hpp>
|
|
||||||
#include <boost/callable_traits/detail/sfinae_errors.hpp>
|
|
||||||
#include <boost/callable_traits/detail/qualifier_flags.hpp>
|
|
||||||
|
|
||||||
namespace boost { namespace callable_traits { namespace detail {
|
|
||||||
|
|
||||||
struct cdecl_tag{};
|
|
||||||
struct stdcall_tag{};
|
|
||||||
struct fastcall_tag{};
|
|
||||||
struct pascal_tag{};
|
|
||||||
|
|
||||||
struct invalid_type { invalid_type() = delete; };
|
|
||||||
struct reference_error { reference_error() = delete; };
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
using error_type = typename std::conditional<
|
|
||||||
std::is_reference<T>::value, reference_error, invalid_type>::type;
|
|
||||||
|
|
||||||
#ifdef BOOST_CLBL_TRTS_DISABLE_ABOMINABLE_FUNCTIONS
|
|
||||||
struct abominable_functions_not_supported_on_this_compiler{};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// used to convey "this type doesn't matter" in code
|
|
||||||
struct dummy {};
|
|
||||||
|
|
||||||
// used as return type in failed SFINAE tests
|
|
||||||
struct substitution_failure : std::false_type{};
|
|
||||||
|
|
||||||
template<bool Value>
|
|
||||||
using bool_type = std::integral_constant<bool, Value>;
|
|
||||||
|
|
||||||
// shorthand for std::tuple_element
|
|
||||||
template<std::size_t I, typename Tup>
|
|
||||||
using at = typename std::tuple_element<I, Tup>::type;
|
|
||||||
|
|
||||||
template<typename T, typename Class>
|
|
||||||
using add_member_pointer = T Class::*;
|
|
||||||
|
|
||||||
template<typename L, typename R, typename ErrorType>
|
|
||||||
using fail_when_same = fail_if<std::is_same<L, R>::value, ErrorType>;
|
|
||||||
|
|
||||||
template<typename T, typename ErrorType,
|
|
||||||
typename U = typename std::remove_reference<T>::type>
|
|
||||||
using try_but_fail_if_invalid = sfinae_try<T,
|
|
||||||
fail_when_same<U, invalid_type, ErrorType>,
|
|
||||||
fail_when_same<U, reference_error,
|
|
||||||
reference_type_not_supported_by_this_metafunction>>;
|
|
||||||
|
|
||||||
template<typename T, typename ErrorType,
|
|
||||||
typename U = typename std::remove_reference<T>::type,
|
|
||||||
bool is_reference_error = std::is_same<reference_error, U>::value>
|
|
||||||
using fail_if_invalid = fail_if<
|
|
||||||
std::is_same<U, invalid_type>::value || is_reference_error,
|
|
||||||
typename std::conditional<is_reference_error,
|
|
||||||
reference_type_not_supported_by_this_metafunction, ErrorType>::type>;
|
|
||||||
|
|
||||||
template<typename T, typename Fallback>
|
|
||||||
using fallback_if_invalid = typename std::conditional<
|
|
||||||
std::is_same<T, invalid_type>::value, Fallback, T>::type;
|
|
||||||
|
|
||||||
template<typename T, template<class> class Alias, typename U = Alias<T>>
|
|
||||||
struct force_sfinae {
|
|
||||||
using type = U;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
using shallow_decay = typename std::remove_cv<
|
|
||||||
typename std::remove_reference<T>::type>::type;
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct is_reference_wrapper_t {
|
|
||||||
using type = std::false_type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct is_reference_wrapper_t<std::reference_wrapper<T>> {
|
|
||||||
using type = std::true_type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
using is_reference_wrapper =
|
|
||||||
typename is_reference_wrapper_t<shallow_decay<T>>::type;
|
|
||||||
|
|
||||||
template<typename T, typename = std::true_type>
|
|
||||||
struct unwrap_reference_t {
|
|
||||||
using type = T;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct unwrap_reference_t<T, is_reference_wrapper<T>> {
|
|
||||||
using type = decltype(std::declval<T>().get());
|
|
||||||
};
|
|
||||||
|
|
||||||
// removes std::reference_wrapper
|
|
||||||
template<typename T>
|
|
||||||
using unwrap_reference = typename unwrap_reference_t<T>::type;
|
|
||||||
|
|
||||||
}}} // namespace boost::callable_traits::detail
|
|
||||||
|
|
||||||
#endif // #ifndef BOOST_CLBL_TRTS_DETAIL_UTILITY_HPP
|
|
||||||
@@ -1,97 +0,0 @@
|
|||||||
/*
|
|
||||||
|
|
||||||
@Copyright Barrett Adair 2015-2017
|
|
||||||
Distributed under the Boost Software License, Version 1.0.
|
|
||||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef BOOST_CLBL_TRTS_FUNCTION_TYPE_HPP
|
|
||||||
#define BOOST_CLBL_TRTS_FUNCTION_TYPE_HPP
|
|
||||||
|
|
||||||
#include <boost/callable_traits/detail/core.hpp>
|
|
||||||
|
|
||||||
namespace boost { namespace callable_traits {
|
|
||||||
|
|
||||||
//[ function_type_hpp
|
|
||||||
/*`[section:ref_function_type function_type]
|
|
||||||
[heading Header]
|
|
||||||
``#include <boost/callable_traits/function_type.hpp>``
|
|
||||||
[heading Definition]
|
|
||||||
*/
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
using function_type_t = //see below
|
|
||||||
//<-
|
|
||||||
detail::try_but_fail_if_invalid<typename detail::traits<
|
|
||||||
detail::shallow_decay<T>>::function_type,
|
|
||||||
cannot_determine_parameters_for_this_type>;
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
template<typename T, typename = std::false_type>
|
|
||||||
struct function_type_impl {};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct function_type_impl <T, typename std::is_same<
|
|
||||||
function_type_t<T>, detail::dummy>::type>
|
|
||||||
{
|
|
||||||
using type = function_type_t<T>;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
//->
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct function_type : detail::function_type_impl<T> {};
|
|
||||||
|
|
||||||
//<-
|
|
||||||
}} // namespace boost::callable_traits
|
|
||||||
//->
|
|
||||||
|
|
||||||
/*`
|
|
||||||
[heading Constraints]
|
|
||||||
* `T` must be one of the following:
|
|
||||||
* function
|
|
||||||
* function pointer
|
|
||||||
* function reference
|
|
||||||
* member function pointer
|
|
||||||
* member data pointer
|
|
||||||
* user-defined type with a non-overloaded `operator()`
|
|
||||||
* type of a non-generic lambda
|
|
||||||
|
|
||||||
[heading Behavior]
|
|
||||||
* When the constraints are violated, a substitution failure occurs.
|
|
||||||
* When `T` is a function, the aliased type is identical to `T`, except that the aliased function type will not have member qualifiers or the `transaction_safe` specifier.
|
|
||||||
* When `T` is a function pointer, the aliased type is equivalent to `std::remove_pointer_t<T>`.
|
|
||||||
* When `T` is a function reference, the aliased type is equivalent to `std::remove_reference_t<T>`.
|
|
||||||
* When `T` is a function object, the aliased type is a function type with the same return type and parameter list as `T`'s `operator()`.
|
|
||||||
* When `T` is a member function pointer, the aliased type is a function type with the same return type as `T`, and the first parameter is a reference to the parent class of `T`, qualified according to the member qualifiers on `T`. The subsequent parameters, if any, are the parameter types of `T`.
|
|
||||||
* When `T` is a member data pointer, the aliased type is a function type returning the underlying member type of `T`, taking a single parameter, which is a `const` reference to the parent type of `T`.
|
|
||||||
* In all cases, the aliased function type will not have member qualifiers, and will not have the `transaction_safe` specifier.
|
|
||||||
|
|
||||||
[heading Input/Output Examples]
|
|
||||||
[table
|
|
||||||
[[`T`] [`function_type_t<T>`]]
|
|
||||||
[[`void(int)`] [`void(int)`]]
|
|
||||||
[[`void(int) const`] [`void(int)`]]
|
|
||||||
[[`void(int) transaction_safe`] [`void(int)`]]
|
|
||||||
[[`void(*const &)(int)`] [`void(int)`]]
|
|
||||||
[[`void(&)(int)`] [`void(int)`]]
|
|
||||||
[[`void(* volatile)()`] [`void()`]]
|
|
||||||
[[`int(foo::*)(int)`] [`int(foo&, int)`]]
|
|
||||||
[[`int(foo::*)(int) const`] [`int(const foo&, int)`]]
|
|
||||||
[[`void(foo::*)() volatile &&`] [`void(volatile foo&&)`]]
|
|
||||||
[[`int foo::*`] [`int(const foo&)`]]
|
|
||||||
[[`const int foo::*`] [`int(const foo&)`]]
|
|
||||||
[[`int`] [(substitution failure)]]
|
|
||||||
]
|
|
||||||
|
|
||||||
[heading Example Program]
|
|
||||||
[import ../example/function_type.cpp]
|
|
||||||
[function_type]
|
|
||||||
[endsect]
|
|
||||||
*/
|
|
||||||
//]
|
|
||||||
|
|
||||||
#endif
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user