externals: Remove mp and replace uses with mcl
This commit is contained in:
parent
f642637971
commit
de4154aa18
60 changed files with 90 additions and 1502 deletions
7
externals/CMakeLists.txt
vendored
7
externals/CMakeLists.txt
vendored
|
@ -19,10 +19,11 @@ if (NOT TARGET fmt AND NOT TARGET fmt::fmt)
|
||||||
add_subdirectory(fmt)
|
add_subdirectory(fmt)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# mp
|
# mcl
|
||||||
|
|
||||||
add_library(mp INTERFACE)
|
if (NOT TARGET merry::mcl)
|
||||||
target_include_directories(mp INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/mp/include>)
|
add_subdirectory(mcl)
|
||||||
|
endif()
|
||||||
|
|
||||||
# robin-map
|
# robin-map
|
||||||
|
|
||||||
|
|
6
externals/README.md
vendored
6
externals/README.md
vendored
|
@ -4,7 +4,7 @@ This repository uses subtrees to manage some of its externals.
|
||||||
|
|
||||||
```
|
```
|
||||||
git remote add externals-fmt https://github.com/fmtlib/fmt.git --no-tags
|
git remote add externals-fmt https://github.com/fmtlib/fmt.git --no-tags
|
||||||
git remote add externals-mp https://github.com/MerryMage/mp.git --no-tags
|
git remote add externals-mcl https://github.com/merryhime/mcl.git --no-tags
|
||||||
git remote add externals-robin-map https://github.com/Tessil/robin-map.git --no-tags
|
git remote add externals-robin-map https://github.com/Tessil/robin-map.git --no-tags
|
||||||
git remote add externals-vixl https://git.linaro.org/arm/vixl.git --no-tags
|
git remote add externals-vixl https://git.linaro.org/arm/vixl.git --no-tags
|
||||||
git remote add externals-xbyak https://github.com/herumi/xbyak.git --no-tags
|
git remote add externals-xbyak https://github.com/herumi/xbyak.git --no-tags
|
||||||
|
@ -18,14 +18,14 @@ Change `<ref>` to refer to the appropriate git reference.
|
||||||
|
|
||||||
```
|
```
|
||||||
git fetch externals-fmt
|
git fetch externals-fmt
|
||||||
git fetch externals-mp
|
git fetch externals-mcl
|
||||||
git fetch externals-robin-map
|
git fetch externals-robin-map
|
||||||
git fetch externals-vixl
|
git fetch externals-vixl
|
||||||
git fetch externals-xbyak
|
git fetch externals-xbyak
|
||||||
git fetch externals-zycore
|
git fetch externals-zycore
|
||||||
git fetch externals-zydis
|
git fetch externals-zydis
|
||||||
git subtree pull --squash --prefix=externals/fmt externals-fmt <ref>
|
git subtree pull --squash --prefix=externals/fmt externals-fmt <ref>
|
||||||
git subtree pull --squash --prefix=externals/mp externals-mp <ref>
|
git subtree pull --squash --prefix=externals/mcl externals-mcl <ref>
|
||||||
git subtree pull --squash --prefix=externals/robin-map externals-robin-map <ref>
|
git subtree pull --squash --prefix=externals/robin-map externals-robin-map <ref>
|
||||||
git subtree pull --squash --prefix=externals/vixl/vixl externals-vixl <ref>
|
git subtree pull --squash --prefix=externals/vixl/vixl externals-vixl <ref>
|
||||||
git subtree pull --squash --prefix=externals/xbyak externals-xbyak <ref>
|
git subtree pull --squash --prefix=externals/xbyak externals-xbyak <ref>
|
||||||
|
|
19
externals/mp/.travis.yml
vendored
19
externals/mp/.travis.yml
vendored
|
@ -1,19 +0,0 @@
|
||||||
language: cpp
|
|
||||||
os: linux
|
|
||||||
|
|
||||||
matrix:
|
|
||||||
- compiler: clang
|
|
||||||
env: CXX=clang
|
|
||||||
dist: bionic
|
|
||||||
- compiler: g++-8
|
|
||||||
env: CXX=g++-8
|
|
||||||
addons:
|
|
||||||
apt:
|
|
||||||
sources:
|
|
||||||
- ubuntu-toolchain-r-test
|
|
||||||
packages:
|
|
||||||
- g++-8
|
|
||||||
|
|
||||||
script:
|
|
||||||
- $CXX --version
|
|
||||||
- $CXX -I./include -std=c++17 -Wall -Wextra -Wcast-qual -pedantic -pedantic-errors -Werror tests/all_tests.cpp
|
|
12
externals/mp/LICENSE-0BSD
vendored
12
externals/mp/LICENSE-0BSD
vendored
|
@ -1,12 +0,0 @@
|
||||||
Copyright (C) 2017 MerryMage
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for
|
|
||||||
any purpose with or without fee is hereby granted.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
|
||||||
AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
|
||||||
OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
122
externals/mp/README.md
vendored
122
externals/mp/README.md
vendored
|
@ -1,122 +0,0 @@
|
||||||
mp
|
|
||||||
===
|
|
||||||
|
|
||||||
A small, 0BSD-licensed metaprogramming library for C++17.
|
|
||||||
|
|
||||||
This is intended to be a lightweight and easy to understand implementation of a subset of useful metaprogramming utilities.
|
|
||||||
|
|
||||||
Usage
|
|
||||||
-----
|
|
||||||
|
|
||||||
Just add the `include` directory to your include path. That's it.
|
|
||||||
|
|
||||||
`typelist`
|
|
||||||
----------
|
|
||||||
|
|
||||||
A `mp::list` is a list of types. This set of headers provide metafunctions for manipulating lists of types.
|
|
||||||
|
|
||||||
### Constructor
|
|
||||||
|
|
||||||
* `mp::list`: Constructs a list.
|
|
||||||
* `mp::lift_sequence`: Lifts a value sequence into a list. Intended for use on `std::integral_sequence`.
|
|
||||||
|
|
||||||
### Element access
|
|
||||||
|
|
||||||
* `mp::get`: Gets a numbered element of a list.
|
|
||||||
* `mp::head`: Gets the first element of a list.
|
|
||||||
* `mp::tail`: Gets all-but-the-first-element as a list.
|
|
||||||
|
|
||||||
### Properties
|
|
||||||
|
|
||||||
* `mp::length`: Gets the length of a list.
|
|
||||||
* `mp::contains`: Determines if this list contains a specified element.
|
|
||||||
|
|
||||||
### Modifiers
|
|
||||||
|
|
||||||
* `mp::append`: Constructs a list with the provided elements appended to it.
|
|
||||||
* `mp::prepend`: Constructs a list with the provided elements prepended to it.
|
|
||||||
|
|
||||||
### Operations
|
|
||||||
|
|
||||||
* `mp::concat`: Concantenates multiple lists together.
|
|
||||||
* `mp::cartesian_product`: Construct a list containing the [cartesian product](https://en.wikipedia.org/wiki/Cartesian_product) of the provided lists.
|
|
||||||
|
|
||||||
### Conversions
|
|
||||||
|
|
||||||
* `mp::lower_to_tuple`: This operation only works on a list solely containing metavalues. Results in a `std::tuple` with equivalent values.
|
|
||||||
|
|
||||||
|
|
||||||
`metavalue`
|
|
||||||
-----------
|
|
||||||
|
|
||||||
A metavalue is a type of template `std::integral_constant`.
|
|
||||||
|
|
||||||
### Constants
|
|
||||||
|
|
||||||
* mp::true_type: Aliases to [`std::true_type`](https://en.cppreference.com/w/cpp/types/integral_constant)
|
|
||||||
* mp::false_type: Aliases to [`mp::false_type`](https://en.cppreference.com/w/cpp/types/integral_constant)
|
|
||||||
|
|
||||||
### Constructor
|
|
||||||
|
|
||||||
* mp::value: Aliases to [`std::integral_constant`](https://en.cppreference.com/w/cpp/types/integral_constant)
|
|
||||||
* mp::bool_value: Aliases to [`std::bool_constant`](https://en.cppreference.com/w/cpp/types/integral_constant)
|
|
||||||
* mp::size_value: Constructs a metavalue with value of type std::size_t
|
|
||||||
* `mp::lift_value`: Lifts a value of any arbitrary type to become a metavalue
|
|
||||||
|
|
||||||
### Conversions
|
|
||||||
|
|
||||||
* `mp::value_cast`
|
|
||||||
|
|
||||||
### Operations
|
|
||||||
|
|
||||||
* `mp::value_equal`: Compares value equality, ignores type. Use `std::is_same` for strict comparison.
|
|
||||||
* `mp::logic_if`: Like std::conditional but has a bool metavalue as first argument.
|
|
||||||
* `mp::bit_not`: Bitwise not
|
|
||||||
* `mp::bit_and`: Bitwise and
|
|
||||||
* `mp::bit_or`: Bitwise or
|
|
||||||
* `mp::bit_xor`: Bitwise xor
|
|
||||||
* `mp::logic_not`: Logical not
|
|
||||||
* `mp::logic_and`: Logical conjunction (no short circuiting, always results in a mp:bool_value)
|
|
||||||
* `mp::logic_or`: Logical disjunction (no short circuiting, always results in a mp:bool_value)
|
|
||||||
* `mp::conjunction`: Logical conjunction (with short circuiting, preserves type)
|
|
||||||
* `mp::disjunction`: Logical disjunction (with short circuiting, preserves type)
|
|
||||||
* `mp::sum`: Sum of values
|
|
||||||
* `mp::product`: Product of values
|
|
||||||
|
|
||||||
`metafunction`
|
|
||||||
--------------
|
|
||||||
|
|
||||||
* `std::void_t`: Always returns `void`.
|
|
||||||
* `mp::identity`: Identity metafunction. Can be used to establish a non-deduced context. See also C++20 `std::type_identity`.
|
|
||||||
* `mp::apply`: Invoke a provided metafunction with arguments specified in a list.
|
|
||||||
* `mp::map`: Apply a provided metafunction to each element of a list.
|
|
||||||
* `mp::bind`: Curry a metafunction. A macro `MM_MP_BIND` is provided to make this a little prettier.
|
|
||||||
|
|
||||||
`traits`
|
|
||||||
--------
|
|
||||||
|
|
||||||
Type traits not in the standard library.
|
|
||||||
|
|
||||||
### `function_info`
|
|
||||||
|
|
||||||
* `mp::parameter_count_v`: Number of parameters a function has
|
|
||||||
* `mp::parameter_list`: Get a typelist of the parameter types
|
|
||||||
* `mp::get_parameter`: Get the type of a parameter by index
|
|
||||||
* `mp::equivalent_function_type`: Get an equivalent function type (for MFPs this does not include the class)
|
|
||||||
* `mp::equivalent_function_type_with_class`: Get an equivalent function type with explicit `this` argument (MFPs only)
|
|
||||||
* `mp::return_type`: Return type of the function
|
|
||||||
* `mp::class_type`: Only valid for member function pointer types. Gets the class the member function is associated with.
|
|
||||||
|
|
||||||
### `integer_of_size`
|
|
||||||
|
|
||||||
* `mp::signed_integer_of_size`: Gets a signed integer of the specified bit-size (if it exists)
|
|
||||||
* `mp::unsigned_integer_of_size`: Gets an unsigned integer of the specified bit-size (if it exists)
|
|
||||||
|
|
||||||
### Misc
|
|
||||||
|
|
||||||
* `mp::is_instance_of_template`: Checks if a type is an instance of a template class.
|
|
||||||
|
|
||||||
License
|
|
||||||
-------
|
|
||||||
|
|
||||||
Please see [LICENSE-0BSD](LICENSE-0BSD).
|
|
26
externals/mp/include/mp/metafunction/apply.h
vendored
26
externals/mp/include/mp/metafunction/apply.h
vendored
|
@ -1,26 +0,0 @@
|
||||||
/* This file is part of the mp project.
|
|
||||||
* Copyright (c) 2017 MerryMage
|
|
||||||
* SPDX-License-Identifier: 0BSD
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
namespace mp {
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
template<template<class...> class F, class L>
|
|
||||||
struct apply_impl;
|
|
||||||
|
|
||||||
template<template<class...> class F, template<class...> class LT, class... Es>
|
|
||||||
struct apply_impl<F, LT<Es...>> {
|
|
||||||
using type = F<Es...>;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
/// Invokes metafunction F where the arguments are all the members of list L
|
|
||||||
template<template<class...> class F, class L>
|
|
||||||
using apply = typename detail::apply_impl<F, L>::type;
|
|
||||||
|
|
||||||
} // namespace mp
|
|
19
externals/mp/include/mp/metafunction/bind.h
vendored
19
externals/mp/include/mp/metafunction/bind.h
vendored
|
@ -1,19 +0,0 @@
|
||||||
/* This file is part of the mp project.
|
|
||||||
* Copyright (c) 2017 MerryMage
|
|
||||||
* SPDX-License-Identifier: 0BSD
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
namespace mp {
|
|
||||||
|
|
||||||
/// Binds the first sizeof...(A) arguments of metafunction F with arguments A
|
|
||||||
template<template<class...> class F, class... As>
|
|
||||||
struct bind {
|
|
||||||
template<class... Rs>
|
|
||||||
using type = F<As..., Rs...>;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace mp
|
|
||||||
|
|
||||||
#define MM_MP_BIND(...) ::mp::bind<__VA_ARGS__>::template type
|
|
23
externals/mp/include/mp/metafunction/identity.h
vendored
23
externals/mp/include/mp/metafunction/identity.h
vendored
|
@ -1,23 +0,0 @@
|
||||||
/* This file is part of the mp project.
|
|
||||||
* Copyright (c) 2017 MerryMage
|
|
||||||
* SPDX-License-Identifier: 0BSD
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
namespace mp {
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
struct identity_impl {
|
|
||||||
using type = T;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
/// Identity metafunction
|
|
||||||
template<class T>
|
|
||||||
using identity = typename identity_impl<T>::type;
|
|
||||||
|
|
||||||
} // namespace mp
|
|
26
externals/mp/include/mp/metafunction/map.h
vendored
26
externals/mp/include/mp/metafunction/map.h
vendored
|
@ -1,26 +0,0 @@
|
||||||
/* This file is part of the mp project.
|
|
||||||
* Copyright (c) 2017 MerryMage
|
|
||||||
* SPDX-License-Identifier: 0BSD
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
namespace mp {
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
template<template<class...> class F, class L>
|
|
||||||
struct map_impl;
|
|
||||||
|
|
||||||
template<template<class...> class F, template<class...> class LT, class... Es>
|
|
||||||
struct map_impl<F, LT<Es...>> {
|
|
||||||
using type = LT<F<Es>...>;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
/// Applies each element of list L to metafunction F
|
|
||||||
template<template<class...> class F, class L>
|
|
||||||
using map = typename detail::map_impl<F, L>::type;
|
|
||||||
|
|
||||||
} // namespace mp
|
|
20
externals/mp/include/mp/metavalue/bit_and.h
vendored
20
externals/mp/include/mp/metavalue/bit_and.h
vendored
|
@ -1,20 +0,0 @@
|
||||||
/* This file is part of the mp project.
|
|
||||||
* Copyright (c) 2020 MerryMage
|
|
||||||
* SPDX-License-Identifier: 0BSD
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <mp/metavalue/lift_value.h>
|
|
||||||
|
|
||||||
namespace mp {
|
|
||||||
|
|
||||||
/// Bitwise and of metavalues Vs
|
|
||||||
template<class... Vs>
|
|
||||||
using bit_and = lift_value<(Vs::value & ...)>;
|
|
||||||
|
|
||||||
/// Bitwise and of metavalues Vs
|
|
||||||
template<class... Vs>
|
|
||||||
constexpr auto bit_and_v = (Vs::value & ...);
|
|
||||||
|
|
||||||
} // namespace mp
|
|
20
externals/mp/include/mp/metavalue/bit_not.h
vendored
20
externals/mp/include/mp/metavalue/bit_not.h
vendored
|
@ -1,20 +0,0 @@
|
||||||
/* This file is part of the mp project.
|
|
||||||
* Copyright (c) 2020 MerryMage
|
|
||||||
* SPDX-License-Identifier: 0BSD
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <mp/metavalue/lift_value.h>
|
|
||||||
|
|
||||||
namespace mp {
|
|
||||||
|
|
||||||
/// Bitwise not of metavalue V
|
|
||||||
template<class V>
|
|
||||||
using bit_not = lift_value<~V::value>;
|
|
||||||
|
|
||||||
/// Bitwise not of metavalue V
|
|
||||||
template<class V>
|
|
||||||
constexpr auto bit_not_v = ~V::value;
|
|
||||||
|
|
||||||
} // namespace mp
|
|
20
externals/mp/include/mp/metavalue/bit_or.h
vendored
20
externals/mp/include/mp/metavalue/bit_or.h
vendored
|
@ -1,20 +0,0 @@
|
||||||
/* This file is part of the mp project.
|
|
||||||
* Copyright (c) 2020 MerryMage
|
|
||||||
* SPDX-License-Identifier: 0BSD
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <mp/metavalue/lift_value.h>
|
|
||||||
|
|
||||||
namespace mp {
|
|
||||||
|
|
||||||
/// Bitwise or of metavalues Vs
|
|
||||||
template<class... Vs>
|
|
||||||
using bit_or = lift_value<(Vs::value | ...)>;
|
|
||||||
|
|
||||||
/// Bitwise or of metavalues Vs
|
|
||||||
template<class... Vs>
|
|
||||||
constexpr auto bit_or_v = (Vs::value | ...);
|
|
||||||
|
|
||||||
} // namespace mp
|
|
20
externals/mp/include/mp/metavalue/bit_xor.h
vendored
20
externals/mp/include/mp/metavalue/bit_xor.h
vendored
|
@ -1,20 +0,0 @@
|
||||||
/* This file is part of the mp project.
|
|
||||||
* Copyright (c) 2020 MerryMage
|
|
||||||
* SPDX-License-Identifier: 0BSD
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <mp/metavalue/lift_value.h>
|
|
||||||
|
|
||||||
namespace mp {
|
|
||||||
|
|
||||||
/// Bitwise xor of metavalues Vs
|
|
||||||
template<class... Vs>
|
|
||||||
using bit_xor = lift_value<(Vs::value ^ ...)>;
|
|
||||||
|
|
||||||
/// Bitwise xor of metavalues Vs
|
|
||||||
template<class... Vs>
|
|
||||||
constexpr auto bit_xor_v = (Vs::value ^ ...);
|
|
||||||
|
|
||||||
} // namespace mp
|
|
43
externals/mp/include/mp/metavalue/conjunction.h
vendored
43
externals/mp/include/mp/metavalue/conjunction.h
vendored
|
@ -1,43 +0,0 @@
|
||||||
/* This file is part of the mp project.
|
|
||||||
* Copyright (c) 2020 MerryMage
|
|
||||||
* SPDX-License-Identifier: 0BSD
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <mp/metavalue/value.h>
|
|
||||||
#include <mp/metavalue/logic_if.h>
|
|
||||||
|
|
||||||
namespace mp {
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
template<class...>
|
|
||||||
struct conjunction_impl;
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct conjunction_impl<> {
|
|
||||||
using type = false_type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class V>
|
|
||||||
struct conjunction_impl<V> {
|
|
||||||
using type = V;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class V1, class... Vs>
|
|
||||||
struct conjunction_impl<V1, Vs...> {
|
|
||||||
using type = logic_if<V1, typename conjunction_impl<Vs...>::type, V1>;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
/// Conjunction of metavalues Vs with short-circuiting and type preservation.
|
|
||||||
template<class... Vs>
|
|
||||||
using conjunction = typename detail::conjunction_impl<Vs...>::type;
|
|
||||||
|
|
||||||
/// Conjunction of metavalues Vs with short-circuiting and type preservation.
|
|
||||||
template<class... Vs>
|
|
||||||
constexpr auto conjunction_v = conjunction<Vs...>::value;
|
|
||||||
|
|
||||||
} // namespace mp
|
|
43
externals/mp/include/mp/metavalue/disjunction.h
vendored
43
externals/mp/include/mp/metavalue/disjunction.h
vendored
|
@ -1,43 +0,0 @@
|
||||||
/* This file is part of the mp project.
|
|
||||||
* Copyright (c) 2020 MerryMage
|
|
||||||
* SPDX-License-Identifier: 0BSD
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <mp/metavalue/value.h>
|
|
||||||
#include <mp/metavalue/logic_if.h>
|
|
||||||
|
|
||||||
namespace mp {
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
template<class...>
|
|
||||||
struct disjunction_impl;
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct disjunction_impl<> {
|
|
||||||
using type = false_type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class V>
|
|
||||||
struct disjunction_impl<V> {
|
|
||||||
using type = V;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class V1, class... Vs>
|
|
||||||
struct disjunction_impl<V1, Vs...> {
|
|
||||||
using type = logic_if<V1, V1, typename disjunction_impl<Vs...>::type>;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
/// Disjunction of metavalues Vs with short-circuiting and type preservation.
|
|
||||||
template<class... Vs>
|
|
||||||
using disjunction = typename detail::disjunction_impl<Vs...>::type;
|
|
||||||
|
|
||||||
/// Disjunction of metavalues Vs with short-circuiting and type preservation.
|
|
||||||
template<class... Vs>
|
|
||||||
constexpr auto disjunction_v = disjunction<Vs...>::value;
|
|
||||||
|
|
||||||
} // namespace mp
|
|
16
externals/mp/include/mp/metavalue/lift_value.h
vendored
16
externals/mp/include/mp/metavalue/lift_value.h
vendored
|
@ -1,16 +0,0 @@
|
||||||
/* This file is part of the mp project.
|
|
||||||
* Copyright (c) 2017 MerryMage
|
|
||||||
* SPDX-License-Identifier: 0BSD
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <type_traits>
|
|
||||||
|
|
||||||
namespace mp {
|
|
||||||
|
|
||||||
/// Lifts a value into a type (a metavalue)
|
|
||||||
template<auto V>
|
|
||||||
using lift_value = std::integral_constant<decltype(V), V>;
|
|
||||||
|
|
||||||
} // namespace mp
|
|
20
externals/mp/include/mp/metavalue/logic_and.h
vendored
20
externals/mp/include/mp/metavalue/logic_and.h
vendored
|
@ -1,20 +0,0 @@
|
||||||
/* This file is part of the mp project.
|
|
||||||
* Copyright (c) 2020 MerryMage
|
|
||||||
* SPDX-License-Identifier: 0BSD
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <mp/metavalue/value.h>
|
|
||||||
|
|
||||||
namespace mp {
|
|
||||||
|
|
||||||
/// Logical conjunction of metavalues Vs without short-circuiting or type presevation.
|
|
||||||
template<class... Vs>
|
|
||||||
using logic_and = bool_value<(true && ... && Vs::value)>;
|
|
||||||
|
|
||||||
/// Logical conjunction of metavalues Vs without short-circuiting or type presevation.
|
|
||||||
template<class... Vs>
|
|
||||||
constexpr bool logic_and_v = (true && ... && Vs::value);
|
|
||||||
|
|
||||||
} // namespace mp
|
|
21
externals/mp/include/mp/metavalue/logic_if.h
vendored
21
externals/mp/include/mp/metavalue/logic_if.h
vendored
|
@ -1,21 +0,0 @@
|
||||||
/* This file is part of the mp project.
|
|
||||||
* Copyright (c) 2020 MerryMage
|
|
||||||
* SPDX-License-Identifier: 0BSD
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <type_traits>
|
|
||||||
#include <mp/metavalue/value.h>
|
|
||||||
|
|
||||||
namespace mp {
|
|
||||||
|
|
||||||
/// Conditionally select between types T and F based on boolean metavalue V
|
|
||||||
template<class V, class T, class F>
|
|
||||||
using logic_if = std::conditional_t<bool(V::value), T, F>;
|
|
||||||
|
|
||||||
/// Conditionally select between metavalues T and F based on boolean metavalue V
|
|
||||||
template<class V, class TV, class FV>
|
|
||||||
constexpr auto logic_if_v = logic_if<V, TV, FV>::value;
|
|
||||||
|
|
||||||
} // namespace mp
|
|
20
externals/mp/include/mp/metavalue/logic_not.h
vendored
20
externals/mp/include/mp/metavalue/logic_not.h
vendored
|
@ -1,20 +0,0 @@
|
||||||
/* This file is part of the mp project.
|
|
||||||
* Copyright (c) 2020 MerryMage
|
|
||||||
* SPDX-License-Identifier: 0BSD
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <mp/metavalue/value.h>
|
|
||||||
|
|
||||||
namespace mp {
|
|
||||||
|
|
||||||
/// Logical negation of metavalue V.
|
|
||||||
template<class V>
|
|
||||||
using logic_not = bool_value<!bool(V::value)>;
|
|
||||||
|
|
||||||
/// Logical negation of metavalue V.
|
|
||||||
template<class V>
|
|
||||||
constexpr bool logic_not_v = !bool(V::value);
|
|
||||||
|
|
||||||
} // namespace mp
|
|
20
externals/mp/include/mp/metavalue/logic_or.h
vendored
20
externals/mp/include/mp/metavalue/logic_or.h
vendored
|
@ -1,20 +0,0 @@
|
||||||
/* This file is part of the mp project.
|
|
||||||
* Copyright (c) 2020 MerryMage
|
|
||||||
* SPDX-License-Identifier: 0BSD
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <mp/metavalue/value.h>
|
|
||||||
|
|
||||||
namespace mp {
|
|
||||||
|
|
||||||
/// Logical disjunction of metavalues Vs without short-circuiting or type presevation.
|
|
||||||
template<class... Vs>
|
|
||||||
using logic_or = bool_value<(false || ... || Vs::value)>;
|
|
||||||
|
|
||||||
/// Logical disjunction of metavalues Vs without short-circuiting or type presevation.
|
|
||||||
template<class... Vs>
|
|
||||||
constexpr bool logic_or_v = (false || ... || Vs::value);
|
|
||||||
|
|
||||||
} // namespace mp
|
|
20
externals/mp/include/mp/metavalue/product.h
vendored
20
externals/mp/include/mp/metavalue/product.h
vendored
|
@ -1,20 +0,0 @@
|
||||||
/* This file is part of the mp project.
|
|
||||||
* Copyright (c) 2020 MerryMage
|
|
||||||
* SPDX-License-Identifier: 0BSD
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <mp/metavalue/lift_value.h>
|
|
||||||
|
|
||||||
namespace mp {
|
|
||||||
|
|
||||||
/// Product of metavalues Vs
|
|
||||||
template<class... Vs>
|
|
||||||
using product = lift_value<(Vs::value * ...)>;
|
|
||||||
|
|
||||||
/// Product of metavalues Vs
|
|
||||||
template<class... Vs>
|
|
||||||
constexpr auto product_v = (Vs::value * ...);
|
|
||||||
|
|
||||||
} // namespace mp
|
|
20
externals/mp/include/mp/metavalue/sum.h
vendored
20
externals/mp/include/mp/metavalue/sum.h
vendored
|
@ -1,20 +0,0 @@
|
||||||
/* This file is part of the mp project.
|
|
||||||
* Copyright (c) 2020 MerryMage
|
|
||||||
* SPDX-License-Identifier: 0BSD
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <mp/metavalue/lift_value.h>
|
|
||||||
|
|
||||||
namespace mp {
|
|
||||||
|
|
||||||
/// Sum of metavalues Vs
|
|
||||||
template<class... Vs>
|
|
||||||
using sum = lift_value<(Vs::value + ...)>;
|
|
||||||
|
|
||||||
/// Sum of metavalues Vs
|
|
||||||
template<class... Vs>
|
|
||||||
constexpr auto sum_v = (Vs::value + ...);
|
|
||||||
|
|
||||||
} // namespace mp
|
|
31
externals/mp/include/mp/metavalue/value.h
vendored
31
externals/mp/include/mp/metavalue/value.h
vendored
|
@ -1,31 +0,0 @@
|
||||||
/* This file is part of the mp project.
|
|
||||||
* Copyright (c) 2020 MerryMage
|
|
||||||
* SPDX-License-Identifier: 0BSD
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <cstddef>
|
|
||||||
#include <type_traits>
|
|
||||||
|
|
||||||
namespace mp {
|
|
||||||
|
|
||||||
/// A metavalue (of type VT and value v).
|
|
||||||
template<class VT, VT v>
|
|
||||||
using value = std::integral_constant<VT, v>;
|
|
||||||
|
|
||||||
/// A metavalue of type std::size_t (and value v).
|
|
||||||
template<std::size_t v>
|
|
||||||
using size_value = value<std::size_t, v>;
|
|
||||||
|
|
||||||
/// A metavalue of type bool (and value v). (Aliases to std::bool_constant.)
|
|
||||||
template<bool v>
|
|
||||||
using bool_value = value<bool, v>;
|
|
||||||
|
|
||||||
/// true metavalue (Aliases to std::true_type).
|
|
||||||
using true_type = bool_value<true>;
|
|
||||||
|
|
||||||
/// false metavalue (Aliases to std::false_type).
|
|
||||||
using false_type = bool_value<false>;
|
|
||||||
|
|
||||||
} // namespace mp
|
|
16
externals/mp/include/mp/metavalue/value_cast.h
vendored
16
externals/mp/include/mp/metavalue/value_cast.h
vendored
|
@ -1,16 +0,0 @@
|
||||||
/* This file is part of the mp project.
|
|
||||||
* Copyright (c) 2017 MerryMage
|
|
||||||
* SPDX-License-Identifier: 0BSD
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <type_traits>
|
|
||||||
|
|
||||||
namespace mp {
|
|
||||||
|
|
||||||
/// Casts a metavalue from one type to another
|
|
||||||
template<class T, class V>
|
|
||||||
using value_cast = std::integral_constant<T, static_cast<T>(V::value)>;
|
|
||||||
|
|
||||||
} // namespace mp
|
|
16
externals/mp/include/mp/metavalue/value_equal.h
vendored
16
externals/mp/include/mp/metavalue/value_equal.h
vendored
|
@ -1,16 +0,0 @@
|
||||||
/* This file is part of the mp project.
|
|
||||||
* Copyright (c) 2020 MerryMage
|
|
||||||
* SPDX-License-Identifier: 0BSD
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <type_traits>
|
|
||||||
|
|
||||||
namespace mp {
|
|
||||||
|
|
||||||
/// Do two metavalues contain the same value?
|
|
||||||
template<class V1, class V2>
|
|
||||||
using value_equal = std::bool_constant<V1::value == V2::value>;
|
|
||||||
|
|
||||||
} // namespace mp
|
|
20
externals/mp/include/mp/misc/argument_count.h
vendored
20
externals/mp/include/mp/misc/argument_count.h
vendored
|
@ -1,20 +0,0 @@
|
||||||
/* This file is part of the mp project.
|
|
||||||
* Copyright (c) 2017 MerryMage
|
|
||||||
* SPDX-License-Identifier: 0BSD
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <mp/metavalue/lift_value.h>
|
|
||||||
|
|
||||||
namespace mp {
|
|
||||||
|
|
||||||
/// Metafunction that returns the number of arguments it has
|
|
||||||
template<typename... Ts>
|
|
||||||
using argument_count = lift_value<sizeof...(Ts)>;
|
|
||||||
|
|
||||||
/// Metafunction that returns the number of arguments it has
|
|
||||||
template<typename... Ts>
|
|
||||||
constexpr auto argument_count_v = sizeof...(Ts);
|
|
||||||
|
|
||||||
} // namespace mp
|
|
71
externals/mp/include/mp/traits/function_info.h
vendored
71
externals/mp/include/mp/traits/function_info.h
vendored
|
@ -1,71 +0,0 @@
|
||||||
/* This file is part of the mp project.
|
|
||||||
* Copyright (c) 2017 MerryMage
|
|
||||||
* SPDX-License-Identifier: 0BSD
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <cstddef>
|
|
||||||
#include <tuple>
|
|
||||||
|
|
||||||
#include <mp/typelist/list.h>
|
|
||||||
|
|
||||||
namespace mp {
|
|
||||||
|
|
||||||
template<class F>
|
|
||||||
struct function_info : function_info<decltype(&F::operator())> {};
|
|
||||||
|
|
||||||
template<class R, class... As>
|
|
||||||
struct function_info<R(As...)> {
|
|
||||||
using return_type = R;
|
|
||||||
using parameter_list = list<As...>;
|
|
||||||
static constexpr std::size_t parameter_count = sizeof...(As);
|
|
||||||
|
|
||||||
using equivalent_function_type = R(As...);
|
|
||||||
|
|
||||||
template<std::size_t I>
|
|
||||||
struct parameter {
|
|
||||||
static_assert(I < parameter_count, "Non-existent parameter");
|
|
||||||
using type = std::tuple_element_t<I, std::tuple<As...>>;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class R, class... As>
|
|
||||||
struct function_info<R(*)(As...)> : function_info<R(As...)> {};
|
|
||||||
|
|
||||||
template<class C, class R, class... As>
|
|
||||||
struct function_info<R(C::*)(As...)> : function_info<R(As...)> {
|
|
||||||
using class_type = C;
|
|
||||||
|
|
||||||
using equivalent_function_type_with_class = R(C*, As...);
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class C, class R, class... As>
|
|
||||||
struct function_info<R(C::*)(As...) const> : function_info<R(As...)> {
|
|
||||||
using class_type = C;
|
|
||||||
|
|
||||||
using equivalent_function_type_with_class = R(C*, As...);
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class F>
|
|
||||||
constexpr size_t parameter_count_v = function_info<F>::parameter_count;
|
|
||||||
|
|
||||||
template<class F>
|
|
||||||
using parameter_list = typename function_info<F>::parameter_list;
|
|
||||||
|
|
||||||
template<class F, std::size_t I>
|
|
||||||
using get_parameter = typename function_info<F>::template parameter<I>::type;
|
|
||||||
|
|
||||||
template<class F>
|
|
||||||
using equivalent_function_type = typename function_info<F>::equivalent_function_type;
|
|
||||||
|
|
||||||
template<class F>
|
|
||||||
using equivalent_function_type_with_class = typename function_info<F>::equivalent_function_type_with_class;
|
|
||||||
|
|
||||||
template<class F>
|
|
||||||
using return_type = typename function_info<F>::return_type;
|
|
||||||
|
|
||||||
template<class F>
|
|
||||||
using class_type = typename function_info<F>::class_type;
|
|
||||||
|
|
||||||
} // namespace mp
|
|
50
externals/mp/include/mp/traits/integer_of_size.h
vendored
50
externals/mp/include/mp/traits/integer_of_size.h
vendored
|
@ -1,50 +0,0 @@
|
||||||
/* This file is part of the mp project.
|
|
||||||
* Copyright (c) 2018 MerryMage
|
|
||||||
* SPDX-License-Identifier: 0BSD
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <cstddef>
|
|
||||||
#include <cstdint>
|
|
||||||
|
|
||||||
namespace mp {
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
template<std::size_t size>
|
|
||||||
struct integer_of_size_impl{};
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct integer_of_size_impl<8> {
|
|
||||||
using unsigned_type = std::uint8_t;
|
|
||||||
using signed_type = std::int8_t;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct integer_of_size_impl<16> {
|
|
||||||
using unsigned_type = std::uint16_t;
|
|
||||||
using signed_type = std::int16_t;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct integer_of_size_impl<32> {
|
|
||||||
using unsigned_type = std::uint32_t;
|
|
||||||
using signed_type = std::int32_t;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct integer_of_size_impl<64> {
|
|
||||||
using unsigned_type = std::uint64_t;
|
|
||||||
using signed_type = std::int64_t;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
template<std::size_t size>
|
|
||||||
using unsigned_integer_of_size = typename detail::integer_of_size_impl<size>::unsigned_type;
|
|
||||||
|
|
||||||
template<std::size_t size>
|
|
||||||
using signed_integer_of_size = typename detail::integer_of_size_impl<size>::signed_type;
|
|
||||||
|
|
||||||
} // namespace mp
|
|
|
@ -1,23 +0,0 @@
|
||||||
/* This file is part of the mp project.
|
|
||||||
* Copyright (c) 2020 MerryMage
|
|
||||||
* SPDX-License-Identifier: 0BSD
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <mp/metavalue/value.h>
|
|
||||||
|
|
||||||
namespace mp {
|
|
||||||
|
|
||||||
/// Is type T an instance of template class C?
|
|
||||||
template <template <class...> class, class>
|
|
||||||
struct is_instance_of_template : false_type {};
|
|
||||||
|
|
||||||
template <template <class...> class C, class... As>
|
|
||||||
struct is_instance_of_template<C, C<As...>> : true_type {};
|
|
||||||
|
|
||||||
/// Is type T an instance of template class C?
|
|
||||||
template<template <class...> class C, class T>
|
|
||||||
constexpr bool is_instance_of_template_v = is_instance_of_template<C, T>::value;
|
|
||||||
|
|
||||||
} // namespace mp
|
|
26
externals/mp/include/mp/typelist/append.h
vendored
26
externals/mp/include/mp/typelist/append.h
vendored
|
@ -1,26 +0,0 @@
|
||||||
/* This file is part of the mp project.
|
|
||||||
* Copyright (c) 2017 MerryMage
|
|
||||||
* SPDX-License-Identifier: 0BSD
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
namespace mp {
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
template<class... L>
|
|
||||||
struct append_impl;
|
|
||||||
|
|
||||||
template<template<class...> class LT, class... E1s, class... E2s>
|
|
||||||
struct append_impl<LT<E1s...>, E2s...> {
|
|
||||||
using type = LT<E1s..., E2s...>;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
/// Append items E to list L
|
|
||||||
template<class L, class... Es>
|
|
||||||
using append = typename detail::append_impl<L, Es...>::type;
|
|
||||||
|
|
||||||
} // namespace mp
|
|
|
@ -1,50 +0,0 @@
|
||||||
/* This file is part of the mp project.
|
|
||||||
* Copyright (c) 2018 MerryMage
|
|
||||||
* SPDX-License-Identifier: 0BSD
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <mp/metafunction/bind.h>
|
|
||||||
#include <mp/metafunction/map.h>
|
|
||||||
#include <mp/typelist/append.h>
|
|
||||||
#include <mp/typelist/concat.h>
|
|
||||||
#include <mp/typelist/list.h>
|
|
||||||
|
|
||||||
namespace mp {
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
template<class... Ls>
|
|
||||||
struct cartesian_product_impl;
|
|
||||||
|
|
||||||
template<class RL>
|
|
||||||
struct cartesian_product_impl<RL> {
|
|
||||||
using type = RL;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<template<class...> class LT, class... REs, class... E2s>
|
|
||||||
struct cartesian_product_impl<LT<REs...>, LT<E2s...>> {
|
|
||||||
using type = concat<
|
|
||||||
map<MM_MP_BIND(append, REs), list<E2s...>>...
|
|
||||||
>;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class RL, class L2, class L3, class... Ls>
|
|
||||||
struct cartesian_product_impl<RL, L2, L3, Ls...> {
|
|
||||||
using type = typename cartesian_product_impl<
|
|
||||||
typename cartesian_product_impl<RL, L2>::type,
|
|
||||||
L3,
|
|
||||||
Ls...
|
|
||||||
>::type;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
/// Produces the cartesian product of a set of lists
|
|
||||||
/// For example:
|
|
||||||
/// cartesian_product<list<A, B>, list<D, E>> == list<list<A, D>, list<A, E>, list<B, D>, list<B, E>
|
|
||||||
template<typename L1, typename... Ls>
|
|
||||||
using cartesian_product = typename detail::cartesian_product_impl<map<list, L1>, Ls...>::type;
|
|
||||||
|
|
||||||
} // namespace mp
|
|
56
externals/mp/include/mp/typelist/concat.h
vendored
56
externals/mp/include/mp/typelist/concat.h
vendored
|
@ -1,56 +0,0 @@
|
||||||
/* This file is part of the mp project.
|
|
||||||
* Copyright (c) 2017 MerryMage
|
|
||||||
* SPDX-License-Identifier: 0BSD
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <mp/typelist/list.h>
|
|
||||||
|
|
||||||
namespace mp {
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
template<class... Ls>
|
|
||||||
struct concat_impl;
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct concat_impl<> {
|
|
||||||
using type = list<>;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class L>
|
|
||||||
struct concat_impl<L> {
|
|
||||||
using type = L;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<template<class...> class LT, class... E1s, class... E2s, class... Ls>
|
|
||||||
struct concat_impl<LT<E1s...>, LT<E2s...>, Ls...> {
|
|
||||||
using type = typename concat_impl<LT<E1s..., E2s...>, Ls...>::type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<template<class...> class LT,
|
|
||||||
class... E1s, class... E2s, class... E3s, class... E4s, class... E5s, class... E6s, class... E7s, class... E8s,
|
|
||||||
class... E9s, class... E10s, class... E11s, class... E12s, class... E13s, class... E14s, class... E15s, class... E16s,
|
|
||||||
class... Ls>
|
|
||||||
struct concat_impl<
|
|
||||||
LT<E1s...>, LT<E2s...>, LT<E3s...>, LT<E4s...>, LT<E5s...>, LT<E6s...>, LT<E7s...>, LT<E8s...>,
|
|
||||||
LT<E9s...>, LT<E10s...>, LT<E11s...>, LT<E12s...>, LT<E13s...>, LT<E14s...>, LT<E15s...>, LT<E16s...>,
|
|
||||||
Ls...>
|
|
||||||
{
|
|
||||||
using type = typename concat_impl<
|
|
||||||
LT<
|
|
||||||
E1s..., E2s..., E3s..., E4s..., E5s..., E6s..., E7s..., E8s...,
|
|
||||||
E9s..., E10s..., E11s..., E12s..., E13s..., E14s..., E15s..., E16s...
|
|
||||||
>,
|
|
||||||
Ls...
|
|
||||||
>::type;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
/// Concatenate lists together
|
|
||||||
template<class... Ls>
|
|
||||||
using concat = typename detail::concat_impl<Ls...>::type;
|
|
||||||
|
|
||||||
} // namespace mp
|
|
25
externals/mp/include/mp/typelist/contains.h
vendored
25
externals/mp/include/mp/typelist/contains.h
vendored
|
@ -1,25 +0,0 @@
|
||||||
/* This file is part of the mp project.
|
|
||||||
* Copyright (c) 2017 MerryMage
|
|
||||||
* SPDX-License-Identifier: 0BSD
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <mp/metavalue/value.h>
|
|
||||||
|
|
||||||
namespace mp {
|
|
||||||
|
|
||||||
/// Does list L contain an element which is same as type T?
|
|
||||||
template<class L, class T>
|
|
||||||
struct contains;
|
|
||||||
|
|
||||||
template<template<class...> class LT, class... Ts, class T>
|
|
||||||
struct contains<LT<Ts...>, T>
|
|
||||||
: bool_value<(false || ... || std::is_same_v<Ts, T>)>
|
|
||||||
{};
|
|
||||||
|
|
||||||
/// Does list L contain an element which is same as type T?
|
|
||||||
template<class L, class T>
|
|
||||||
constexpr bool contains_v = contains<L, T>::value;
|
|
||||||
|
|
||||||
} // namespace mp
|
|
34
externals/mp/include/mp/typelist/drop.h
vendored
34
externals/mp/include/mp/typelist/drop.h
vendored
|
@ -1,34 +0,0 @@
|
||||||
/* This file is part of the mp project.
|
|
||||||
* Copyright (c) 2020 MerryMage
|
|
||||||
* SPDX-License-Identifier: 0BSD
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <cstddef>
|
|
||||||
#include <type_traits>
|
|
||||||
|
|
||||||
namespace mp {
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
template<size_t N, class L>
|
|
||||||
struct drop_impl;
|
|
||||||
|
|
||||||
template<size_t N, template<class...> class LT>
|
|
||||||
struct drop_impl<N, LT<>> {
|
|
||||||
using type = LT<>;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<size_t N, template<class...> class LT, class E1, class... Es>
|
|
||||||
struct drop_impl<N, LT<E1, Es...>> {
|
|
||||||
using type = std::conditional_t<N == 0, LT<E1, Es...>, typename drop_impl<N - 1, LT<Es...>>::type>;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
/// Drops the first N elements of list L
|
|
||||||
template<std::size_t N, class L>
|
|
||||||
using drop = typename detail::drop_impl<N, L>::type;
|
|
||||||
|
|
||||||
} // namespace mp
|
|
19
externals/mp/include/mp/typelist/get.h
vendored
19
externals/mp/include/mp/typelist/get.h
vendored
|
@ -1,19 +0,0 @@
|
||||||
/* This file is part of the mp project.
|
|
||||||
* Copyright (c) 2017 MerryMage
|
|
||||||
* SPDX-License-Identifier: 0BSD
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <cstddef>
|
|
||||||
#include <tuple>
|
|
||||||
|
|
||||||
#include <mp/metafunction/apply.h>
|
|
||||||
|
|
||||||
namespace mp {
|
|
||||||
|
|
||||||
/// Get element I from list L
|
|
||||||
template<std::size_t I, class L>
|
|
||||||
using get = std::tuple_element_t<I, apply<std::tuple, L>>;
|
|
||||||
|
|
||||||
} // namespace mp
|
|
26
externals/mp/include/mp/typelist/head.h
vendored
26
externals/mp/include/mp/typelist/head.h
vendored
|
@ -1,26 +0,0 @@
|
||||||
/* This file is part of the mp project.
|
|
||||||
* Copyright (c) 2017 MerryMage
|
|
||||||
* SPDX-License-Identifier: 0BSD
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
namespace mp {
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
template<class L>
|
|
||||||
struct head_impl;
|
|
||||||
|
|
||||||
template<template<class...> class LT, class E1, class... Es>
|
|
||||||
struct head_impl<LT<E1, Es...>> {
|
|
||||||
using type = E1;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
/// Gets the tail/cdr/all-but-the-first-element of list L
|
|
||||||
template<class L>
|
|
||||||
using head = typename detail::head_impl<L>::type;
|
|
||||||
|
|
||||||
} // namespace mp
|
|
21
externals/mp/include/mp/typelist/length.h
vendored
21
externals/mp/include/mp/typelist/length.h
vendored
|
@ -1,21 +0,0 @@
|
||||||
/* This file is part of the mp project.
|
|
||||||
* Copyright (c) 2017 MerryMage
|
|
||||||
* SPDX-License-Identifier: 0BSD
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <mp/metafunction/apply.h>
|
|
||||||
#include <mp/misc/argument_count.h>
|
|
||||||
|
|
||||||
namespace mp {
|
|
||||||
|
|
||||||
/// Length of list L
|
|
||||||
template<class L>
|
|
||||||
using length = apply<argument_count, L>;
|
|
||||||
|
|
||||||
/// Length of list L
|
|
||||||
template<class L>
|
|
||||||
constexpr auto length_v = length<L>::value;
|
|
||||||
|
|
||||||
} // namespace mp
|
|
30
externals/mp/include/mp/typelist/lift_sequence.h
vendored
30
externals/mp/include/mp/typelist/lift_sequence.h
vendored
|
@ -1,30 +0,0 @@
|
||||||
/* This file is part of the mp project.
|
|
||||||
* Copyright (c) 2017 MerryMage
|
|
||||||
* SPDX-License-Identifier: 0BSD
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <type_traits>
|
|
||||||
|
|
||||||
#include <mp/typelist/list.h>
|
|
||||||
|
|
||||||
namespace mp {
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
template<class VL>
|
|
||||||
struct lift_sequence_impl;
|
|
||||||
|
|
||||||
template<class T, template <class, T...> class VLT, T... values>
|
|
||||||
struct lift_sequence_impl<VLT<T, values...>> {
|
|
||||||
using type = list<std::integral_constant<T, values>...>;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
/// Lifts values in value list VL to create a type list.
|
|
||||||
template<class VL>
|
|
||||||
using lift_sequence = typename detail::lift_sequence_impl<VL>::type;
|
|
||||||
|
|
||||||
} // namespace mp
|
|
14
externals/mp/include/mp/typelist/list.h
vendored
14
externals/mp/include/mp/typelist/list.h
vendored
|
@ -1,14 +0,0 @@
|
||||||
/* This file is part of the mp project.
|
|
||||||
* Copyright (c) 2017 MerryMage
|
|
||||||
* SPDX-License-Identifier: 0BSD
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
namespace mp {
|
|
||||||
|
|
||||||
/// Contains a list of types
|
|
||||||
template<class... E>
|
|
||||||
struct list {};
|
|
||||||
|
|
||||||
} // namespace mp
|
|
|
@ -1,25 +0,0 @@
|
||||||
/* This file is part of the mp project.
|
|
||||||
* Copyright (c) 2017 MerryMage
|
|
||||||
* SPDX-License-Identifier: 0BSD
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <tuple>
|
|
||||||
|
|
||||||
namespace mp {
|
|
||||||
|
|
||||||
/// Converts a list of metavalues to a tuple.
|
|
||||||
template<class L>
|
|
||||||
struct lower_to_tuple;
|
|
||||||
|
|
||||||
template<template<class...> class LT, class... Es>
|
|
||||||
struct lower_to_tuple<LT<Es...>> {
|
|
||||||
static constexpr auto value = std::make_tuple(static_cast<typename Es::value_type>(Es::value)...);
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Converts a list of metavalues to a tuple.
|
|
||||||
template<class L>
|
|
||||||
constexpr auto lower_to_tuple_v = lower_to_tuple<L>::value;
|
|
||||||
|
|
||||||
} // namespace mp
|
|
26
externals/mp/include/mp/typelist/prepend.h
vendored
26
externals/mp/include/mp/typelist/prepend.h
vendored
|
@ -1,26 +0,0 @@
|
||||||
/* This file is part of the mp project.
|
|
||||||
* Copyright (c) 2017 MerryMage
|
|
||||||
* SPDX-License-Identifier: 0BSD
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
namespace mp {
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
template<class... L>
|
|
||||||
struct prepend_impl;
|
|
||||||
|
|
||||||
template<template<class...> class LT, class... E1s, class... E2s>
|
|
||||||
struct prepend_impl<LT<E1s...>, E2s...> {
|
|
||||||
using type = LT<E2s..., E1s...>;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
/// Prepend items E to list L
|
|
||||||
template<class L, class... Es>
|
|
||||||
using prepend = typename detail::prepend_impl<L, Es...>::type;
|
|
||||||
|
|
||||||
} // namespace mp
|
|
26
externals/mp/include/mp/typelist/tail.h
vendored
26
externals/mp/include/mp/typelist/tail.h
vendored
|
@ -1,26 +0,0 @@
|
||||||
/* This file is part of the mp project.
|
|
||||||
* Copyright (c) 2017 MerryMage
|
|
||||||
* SPDX-License-Identifier: 0BSD
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
namespace mp {
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
template<class L>
|
|
||||||
struct tail_impl;
|
|
||||||
|
|
||||||
template<template<class...> class LT, class E1, class... Es>
|
|
||||||
struct tail_impl<LT<E1, Es...>> {
|
|
||||||
using type = LT<Es...>;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
/// Gets the first type of list L
|
|
||||||
template<class L>
|
|
||||||
using tail = typename detail::tail_impl<L>::type;
|
|
||||||
|
|
||||||
} // namespace mp
|
|
12
externals/mp/tests/all_tests.cpp
vendored
12
externals/mp/tests/all_tests.cpp
vendored
|
@ -1,12 +0,0 @@
|
||||||
/* This file is part of the mp project.
|
|
||||||
* Copyright (c) 2020 MerryMage
|
|
||||||
* SPDX-License-Identifier: 0BSD
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "metavalue_tests.h"
|
|
||||||
#include "traits_tests.h"
|
|
||||||
#include "typelist_tests.h"
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
93
externals/mp/tests/metavalue_tests.h
vendored
93
externals/mp/tests/metavalue_tests.h
vendored
|
@ -1,93 +0,0 @@
|
||||||
/* This file is part of the mp project.
|
|
||||||
* Copyright (c) 2020 MerryMage
|
|
||||||
* SPDX-License-Identifier: 0BSD
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <type_traits>
|
|
||||||
|
|
||||||
#include <mp/metavalue/bit_and.h>
|
|
||||||
#include <mp/metavalue/bit_not.h>
|
|
||||||
#include <mp/metavalue/bit_or.h>
|
|
||||||
#include <mp/metavalue/bit_xor.h>
|
|
||||||
#include <mp/metavalue/conjunction.h>
|
|
||||||
#include <mp/metavalue/disjunction.h>
|
|
||||||
#include <mp/metavalue/lift_value.h>
|
|
||||||
#include <mp/metavalue/logic_and.h>
|
|
||||||
#include <mp/metavalue/logic_not.h>
|
|
||||||
#include <mp/metavalue/logic_or.h>
|
|
||||||
#include <mp/metavalue/product.h>
|
|
||||||
#include <mp/metavalue/sum.h>
|
|
||||||
#include <mp/metavalue/value.h>
|
|
||||||
#include <mp/metavalue/value_cast.h>
|
|
||||||
#include <mp/metavalue/value_equal.h>
|
|
||||||
|
|
||||||
using namespace mp;
|
|
||||||
|
|
||||||
// bit_and
|
|
||||||
|
|
||||||
static_assert(bit_and<lift_value<3>, lift_value<1>>::value == 1);
|
|
||||||
|
|
||||||
// bit_not
|
|
||||||
|
|
||||||
static_assert(bit_not<lift_value<0>>::value == ~0);
|
|
||||||
|
|
||||||
// bit_or
|
|
||||||
|
|
||||||
static_assert(bit_or<lift_value<1>, lift_value<3>>::value == 3);
|
|
||||||
|
|
||||||
// bit_xor
|
|
||||||
|
|
||||||
static_assert(bit_xor<lift_value<1>, lift_value<3>>::value == 2);
|
|
||||||
|
|
||||||
// conjunction
|
|
||||||
|
|
||||||
static_assert(std::is_same_v<conjunction<std::true_type>, std::true_type>);
|
|
||||||
static_assert(std::is_same_v<conjunction<std::true_type, lift_value<0>>, lift_value<0>>);
|
|
||||||
static_assert(std::is_same_v<conjunction<std::true_type, lift_value<42>, std::true_type>, std::true_type>);
|
|
||||||
|
|
||||||
// disjunction
|
|
||||||
|
|
||||||
static_assert(std::is_same_v<disjunction<std::true_type>, std::true_type>);
|
|
||||||
static_assert(std::is_same_v<disjunction<std::false_type, lift_value<0>>, lift_value<0>>);
|
|
||||||
static_assert(std::is_same_v<disjunction<std::false_type, lift_value<42>, std::true_type>, lift_value<42>>);
|
|
||||||
|
|
||||||
// lift_value
|
|
||||||
|
|
||||||
static_assert(std::is_same_v<lift_value<3>, std::integral_constant<int, 3>>);
|
|
||||||
static_assert(std::is_same_v<lift_value<false>, std::false_type>);
|
|
||||||
|
|
||||||
// logic_and
|
|
||||||
|
|
||||||
static_assert(std::is_same_v<logic_and<>, std::true_type>);
|
|
||||||
static_assert(std::is_same_v<logic_and<std::true_type>, std::true_type>);
|
|
||||||
static_assert(std::is_same_v<logic_and<lift_value<1>>, std::true_type>);
|
|
||||||
static_assert(std::is_same_v<logic_and<std::true_type, std::false_type>, std::false_type>);
|
|
||||||
|
|
||||||
// logic_not
|
|
||||||
|
|
||||||
static_assert(std::is_same_v<logic_not<std::false_type>, std::true_type>);
|
|
||||||
|
|
||||||
// logic_or
|
|
||||||
|
|
||||||
static_assert(std::is_same_v<logic_or<>, std::false_type>);
|
|
||||||
static_assert(std::is_same_v<logic_or<std::true_type>, std::true_type>);
|
|
||||||
static_assert(std::is_same_v<logic_or<lift_value<0>>, std::false_type>);
|
|
||||||
static_assert(std::is_same_v<logic_or<std::true_type, std::false_type>, std::true_type>);
|
|
||||||
|
|
||||||
// product
|
|
||||||
|
|
||||||
static_assert(product<lift_value<1>, lift_value<2>, lift_value<3>, lift_value<4>>::value == 24);
|
|
||||||
|
|
||||||
// sum
|
|
||||||
|
|
||||||
static_assert(sum<lift_value<1>, lift_value<2>, lift_value<3>, lift_value<4>>::value == 10);
|
|
||||||
|
|
||||||
// value_cast
|
|
||||||
|
|
||||||
static_assert(std::is_same_v<value_cast<int, std::true_type>, std::integral_constant<int, 1>>);
|
|
||||||
|
|
||||||
// value_equal
|
|
||||||
|
|
||||||
static_assert(std::is_same_v<value_equal<std::true_type, std::integral_constant<int, 1>>, std::true_type>);
|
|
42
externals/mp/tests/traits_tests.h
vendored
42
externals/mp/tests/traits_tests.h
vendored
|
@ -1,42 +0,0 @@
|
||||||
/* This file is part of the mp project.
|
|
||||||
* Copyright (c) 2020 MerryMage
|
|
||||||
* SPDX-License-Identifier: 0BSD
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <tuple>
|
|
||||||
#include <type_traits>
|
|
||||||
|
|
||||||
#include <mp/traits/function_info.h>
|
|
||||||
#include <mp/traits/is_instance_of_template.h>
|
|
||||||
|
|
||||||
using namespace mp;
|
|
||||||
|
|
||||||
// function_info
|
|
||||||
|
|
||||||
struct Bar {
|
|
||||||
int frob(double a) { return a; }
|
|
||||||
};
|
|
||||||
|
|
||||||
static_assert(parameter_count_v<void()> == 0);
|
|
||||||
static_assert(parameter_count_v<void(int, int, int)> == 3);
|
|
||||||
static_assert(std::is_same_v<get_parameter<void(*)(bool, int, double), 2>, double>);
|
|
||||||
static_assert(std::is_same_v<equivalent_function_type<void(*)(bool, int, double)>, void(bool, int, double)>);
|
|
||||||
static_assert(std::is_same_v<return_type<void(*)(bool, int, double)>, void>);
|
|
||||||
static_assert(std::is_same_v<equivalent_function_type<decltype(&Bar::frob)>, int(double)>);
|
|
||||||
static_assert(std::is_same_v<class_type<decltype(&Bar::frob)>, Bar>);
|
|
||||||
|
|
||||||
// is_instance_of_template
|
|
||||||
|
|
||||||
template<class, class...>
|
|
||||||
class Foo {};
|
|
||||||
|
|
||||||
template<class, class>
|
|
||||||
class Pair {};
|
|
||||||
|
|
||||||
static_assert(is_instance_of_template_v<std::tuple, std::tuple<int, bool>>);
|
|
||||||
static_assert(!is_instance_of_template_v<std::tuple, bool>);
|
|
||||||
static_assert(is_instance_of_template_v<Foo, Foo<bool>>);
|
|
||||||
static_assert(is_instance_of_template_v<Pair, Pair<bool, int>>);
|
|
||||||
static_assert(!is_instance_of_template_v<Pair, Foo<bool, int>>);
|
|
113
externals/mp/tests/typelist_tests.h
vendored
113
externals/mp/tests/typelist_tests.h
vendored
|
@ -1,113 +0,0 @@
|
||||||
/* This file is part of the mp project.
|
|
||||||
* Copyright (c) 2020 MerryMage
|
|
||||||
* SPDX-License-Identifier: 0BSD
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <cstddef>
|
|
||||||
#include <tuple>
|
|
||||||
#include <type_traits>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
#include <mp/metavalue/value.h>
|
|
||||||
|
|
||||||
#include <mp/typelist/append.h>
|
|
||||||
#include <mp/typelist/cartesian_product.h>
|
|
||||||
#include <mp/typelist/concat.h>
|
|
||||||
#include <mp/typelist/contains.h>
|
|
||||||
#include <mp/typelist/drop.h>
|
|
||||||
#include <mp/typelist/get.h>
|
|
||||||
#include <mp/typelist/head.h>
|
|
||||||
#include <mp/typelist/length.h>
|
|
||||||
#include <mp/typelist/lift_sequence.h>
|
|
||||||
#include <mp/typelist/list.h>
|
|
||||||
#include <mp/typelist/lower_to_tuple.h>
|
|
||||||
#include <mp/typelist/prepend.h>
|
|
||||||
#include <mp/typelist/tail.h>
|
|
||||||
|
|
||||||
using namespace mp;
|
|
||||||
|
|
||||||
// append
|
|
||||||
|
|
||||||
static_assert(std::is_same_v<append<list<int, bool>, double>, list<int, bool, double>>);
|
|
||||||
static_assert(std::is_same_v<append<list<>, int, int>, list<int, int>>);
|
|
||||||
|
|
||||||
// cartesian_product
|
|
||||||
|
|
||||||
static_assert(
|
|
||||||
std::is_same_v<
|
|
||||||
cartesian_product<list<int, bool>, list<double, float>, list<char, unsigned>>,
|
|
||||||
list<
|
|
||||||
list<int, double, char>,
|
|
||||||
list<int, double, unsigned>,
|
|
||||||
list<int, float, char>,
|
|
||||||
list<int, float, unsigned>,
|
|
||||||
list<bool, double, char>,
|
|
||||||
list<bool, double, unsigned>,
|
|
||||||
list<bool, float, char>,
|
|
||||||
list<bool, float, unsigned>
|
|
||||||
>
|
|
||||||
>
|
|
||||||
);
|
|
||||||
|
|
||||||
// concat
|
|
||||||
|
|
||||||
static_assert(std::is_same_v<concat<list<int, bool>, list<double>>, list<int, bool, double>>);
|
|
||||||
static_assert(std::is_same_v<concat<list<>, list<int>, list<int>>, list<int, int>>);
|
|
||||||
|
|
||||||
// contains
|
|
||||||
|
|
||||||
static_assert(contains_v<list<int>, int>);
|
|
||||||
static_assert(!contains_v<list<>, int>);
|
|
||||||
static_assert(!contains_v<list<double>, int>);
|
|
||||||
static_assert(contains_v<list<double, int>, int>);
|
|
||||||
|
|
||||||
// drop
|
|
||||||
|
|
||||||
static_assert(std::is_same_v<list<>, drop<3, list<int, int>>>);
|
|
||||||
static_assert(std::is_same_v<list<>, drop<3, list<int, int, int>>>);
|
|
||||||
static_assert(std::is_same_v<list<int>, drop<3, list<int, int, int, int>>>);
|
|
||||||
static_assert(std::is_same_v<list<double>, drop<3, list<int, int, int, double>>>);
|
|
||||||
static_assert(std::is_same_v<list<int, double, bool>, drop<0, list<int, double, bool>>>);
|
|
||||||
|
|
||||||
// get
|
|
||||||
|
|
||||||
static_assert(std::is_same_v<get<0, list<int, double>>, int>);
|
|
||||||
static_assert(std::is_same_v<get<1, list<int, double>>, double>);
|
|
||||||
|
|
||||||
// head
|
|
||||||
|
|
||||||
static_assert(std::is_same_v<head<list<int, double>>, int>);
|
|
||||||
static_assert(std::is_same_v<head<list<int>>, int>);
|
|
||||||
|
|
||||||
// length
|
|
||||||
|
|
||||||
static_assert(length_v<list<>> == 0);
|
|
||||||
static_assert(length_v<list<int>> == 1);
|
|
||||||
static_assert(length_v<list<int, int, int>> == 3);
|
|
||||||
|
|
||||||
// lift_sequence
|
|
||||||
|
|
||||||
static_assert(
|
|
||||||
std::is_same_v<
|
|
||||||
lift_sequence<std::make_index_sequence<3>>,
|
|
||||||
list<size_value<0>, size_value<1>, size_value<2>>
|
|
||||||
>
|
|
||||||
);
|
|
||||||
|
|
||||||
// lower_to_tuple
|
|
||||||
|
|
||||||
static_assert(lower_to_tuple_v<list<size_value<0>, size_value<1>, size_value<2>>> == std::tuple<std::size_t, std::size_t, std::size_t>(0, 1, 2));
|
|
||||||
static_assert(lower_to_tuple_v<list<std::true_type, std::false_type>> == std::make_tuple(true, false));
|
|
||||||
|
|
||||||
// prepend
|
|
||||||
|
|
||||||
static_assert(std::is_same_v<prepend<list<int, int>, double>, list<double, int, int>>);
|
|
||||||
static_assert(std::is_same_v<prepend<list<>, double>, list<double>>);
|
|
||||||
static_assert(std::is_same_v<prepend<list<int>, double, bool>, list<double, bool, int>>);
|
|
||||||
|
|
||||||
// tail
|
|
||||||
|
|
||||||
static_assert(std::is_same_v<tail<list<int, double>>, list<double>>);
|
|
||||||
static_assert(std::is_same_v<tail<list<int>>, list<>>);
|
|
|
@ -388,7 +388,7 @@ target_link_libraries(dynarmic
|
||||||
PRIVATE
|
PRIVATE
|
||||||
$<BUILD_INTERFACE:boost>
|
$<BUILD_INTERFACE:boost>
|
||||||
$<BUILD_INTERFACE:fmt::fmt>
|
$<BUILD_INTERFACE:fmt::fmt>
|
||||||
$<BUILD_INTERFACE:mp>
|
$<BUILD_INTERFACE:merry::mcl>
|
||||||
tsl::robin_map
|
tsl::robin_map
|
||||||
$<BUILD_INTERFACE:xbyak>
|
$<BUILD_INTERFACE:xbyak>
|
||||||
$<BUILD_INTERFACE:Zydis>
|
$<BUILD_INTERFACE:Zydis>
|
||||||
|
@ -401,7 +401,7 @@ if (DYNARMIC_ENABLE_NO_EXECUTE_SUPPORT)
|
||||||
target_compile_definitions(dynarmic PRIVATE DYNARMIC_ENABLE_NO_EXECUTE_SUPPORT=1)
|
target_compile_definitions(dynarmic PRIVATE DYNARMIC_ENABLE_NO_EXECUTE_SUPPORT=1)
|
||||||
endif()
|
endif()
|
||||||
if (DYNARMIC_IGNORE_ASSERTS)
|
if (DYNARMIC_IGNORE_ASSERTS)
|
||||||
target_compile_definitions(dynarmic PRIVATE DYNARMIC_IGNORE_ASSERTS=1)
|
target_compile_definitions(dynarmic PRIVATE MCL_IGNORE_ASSERTS=1)
|
||||||
endif()
|
endif()
|
||||||
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||||
target_compile_definitions(dynarmic PRIVATE FMT_USE_WINDOWS_H=0)
|
target_compile_definitions(dynarmic PRIVATE FMT_USE_WINDOWS_H=0)
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
#include <fmt/ostream.h>
|
#include <fmt/ostream.h>
|
||||||
#include <mp/traits/integer_of_size.h>
|
#include <mcl/type_traits/integer_of_size.hpp>
|
||||||
#include <xbyak/xbyak.h>
|
#include <xbyak/xbyak.h>
|
||||||
|
|
||||||
#include "dynarmic/backend/x64/a32_emit_x64.h"
|
#include "dynarmic/backend/x64/a32_emit_x64.h"
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
#include <fmt/ostream.h>
|
#include <fmt/ostream.h>
|
||||||
#include <mp/traits/integer_of_size.h>
|
#include <mcl/type_traits/integer_of_size.hpp>
|
||||||
|
|
||||||
#include "dynarmic/backend/x64/a64_jitstate.h"
|
#include "dynarmic/backend/x64/a64_jitstate.h"
|
||||||
#include "dynarmic/backend/x64/abi.h"
|
#include "dynarmic/backend/x64/abi.h"
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
#include <fmt/ostream.h>
|
#include <fmt/ostream.h>
|
||||||
#include <mp/traits/integer_of_size.h>
|
#include <mcl/type_traits/integer_of_size.hpp>
|
||||||
#include <xbyak/xbyak.h>
|
#include <xbyak/xbyak.h>
|
||||||
|
|
||||||
#include "dynarmic/backend/x64/a64_emit_x64.h"
|
#include "dynarmic/backend/x64/a64_emit_x64.h"
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include <mp/traits/function_info.h>
|
#include <mcl/type_traits/function_info.hpp>
|
||||||
|
|
||||||
#include "dynarmic/backend/x64/callback.h"
|
#include "dynarmic/backend/x64/callback.h"
|
||||||
#include "dynarmic/common/cast_util.h"
|
#include "dynarmic/common/cast_util.h"
|
||||||
|
@ -32,18 +32,18 @@ struct ThunkBuilder<R (C::*)(Args...), mfp> {
|
||||||
} // namespace impl
|
} // namespace impl
|
||||||
|
|
||||||
template<auto mfp>
|
template<auto mfp>
|
||||||
ArgCallback DevirtualizeGeneric(mp::class_type<decltype(mfp)>* this_) {
|
ArgCallback DevirtualizeGeneric(mcl::class_type<decltype(mfp)>* this_) {
|
||||||
return ArgCallback{&impl::ThunkBuilder<decltype(mfp), mfp>::Thunk, reinterpret_cast<u64>(this_)};
|
return ArgCallback{&impl::ThunkBuilder<decltype(mfp), mfp>::Thunk, reinterpret_cast<u64>(this_)};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<auto mfp>
|
template<auto mfp>
|
||||||
ArgCallback DevirtualizeWindows(mp::class_type<decltype(mfp)>* this_) {
|
ArgCallback DevirtualizeWindows(mcl::class_type<decltype(mfp)>* this_) {
|
||||||
static_assert(sizeof(mfp) == 8);
|
static_assert(sizeof(mfp) == 8);
|
||||||
return ArgCallback{Common::BitCast<u64>(mfp), reinterpret_cast<u64>(this_)};
|
return ArgCallback{Common::BitCast<u64>(mfp), reinterpret_cast<u64>(this_)};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<auto mfp>
|
template<auto mfp>
|
||||||
ArgCallback DevirtualizeItanium(mp::class_type<decltype(mfp)>* this_) {
|
ArgCallback DevirtualizeItanium(mcl::class_type<decltype(mfp)>* this_) {
|
||||||
struct MemberFunctionPointer {
|
struct MemberFunctionPointer {
|
||||||
/// For a non-virtual function, this is a simple function pointer.
|
/// For a non-virtual function, this is a simple function pointer.
|
||||||
/// For a virtual function, it is (1 + virtual table offset in bytes).
|
/// For a virtual function, it is (1 + virtual table offset in bytes).
|
||||||
|
@ -65,7 +65,7 @@ ArgCallback DevirtualizeItanium(mp::class_type<decltype(mfp)>* this_) {
|
||||||
}
|
}
|
||||||
|
|
||||||
template<auto mfp>
|
template<auto mfp>
|
||||||
ArgCallback Devirtualize(mp::class_type<decltype(mfp)>* this_) {
|
ArgCallback Devirtualize(mcl::class_type<decltype(mfp)>* this_) {
|
||||||
#if defined(__APPLE__) || defined(linux) || defined(__linux) || defined(__linux__)
|
#if defined(__APPLE__) || defined(linux) || defined(__linux) || defined(__linux__)
|
||||||
return DevirtualizeItanium<mfp>(this_);
|
return DevirtualizeItanium<mfp>(this_);
|
||||||
#elif defined(__MINGW64__)
|
#elif defined(__MINGW64__)
|
||||||
|
|
|
@ -7,12 +7,12 @@
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include <mp/metavalue/lift_value.h>
|
#include <mcl/mp/metavalue/lift_value.hpp>
|
||||||
#include <mp/traits/integer_of_size.h>
|
#include <mcl/mp/typelist/cartesian_product.hpp>
|
||||||
#include <mp/typelist/cartesian_product.h>
|
#include <mcl/mp/typelist/lift_sequence.hpp>
|
||||||
#include <mp/typelist/lift_sequence.h>
|
#include <mcl/mp/typelist/list.hpp>
|
||||||
#include <mp/typelist/list.h>
|
#include <mcl/mp/typelist/lower_to_tuple.hpp>
|
||||||
#include <mp/typelist/lower_to_tuple.h>
|
#include <mcl/type_traits/integer_of_size.hpp>
|
||||||
|
|
||||||
#include "dynarmic/backend/x64/abi.h"
|
#include "dynarmic/backend/x64/abi.h"
|
||||||
#include "dynarmic/backend/x64/block_of_code.h"
|
#include "dynarmic/backend/x64/block_of_code.h"
|
||||||
|
@ -34,6 +34,7 @@
|
||||||
namespace Dynarmic::Backend::X64 {
|
namespace Dynarmic::Backend::X64 {
|
||||||
|
|
||||||
using namespace Xbyak::util;
|
using namespace Xbyak::util;
|
||||||
|
namespace mp = mcl::mp;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
@ -173,7 +174,7 @@ void PostProcessNaN(BlockOfCode& code, Xbyak::Xmm result, Xbyak::Xmm tmp) {
|
||||||
// We allow for the case where op1 and result are the same register. We do not read from op1 once result is written to.
|
// We allow for the case where op1 and result are the same register. We do not read from op1 once result is written to.
|
||||||
template<size_t fsize>
|
template<size_t fsize>
|
||||||
void EmitPostProcessNaNs(BlockOfCode& code, Xbyak::Xmm result, Xbyak::Xmm op1, Xbyak::Xmm op2, Xbyak::Reg64 tmp, Xbyak::Label end) {
|
void EmitPostProcessNaNs(BlockOfCode& code, Xbyak::Xmm result, Xbyak::Xmm op1, Xbyak::Xmm op2, Xbyak::Reg64 tmp, Xbyak::Label end) {
|
||||||
using FPT = mp::unsigned_integer_of_size<fsize>;
|
using FPT = mcl::unsigned_integer_of_size<fsize>;
|
||||||
constexpr FPT exponent_mask = FP::FPInfo<FPT>::exponent_mask;
|
constexpr FPT exponent_mask = FP::FPInfo<FPT>::exponent_mask;
|
||||||
constexpr FPT mantissa_msb = FP::FPInfo<FPT>::mantissa_msb;
|
constexpr FPT mantissa_msb = FP::FPInfo<FPT>::mantissa_msb;
|
||||||
constexpr u8 mantissa_msb_bit = static_cast<u8>(FP::FPInfo<FPT>::explicit_mantissa_width - 1);
|
constexpr u8 mantissa_msb_bit = static_cast<u8>(FP::FPInfo<FPT>::explicit_mantissa_width - 1);
|
||||||
|
@ -267,7 +268,7 @@ void FPTwoOp(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, Function fn) {
|
||||||
|
|
||||||
template<size_t fsize, typename Function>
|
template<size_t fsize, typename Function>
|
||||||
void FPThreeOp(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, Function fn) {
|
void FPThreeOp(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, Function fn) {
|
||||||
using FPT = mp::unsigned_integer_of_size<fsize>;
|
using FPT = mcl::unsigned_integer_of_size<fsize>;
|
||||||
|
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
|
|
||||||
|
@ -324,7 +325,7 @@ void FPThreeOp(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, Function fn)
|
||||||
|
|
||||||
template<size_t fsize>
|
template<size_t fsize>
|
||||||
void FPAbs(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
void FPAbs(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
using FPT = mp::unsigned_integer_of_size<fsize>;
|
using FPT = mcl::unsigned_integer_of_size<fsize>;
|
||||||
constexpr FPT non_sign_mask = FP::FPInfo<FPT>::sign_mask - FPT(1u);
|
constexpr FPT non_sign_mask = FP::FPInfo<FPT>::sign_mask - FPT(1u);
|
||||||
|
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
|
@ -350,7 +351,7 @@ void EmitX64::EmitFPAbs64(EmitContext& ctx, IR::Inst* inst) {
|
||||||
|
|
||||||
template<size_t fsize>
|
template<size_t fsize>
|
||||||
void FPNeg(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
void FPNeg(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
using FPT = mp::unsigned_integer_of_size<fsize>;
|
using FPT = mcl::unsigned_integer_of_size<fsize>;
|
||||||
constexpr FPT sign_mask = FP::FPInfo<FPT>::sign_mask;
|
constexpr FPT sign_mask = FP::FPInfo<FPT>::sign_mask;
|
||||||
|
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
|
@ -440,7 +441,7 @@ static void EmitFPMinMax(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
|
|
||||||
template<size_t fsize, bool is_max>
|
template<size_t fsize, bool is_max>
|
||||||
static void EmitFPMinMaxNumeric(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
static void EmitFPMinMaxNumeric(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
using FPT = mp::unsigned_integer_of_size<fsize>;
|
using FPT = mcl::unsigned_integer_of_size<fsize>;
|
||||||
constexpr FPT default_nan = FP::FPInfo<FPT>::DefaultNaN();
|
constexpr FPT default_nan = FP::FPInfo<FPT>::DefaultNaN();
|
||||||
constexpr u8 mantissa_msb_bit = static_cast<u8>(FP::FPInfo<FPT>::explicit_mantissa_width - 1);
|
constexpr u8 mantissa_msb_bit = static_cast<u8>(FP::FPInfo<FPT>::explicit_mantissa_width - 1);
|
||||||
|
|
||||||
|
@ -592,7 +593,7 @@ void EmitX64::EmitFPMul64(EmitContext& ctx, IR::Inst* inst) {
|
||||||
|
|
||||||
template<size_t fsize>
|
template<size_t fsize>
|
||||||
static void EmitFPMulAdd(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
static void EmitFPMulAdd(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
using FPT = mp::unsigned_integer_of_size<fsize>;
|
using FPT = mcl::unsigned_integer_of_size<fsize>;
|
||||||
|
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
|
|
||||||
|
@ -697,7 +698,7 @@ void EmitX64::EmitFPMulAdd64(EmitContext& ctx, IR::Inst* inst) {
|
||||||
|
|
||||||
template<size_t fsize>
|
template<size_t fsize>
|
||||||
static void EmitFPMulX(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
static void EmitFPMulX(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
using FPT = mp::unsigned_integer_of_size<fsize>;
|
using FPT = mcl::unsigned_integer_of_size<fsize>;
|
||||||
|
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
|
|
||||||
|
@ -755,7 +756,7 @@ void EmitX64::EmitFPMulX64(EmitContext& ctx, IR::Inst* inst) {
|
||||||
|
|
||||||
template<size_t fsize>
|
template<size_t fsize>
|
||||||
static void EmitFPRecipEstimate(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
static void EmitFPRecipEstimate(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
using FPT = mp::unsigned_integer_of_size<fsize>;
|
using FPT = mcl::unsigned_integer_of_size<fsize>;
|
||||||
|
|
||||||
if constexpr (fsize != 16) {
|
if constexpr (fsize != 16) {
|
||||||
if (ctx.HasOptimization(OptimizationFlag::Unsafe_ReducedErrorFP)) {
|
if (ctx.HasOptimization(OptimizationFlag::Unsafe_ReducedErrorFP)) {
|
||||||
|
@ -801,7 +802,7 @@ void EmitX64::EmitFPRecipEstimate64(EmitContext& ctx, IR::Inst* inst) {
|
||||||
|
|
||||||
template<size_t fsize>
|
template<size_t fsize>
|
||||||
static void EmitFPRecipExponent(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
static void EmitFPRecipExponent(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
using FPT = mp::unsigned_integer_of_size<fsize>;
|
using FPT = mcl::unsigned_integer_of_size<fsize>;
|
||||||
|
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
ctx.reg_alloc.HostCall(inst, args[0]);
|
ctx.reg_alloc.HostCall(inst, args[0]);
|
||||||
|
@ -824,7 +825,7 @@ void EmitX64::EmitFPRecipExponent64(EmitContext& ctx, IR::Inst* inst) {
|
||||||
|
|
||||||
template<size_t fsize>
|
template<size_t fsize>
|
||||||
static void EmitFPRecipStepFused(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
static void EmitFPRecipStepFused(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
using FPT = mp::unsigned_integer_of_size<fsize>;
|
using FPT = mcl::unsigned_integer_of_size<fsize>;
|
||||||
|
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
|
|
||||||
|
@ -949,7 +950,7 @@ static void EmitFPRound(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, siz
|
||||||
constexpr size_t fsize = std::get<0>(t);
|
constexpr size_t fsize = std::get<0>(t);
|
||||||
constexpr FP::RoundingMode rounding_mode = std::get<1>(t);
|
constexpr FP::RoundingMode rounding_mode = std::get<1>(t);
|
||||||
constexpr bool exact = std::get<2>(t);
|
constexpr bool exact = std::get<2>(t);
|
||||||
using InputSize = mp::unsigned_integer_of_size<fsize>;
|
using InputSize = mcl::unsigned_integer_of_size<fsize>;
|
||||||
|
|
||||||
return FP::FPRoundInt<InputSize>(static_cast<InputSize>(input), fpcr, rounding_mode, exact, fpsr);
|
return FP::FPRoundInt<InputSize>(static_cast<InputSize>(input), fpcr, rounding_mode, exact, fpsr);
|
||||||
})};
|
})};
|
||||||
|
@ -977,7 +978,7 @@ void EmitX64::EmitFPRoundInt64(EmitContext& ctx, IR::Inst* inst) {
|
||||||
|
|
||||||
template<size_t fsize>
|
template<size_t fsize>
|
||||||
static void EmitFPRSqrtEstimate(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
static void EmitFPRSqrtEstimate(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
using FPT = mp::unsigned_integer_of_size<fsize>;
|
using FPT = mcl::unsigned_integer_of_size<fsize>;
|
||||||
|
|
||||||
if constexpr (fsize != 16) {
|
if constexpr (fsize != 16) {
|
||||||
if (ctx.HasOptimization(OptimizationFlag::Unsafe_ReducedErrorFP)) {
|
if (ctx.HasOptimization(OptimizationFlag::Unsafe_ReducedErrorFP)) {
|
||||||
|
@ -1156,7 +1157,7 @@ void EmitX64::EmitFPRSqrtEstimate64(EmitContext& ctx, IR::Inst* inst) {
|
||||||
|
|
||||||
template<size_t fsize>
|
template<size_t fsize>
|
||||||
static void EmitFPRSqrtStepFused(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
static void EmitFPRSqrtStepFused(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
using FPT = mp::unsigned_integer_of_size<fsize>;
|
using FPT = mcl::unsigned_integer_of_size<fsize>;
|
||||||
|
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
|
|
||||||
|
@ -1589,7 +1590,7 @@ static void EmitFPToFixed(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
constexpr auto t = mp::lower_to_tuple_v<decltype(args)>;
|
constexpr auto t = mp::lower_to_tuple_v<decltype(args)>;
|
||||||
constexpr size_t fbits = std::get<0>(t);
|
constexpr size_t fbits = std::get<0>(t);
|
||||||
constexpr FP::RoundingMode rounding_mode = std::get<1>(t);
|
constexpr FP::RoundingMode rounding_mode = std::get<1>(t);
|
||||||
using FPT = mp::unsigned_integer_of_size<fsize>;
|
using FPT = mcl::unsigned_integer_of_size<fsize>;
|
||||||
|
|
||||||
return FP::FPToFixed<FPT>(isize, static_cast<FPT>(input), fbits, unsigned_, fpcr, rounding_mode, fpsr);
|
return FP::FPToFixed<FPT>(isize, static_cast<FPT>(input), fbits, unsigned_, fpcr, rounding_mode, fpsr);
|
||||||
})};
|
})};
|
||||||
|
|
|
@ -210,7 +210,7 @@ void AxxEmitX64::EmitExclusiveReadMemory(AxxEmitContext& ctx, IR::Inst* inst) {
|
||||||
const bool ordered = IsOrdered(args[1].GetImmediateAccType());
|
const bool ordered = IsOrdered(args[1].GetImmediateAccType());
|
||||||
|
|
||||||
if constexpr (bitsize != 128) {
|
if constexpr (bitsize != 128) {
|
||||||
using T = mp::unsigned_integer_of_size<bitsize>;
|
using T = mcl::unsigned_integer_of_size<bitsize>;
|
||||||
|
|
||||||
ctx.reg_alloc.HostCall(inst, {}, args[0]);
|
ctx.reg_alloc.HostCall(inst, {}, args[0]);
|
||||||
|
|
||||||
|
@ -275,7 +275,7 @@ void AxxEmitX64::EmitExclusiveWriteMemory(AxxEmitContext& ctx, IR::Inst* inst) {
|
||||||
code.mov(code.byte[r15 + offsetof(AxxJitState, exclusive_state)], u8(0));
|
code.mov(code.byte[r15 + offsetof(AxxJitState, exclusive_state)], u8(0));
|
||||||
code.mov(code.ABI_PARAM1, reinterpret_cast<u64>(&conf));
|
code.mov(code.ABI_PARAM1, reinterpret_cast<u64>(&conf));
|
||||||
if constexpr (bitsize != 128) {
|
if constexpr (bitsize != 128) {
|
||||||
using T = mp::unsigned_integer_of_size<bitsize>;
|
using T = mcl::unsigned_integer_of_size<bitsize>;
|
||||||
|
|
||||||
code.CallLambda(
|
code.CallLambda(
|
||||||
[](AxxUserConfig& conf, Axx::VAddr vaddr, T value) -> u32 {
|
[](AxxUserConfig& conf, Axx::VAddr vaddr, T value) -> u32 {
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
||||||
#include <mp/traits/integer_of_size.h>
|
#include <mcl/type_traits/integer_of_size.hpp>
|
||||||
|
|
||||||
#include "dynarmic/backend/x64/block_of_code.h"
|
#include "dynarmic/backend/x64/block_of_code.h"
|
||||||
#include "dynarmic/backend/x64/emit_x64.h"
|
#include "dynarmic/backend/x64/emit_x64.h"
|
||||||
|
@ -37,7 +37,7 @@ void EmitSignedSaturatedOp(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst)
|
||||||
Xbyak::Reg addend = ctx.reg_alloc.UseGpr(args[1]).changeBit(size);
|
Xbyak::Reg addend = ctx.reg_alloc.UseGpr(args[1]).changeBit(size);
|
||||||
Xbyak::Reg overflow = ctx.reg_alloc.ScratchGpr().changeBit(size);
|
Xbyak::Reg overflow = ctx.reg_alloc.ScratchGpr().changeBit(size);
|
||||||
|
|
||||||
constexpr u64 int_max = static_cast<u64>(std::numeric_limits<mp::signed_integer_of_size<size>>::max());
|
constexpr u64 int_max = static_cast<u64>(std::numeric_limits<mcl::signed_integer_of_size<size>>::max());
|
||||||
if constexpr (size < 64) {
|
if constexpr (size < 64) {
|
||||||
code.xor_(overflow.cvt32(), overflow.cvt32());
|
code.xor_(overflow.cvt32(), overflow.cvt32());
|
||||||
code.bt(result.cvt32(), size - 1);
|
code.bt(result.cvt32(), size - 1);
|
||||||
|
@ -81,7 +81,7 @@ void EmitUnsignedSaturatedOp(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst
|
||||||
Xbyak::Reg op_result = ctx.reg_alloc.UseScratchGpr(args[0]).changeBit(size);
|
Xbyak::Reg op_result = ctx.reg_alloc.UseScratchGpr(args[0]).changeBit(size);
|
||||||
Xbyak::Reg addend = ctx.reg_alloc.UseScratchGpr(args[1]).changeBit(size);
|
Xbyak::Reg addend = ctx.reg_alloc.UseScratchGpr(args[1]).changeBit(size);
|
||||||
|
|
||||||
constexpr u64 boundary = op == Op::Add ? std::numeric_limits<mp::unsigned_integer_of_size<size>>::max() : 0;
|
constexpr u64 boundary = op == Op::Add ? std::numeric_limits<mcl::unsigned_integer_of_size<size>>::max() : 0;
|
||||||
|
|
||||||
if constexpr (op == Op::Add) {
|
if constexpr (op == Op::Add) {
|
||||||
code.add(op_result, addend);
|
code.add(op_result, addend);
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
#include <mp/traits/function_info.h>
|
#include <mcl/type_traits/function_info.hpp>
|
||||||
#include <xbyak/xbyak.h>
|
#include <xbyak/xbyak.h>
|
||||||
|
|
||||||
#include "dynarmic/backend/x64/abi.h"
|
#include "dynarmic/backend/x64/abi.h"
|
||||||
|
@ -53,7 +53,7 @@ static void EmitAVXVectorOperation(BlockOfCode& code, EmitContext& ctx, IR::Inst
|
||||||
|
|
||||||
template<typename Lambda>
|
template<typename Lambda>
|
||||||
static void EmitOneArgumentFallback(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, Lambda lambda) {
|
static void EmitOneArgumentFallback(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, Lambda lambda) {
|
||||||
const auto fn = static_cast<mp::equivalent_function_type<Lambda>*>(lambda);
|
const auto fn = static_cast<mcl::equivalent_function_type<Lambda>*>(lambda);
|
||||||
constexpr u32 stack_space = 2 * 16;
|
constexpr u32 stack_space = 2 * 16;
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
const Xbyak::Xmm arg1 = ctx.reg_alloc.UseXmm(args[0]);
|
const Xbyak::Xmm arg1 = ctx.reg_alloc.UseXmm(args[0]);
|
||||||
|
@ -76,7 +76,7 @@ static void EmitOneArgumentFallback(BlockOfCode& code, EmitContext& ctx, IR::Ins
|
||||||
|
|
||||||
template<typename Lambda>
|
template<typename Lambda>
|
||||||
static void EmitOneArgumentFallbackWithSaturation(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, Lambda lambda) {
|
static void EmitOneArgumentFallbackWithSaturation(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, Lambda lambda) {
|
||||||
const auto fn = static_cast<mp::equivalent_function_type<Lambda>*>(lambda);
|
const auto fn = static_cast<mcl::equivalent_function_type<Lambda>*>(lambda);
|
||||||
constexpr u32 stack_space = 2 * 16;
|
constexpr u32 stack_space = 2 * 16;
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
const Xbyak::Xmm arg1 = ctx.reg_alloc.UseXmm(args[0]);
|
const Xbyak::Xmm arg1 = ctx.reg_alloc.UseXmm(args[0]);
|
||||||
|
@ -101,7 +101,7 @@ static void EmitOneArgumentFallbackWithSaturation(BlockOfCode& code, EmitContext
|
||||||
|
|
||||||
template<typename Lambda>
|
template<typename Lambda>
|
||||||
static void EmitTwoArgumentFallbackWithSaturation(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, Lambda lambda) {
|
static void EmitTwoArgumentFallbackWithSaturation(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, Lambda lambda) {
|
||||||
const auto fn = static_cast<mp::equivalent_function_type<Lambda>*>(lambda);
|
const auto fn = static_cast<mcl::equivalent_function_type<Lambda>*>(lambda);
|
||||||
constexpr u32 stack_space = 3 * 16;
|
constexpr u32 stack_space = 3 * 16;
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
const Xbyak::Xmm arg1 = ctx.reg_alloc.UseXmm(args[0]);
|
const Xbyak::Xmm arg1 = ctx.reg_alloc.UseXmm(args[0]);
|
||||||
|
@ -129,7 +129,7 @@ static void EmitTwoArgumentFallbackWithSaturation(BlockOfCode& code, EmitContext
|
||||||
|
|
||||||
template<typename Lambda>
|
template<typename Lambda>
|
||||||
static void EmitTwoArgumentFallback(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, Lambda lambda) {
|
static void EmitTwoArgumentFallback(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, Lambda lambda) {
|
||||||
const auto fn = static_cast<mp::equivalent_function_type<Lambda>*>(lambda);
|
const auto fn = static_cast<mcl::equivalent_function_type<Lambda>*>(lambda);
|
||||||
constexpr u32 stack_space = 3 * 16;
|
constexpr u32 stack_space = 3 * 16;
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
const Xbyak::Xmm arg1 = ctx.reg_alloc.UseXmm(args[0]);
|
const Xbyak::Xmm arg1 = ctx.reg_alloc.UseXmm(args[0]);
|
||||||
|
|
|
@ -9,13 +9,13 @@
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include <mp/metavalue/lift_value.h>
|
#include <mcl/mp/metavalue/lift_value.hpp>
|
||||||
#include <mp/traits/function_info.h>
|
#include <mcl/mp/typelist/cartesian_product.hpp>
|
||||||
#include <mp/traits/integer_of_size.h>
|
#include <mcl/mp/typelist/lift_sequence.hpp>
|
||||||
#include <mp/typelist/cartesian_product.h>
|
#include <mcl/mp/typelist/list.hpp>
|
||||||
#include <mp/typelist/lift_sequence.h>
|
#include <mcl/mp/typelist/lower_to_tuple.hpp>
|
||||||
#include <mp/typelist/list.h>
|
#include <mcl/type_traits/function_info.hpp>
|
||||||
#include <mp/typelist/lower_to_tuple.h>
|
#include <mcl/type_traits/integer_of_size.hpp>
|
||||||
|
|
||||||
#include "dynarmic/backend/x64/abi.h"
|
#include "dynarmic/backend/x64/abi.h"
|
||||||
#include "dynarmic/backend/x64/block_of_code.h"
|
#include "dynarmic/backend/x64/block_of_code.h"
|
||||||
|
@ -34,6 +34,7 @@
|
||||||
namespace Dynarmic::Backend::X64 {
|
namespace Dynarmic::Backend::X64 {
|
||||||
|
|
||||||
using namespace Xbyak::util;
|
using namespace Xbyak::util;
|
||||||
|
namespace mp = mcl::mp;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
@ -70,7 +71,7 @@ void MaybeStandardFPSCRValue(BlockOfCode& code, EmitContext& ctx, bool fpcr_cont
|
||||||
template<size_t fsize, template<typename> class Indexer, size_t narg>
|
template<size_t fsize, template<typename> class Indexer, size_t narg>
|
||||||
struct NaNHandler {
|
struct NaNHandler {
|
||||||
public:
|
public:
|
||||||
using FPT = mp::unsigned_integer_of_size<fsize>;
|
using FPT = mcl::unsigned_integer_of_size<fsize>;
|
||||||
|
|
||||||
using function_type = void (*)(std::array<VectorArray<FPT>, narg>&, FP::FPCR);
|
using function_type = void (*)(std::array<VectorArray<FPT>, narg>&, FP::FPCR);
|
||||||
|
|
||||||
|
@ -161,26 +162,26 @@ Xbyak::Address GetVectorOf(BlockOfCode& code) {
|
||||||
|
|
||||||
template<size_t fsize>
|
template<size_t fsize>
|
||||||
Xbyak::Address GetNaNVector(BlockOfCode& code) {
|
Xbyak::Address GetNaNVector(BlockOfCode& code) {
|
||||||
using FPT = mp::unsigned_integer_of_size<fsize>;
|
using FPT = mcl::unsigned_integer_of_size<fsize>;
|
||||||
return GetVectorOf<fsize, FP::FPInfo<FPT>::DefaultNaN()>(code);
|
return GetVectorOf<fsize, FP::FPInfo<FPT>::DefaultNaN()>(code);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t fsize>
|
template<size_t fsize>
|
||||||
Xbyak::Address GetNegativeZeroVector(BlockOfCode& code) {
|
Xbyak::Address GetNegativeZeroVector(BlockOfCode& code) {
|
||||||
using FPT = mp::unsigned_integer_of_size<fsize>;
|
using FPT = mcl::unsigned_integer_of_size<fsize>;
|
||||||
return GetVectorOf<fsize, FP::FPInfo<FPT>::Zero(true)>(code);
|
return GetVectorOf<fsize, FP::FPInfo<FPT>::Zero(true)>(code);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t fsize>
|
template<size_t fsize>
|
||||||
Xbyak::Address GetSmallestNormalVector(BlockOfCode& code) {
|
Xbyak::Address GetSmallestNormalVector(BlockOfCode& code) {
|
||||||
using FPT = mp::unsigned_integer_of_size<fsize>;
|
using FPT = mcl::unsigned_integer_of_size<fsize>;
|
||||||
constexpr FPT smallest_normal_number = FP::FPValue<FPT, false, FP::FPInfo<FPT>::exponent_min, 1>();
|
constexpr FPT smallest_normal_number = FP::FPValue<FPT, false, FP::FPInfo<FPT>::exponent_min, 1>();
|
||||||
return GetVectorOf<fsize, smallest_normal_number>(code);
|
return GetVectorOf<fsize, smallest_normal_number>(code);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t fsize, bool sign, int exponent, mp::unsigned_integer_of_size<fsize> value>
|
template<size_t fsize, bool sign, int exponent, mcl::unsigned_integer_of_size<fsize> value>
|
||||||
Xbyak::Address GetVectorOf(BlockOfCode& code) {
|
Xbyak::Address GetVectorOf(BlockOfCode& code) {
|
||||||
using FPT = mp::unsigned_integer_of_size<fsize>;
|
using FPT = mcl::unsigned_integer_of_size<fsize>;
|
||||||
return GetVectorOf<fsize, FP::FPValue<FPT, sign, exponent, value>()>(code);
|
return GetVectorOf<fsize, FP::FPValue<FPT, sign, exponent, value>()>(code);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -413,7 +414,7 @@ void EmitThreeOpVectorOperation(BlockOfCode& code, EmitContext& ctx, IR::Inst* i
|
||||||
|
|
||||||
template<typename Lambda>
|
template<typename Lambda>
|
||||||
void EmitTwoOpFallbackWithoutRegAlloc(BlockOfCode& code, EmitContext& ctx, Xbyak::Xmm result, Xbyak::Xmm arg1, Lambda lambda, bool fpcr_controlled) {
|
void EmitTwoOpFallbackWithoutRegAlloc(BlockOfCode& code, EmitContext& ctx, Xbyak::Xmm result, Xbyak::Xmm arg1, Lambda lambda, bool fpcr_controlled) {
|
||||||
const auto fn = static_cast<mp::equivalent_function_type<Lambda>*>(lambda);
|
const auto fn = static_cast<mcl::equivalent_function_type<Lambda>*>(lambda);
|
||||||
|
|
||||||
const u32 fpcr = ctx.FPCR(fpcr_controlled).Value();
|
const u32 fpcr = ctx.FPCR(fpcr_controlled).Value();
|
||||||
|
|
||||||
|
@ -448,7 +449,7 @@ void EmitTwoOpFallback(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, Lamb
|
||||||
|
|
||||||
template<typename Lambda>
|
template<typename Lambda>
|
||||||
void EmitThreeOpFallbackWithoutRegAlloc(BlockOfCode& code, EmitContext& ctx, Xbyak::Xmm result, Xbyak::Xmm arg1, Xbyak::Xmm arg2, Lambda lambda, bool fpcr_controlled) {
|
void EmitThreeOpFallbackWithoutRegAlloc(BlockOfCode& code, EmitContext& ctx, Xbyak::Xmm result, Xbyak::Xmm arg1, Xbyak::Xmm arg2, Lambda lambda, bool fpcr_controlled) {
|
||||||
const auto fn = static_cast<mp::equivalent_function_type<Lambda>*>(lambda);
|
const auto fn = static_cast<mcl::equivalent_function_type<Lambda>*>(lambda);
|
||||||
|
|
||||||
const u32 fpcr = ctx.FPCR(fpcr_controlled).Value();
|
const u32 fpcr = ctx.FPCR(fpcr_controlled).Value();
|
||||||
|
|
||||||
|
@ -502,7 +503,7 @@ void EmitThreeOpFallback(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, La
|
||||||
|
|
||||||
template<typename Lambda>
|
template<typename Lambda>
|
||||||
void EmitFourOpFallbackWithoutRegAlloc(BlockOfCode& code, EmitContext& ctx, Xbyak::Xmm result, Xbyak::Xmm arg1, Xbyak::Xmm arg2, Xbyak::Xmm arg3, Lambda lambda, bool fpcr_controlled) {
|
void EmitFourOpFallbackWithoutRegAlloc(BlockOfCode& code, EmitContext& ctx, Xbyak::Xmm result, Xbyak::Xmm arg1, Xbyak::Xmm arg2, Xbyak::Xmm arg3, Lambda lambda, bool fpcr_controlled) {
|
||||||
const auto fn = static_cast<mp::equivalent_function_type<Lambda>*>(lambda);
|
const auto fn = static_cast<mcl::equivalent_function_type<Lambda>*>(lambda);
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
constexpr u32 stack_space = 5 * 16;
|
constexpr u32 stack_space = 5 * 16;
|
||||||
|
@ -559,7 +560,7 @@ void EmitFourOpFallback(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, Lam
|
||||||
|
|
||||||
template<size_t fsize>
|
template<size_t fsize>
|
||||||
void FPVectorAbs(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
void FPVectorAbs(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
using FPT = mp::unsigned_integer_of_size<fsize>;
|
using FPT = mcl::unsigned_integer_of_size<fsize>;
|
||||||
constexpr FPT non_sign_mask = FP::FPInfo<FPT>::sign_mask - FPT(1u);
|
constexpr FPT non_sign_mask = FP::FPInfo<FPT>::sign_mask - FPT(1u);
|
||||||
constexpr u64 non_sign_mask64 = Common::Replicate<u64>(non_sign_mask, fsize);
|
constexpr u64 non_sign_mask64 = Common::Replicate<u64>(non_sign_mask, fsize);
|
||||||
|
|
||||||
|
@ -1065,7 +1066,7 @@ void EmitX64::EmitFPVectorMul64(EmitContext& ctx, IR::Inst* inst) {
|
||||||
|
|
||||||
template<size_t fsize>
|
template<size_t fsize>
|
||||||
void EmitFPVectorMulAdd(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
void EmitFPVectorMulAdd(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
using FPT = mp::unsigned_integer_of_size<fsize>;
|
using FPT = mcl::unsigned_integer_of_size<fsize>;
|
||||||
|
|
||||||
const auto fallback_fn = [](VectorArray<FPT>& result, const VectorArray<FPT>& addend, const VectorArray<FPT>& op1, const VectorArray<FPT>& op2, FP::FPCR fpcr, FP::FPSR& fpsr) {
|
const auto fallback_fn = [](VectorArray<FPT>& result, const VectorArray<FPT>& addend, const VectorArray<FPT>& op1, const VectorArray<FPT>& op2, FP::FPCR fpcr, FP::FPSR& fpsr) {
|
||||||
for (size_t i = 0; i < result.size(); i++) {
|
for (size_t i = 0; i < result.size(); i++) {
|
||||||
|
@ -1160,7 +1161,7 @@ void EmitX64::EmitFPVectorMulAdd64(EmitContext& ctx, IR::Inst* inst) {
|
||||||
|
|
||||||
template<size_t fsize>
|
template<size_t fsize>
|
||||||
static void EmitFPVectorMulX(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
static void EmitFPVectorMulX(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
using FPT = mp::unsigned_integer_of_size<fsize>;
|
using FPT = mcl::unsigned_integer_of_size<fsize>;
|
||||||
|
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
const bool fpcr_controlled = args[2].GetImmediateU1();
|
const bool fpcr_controlled = args[2].GetImmediateU1();
|
||||||
|
@ -1226,7 +1227,7 @@ void EmitX64::EmitFPVectorMulX64(EmitContext& ctx, IR::Inst* inst) {
|
||||||
|
|
||||||
template<size_t fsize>
|
template<size_t fsize>
|
||||||
void FPVectorNeg(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
void FPVectorNeg(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
using FPT = mp::unsigned_integer_of_size<fsize>;
|
using FPT = mcl::unsigned_integer_of_size<fsize>;
|
||||||
constexpr FPT sign_mask = FP::FPInfo<FPT>::sign_mask;
|
constexpr FPT sign_mask = FP::FPInfo<FPT>::sign_mask;
|
||||||
constexpr u64 sign_mask64 = Common::Replicate<u64>(sign_mask, fsize);
|
constexpr u64 sign_mask64 = Common::Replicate<u64>(sign_mask, fsize);
|
||||||
|
|
||||||
|
@ -1280,7 +1281,7 @@ void EmitX64::EmitFPVectorPairedAddLower64(EmitContext& ctx, IR::Inst* inst) {
|
||||||
|
|
||||||
template<size_t fsize>
|
template<size_t fsize>
|
||||||
static void EmitRecipEstimate(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
static void EmitRecipEstimate(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
using FPT = mp::unsigned_integer_of_size<fsize>;
|
using FPT = mcl::unsigned_integer_of_size<fsize>;
|
||||||
|
|
||||||
if constexpr (fsize != 16) {
|
if constexpr (fsize != 16) {
|
||||||
if (ctx.HasOptimization(OptimizationFlag::Unsafe_ReducedErrorFP)) {
|
if (ctx.HasOptimization(OptimizationFlag::Unsafe_ReducedErrorFP)) {
|
||||||
|
@ -1326,7 +1327,7 @@ void EmitX64::EmitFPVectorRecipEstimate64(EmitContext& ctx, IR::Inst* inst) {
|
||||||
|
|
||||||
template<size_t fsize>
|
template<size_t fsize>
|
||||||
static void EmitRecipStepFused(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
static void EmitRecipStepFused(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
using FPT = mp::unsigned_integer_of_size<fsize>;
|
using FPT = mcl::unsigned_integer_of_size<fsize>;
|
||||||
|
|
||||||
const auto fallback_fn = [](VectorArray<FPT>& result, const VectorArray<FPT>& op1, const VectorArray<FPT>& op2, FP::FPCR fpcr, FP::FPSR& fpsr) {
|
const auto fallback_fn = [](VectorArray<FPT>& result, const VectorArray<FPT>& op1, const VectorArray<FPT>& op2, FP::FPCR fpcr, FP::FPSR& fpsr) {
|
||||||
for (size_t i = 0; i < result.size(); i++) {
|
for (size_t i = 0; i < result.size(); i++) {
|
||||||
|
@ -1420,7 +1421,7 @@ void EmitX64::EmitFPVectorRecipStepFused64(EmitContext& ctx, IR::Inst* inst) {
|
||||||
|
|
||||||
template<size_t fsize>
|
template<size_t fsize>
|
||||||
void EmitFPVectorRoundInt(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
void EmitFPVectorRoundInt(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
using FPT = mp::unsigned_integer_of_size<fsize>;
|
using FPT = mcl::unsigned_integer_of_size<fsize>;
|
||||||
|
|
||||||
const auto rounding = static_cast<FP::RoundingMode>(inst->GetArg(1).GetU8());
|
const auto rounding = static_cast<FP::RoundingMode>(inst->GetArg(1).GetU8());
|
||||||
const bool exact = inst->GetArg(2).GetU1();
|
const bool exact = inst->GetArg(2).GetU1();
|
||||||
|
@ -1492,7 +1493,7 @@ void EmitX64::EmitFPVectorRoundInt64(EmitContext& ctx, IR::Inst* inst) {
|
||||||
|
|
||||||
template<size_t fsize>
|
template<size_t fsize>
|
||||||
static void EmitRSqrtEstimate(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
static void EmitRSqrtEstimate(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
using FPT = mp::unsigned_integer_of_size<fsize>;
|
using FPT = mcl::unsigned_integer_of_size<fsize>;
|
||||||
|
|
||||||
const auto fallback_fn = [](VectorArray<FPT>& result, const VectorArray<FPT>& operand, FP::FPCR fpcr, FP::FPSR& fpsr) {
|
const auto fallback_fn = [](VectorArray<FPT>& result, const VectorArray<FPT>& operand, FP::FPCR fpcr, FP::FPSR& fpsr) {
|
||||||
for (size_t i = 0; i < result.size(); i++) {
|
for (size_t i = 0; i < result.size(); i++) {
|
||||||
|
@ -1540,7 +1541,7 @@ void EmitX64::EmitFPVectorRSqrtEstimate64(EmitContext& ctx, IR::Inst* inst) {
|
||||||
|
|
||||||
template<size_t fsize>
|
template<size_t fsize>
|
||||||
static void EmitRSqrtStepFused(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
static void EmitRSqrtStepFused(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
using FPT = mp::unsigned_integer_of_size<fsize>;
|
using FPT = mcl::unsigned_integer_of_size<fsize>;
|
||||||
|
|
||||||
const auto fallback_fn = [](VectorArray<FPT>& result, const VectorArray<FPT>& op1, const VectorArray<FPT>& op2, FP::FPCR fpcr, FP::FPSR& fpsr) {
|
const auto fallback_fn = [](VectorArray<FPT>& result, const VectorArray<FPT>& op1, const VectorArray<FPT>& op2, FP::FPCR fpcr, FP::FPSR& fpsr) {
|
||||||
for (size_t i = 0; i < result.size(); i++) {
|
for (size_t i = 0; i < result.size(); i++) {
|
||||||
|
@ -1709,7 +1710,7 @@ void EmitX64::EmitFPVectorToHalf32(EmitContext& ctx, IR::Inst* inst) {
|
||||||
|
|
||||||
template<size_t fsize, bool unsigned_>
|
template<size_t fsize, bool unsigned_>
|
||||||
void EmitFPVectorToFixed(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
void EmitFPVectorToFixed(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
using FPT = mp::unsigned_integer_of_size<fsize>;
|
using FPT = mcl::unsigned_integer_of_size<fsize>;
|
||||||
|
|
||||||
const size_t fbits = inst->GetArg(1).GetU8();
|
const size_t fbits = inst->GetArg(1).GetU8();
|
||||||
const auto rounding = static_cast<FP::RoundingMode>(inst->GetArg(2).GetU8());
|
const auto rounding = static_cast<FP::RoundingMode>(inst->GetArg(2).GetU8());
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
#include <mp/traits/function_info.h>
|
#include <mcl/type_traits/function_info.hpp>
|
||||||
|
|
||||||
namespace Dynarmic::Common {
|
namespace Dynarmic::Common {
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ inline Dest BitCastPointee(const SourcePtr source) noexcept {
|
||||||
/// Cast a lambda into an equivalent function pointer.
|
/// Cast a lambda into an equivalent function pointer.
|
||||||
template<class Function>
|
template<class Function>
|
||||||
inline auto FptrCast(Function f) noexcept {
|
inline auto FptrCast(Function f) noexcept {
|
||||||
return static_cast<mp::equivalent_function_type<Function>*>(f);
|
return static_cast<mcl::equivalent_function_type<Function>*>(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Dynarmic::Common
|
} // namespace Dynarmic::Common
|
||||||
|
|
|
@ -9,26 +9,26 @@
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
#include <mp/metafunction/apply.h>
|
#include <mcl/mp/metafunction/apply.hpp>
|
||||||
#include <mp/traits/is_instance_of_template.h>
|
#include <mcl/mp/typelist/list.hpp>
|
||||||
#include <mp/typelist/list.h>
|
#include <mcl/type_traits/is_instance_of_template.hpp>
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
# include <mp/typelist/head.h>
|
# include <mcl/mp/typelist/head.hpp>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace Dynarmic::Common {
|
namespace Dynarmic::Common {
|
||||||
|
|
||||||
template<typename Function, typename... Values>
|
template<typename Function, typename... Values>
|
||||||
inline auto GenerateLookupTableFromList(Function f, mp::list<Values...>) {
|
inline auto GenerateLookupTableFromList(Function f, mcl::mp::list<Values...>) {
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
using PairT = std::invoke_result_t<Function, mp::head<mp::list<Values...>>>;
|
using PairT = std::invoke_result_t<Function, mcl::mp::head<mcl::mp::list<Values...>>>;
|
||||||
#else
|
#else
|
||||||
using PairT = std::common_type_t<std::invoke_result_t<Function, Values>...>;
|
using PairT = std::common_type_t<std::invoke_result_t<Function, Values>...>;
|
||||||
#endif
|
#endif
|
||||||
using MapT = mp::apply<std::map, PairT>;
|
using MapT = mcl::mp::apply<std::map, PairT>;
|
||||||
|
|
||||||
static_assert(mp::is_instance_of_template_v<std::pair, PairT>);
|
static_assert(mcl::is_instance_of_template_v<std::pair, PairT>);
|
||||||
|
|
||||||
const std::initializer_list<PairT> pair_array{f(Values{})...};
|
const std::initializer_list<PairT> pair_array{f(Values{})...};
|
||||||
return MapT(pair_array.begin(), pair_array.end());
|
return MapT(pair_array.begin(), pair_array.end());
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
|
||||||
#include <mp/traits/function_info.h>
|
#include <mcl/type_traits/function_info.hpp>
|
||||||
|
|
||||||
#include "dynarmic/common/assert.h"
|
#include "dynarmic/common/assert.h"
|
||||||
#include "dynarmic/common/bit_util.h"
|
#include "dynarmic/common/bit_util.h"
|
||||||
|
@ -165,7 +165,7 @@ struct detail {
|
||||||
* Creates a matcher that can match and parse instructions based on bitstring.
|
* Creates a matcher that can match and parse instructions based on bitstring.
|
||||||
* See also: GetMaskAndExpect and GetArgInfo for format of bitstring.
|
* See also: GetMaskAndExpect and GetArgInfo for format of bitstring.
|
||||||
*/
|
*/
|
||||||
template<typename FnT, size_t args_count = mp::parameter_count_v<FnT>>
|
template<typename FnT, size_t args_count = mcl::parameter_count_v<FnT>>
|
||||||
static auto GetMatcher(FnT fn, const char* const name, std::tuple<opcode_type, opcode_type> mask_and_expect, std::tuple<std::array<opcode_type, args_count>, std::array<size_t, args_count>> masks_and_shifts) {
|
static auto GetMatcher(FnT fn, const char* const name, std::tuple<opcode_type, opcode_type> mask_and_expect, std::tuple<std::array<opcode_type, args_count>, std::array<size_t, args_count>> masks_and_shifts) {
|
||||||
using Iota = std::make_index_sequence<args_count>;
|
using Iota = std::make_index_sequence<args_count>;
|
||||||
|
|
||||||
|
@ -177,7 +177,7 @@ struct detail {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#define DYNARMIC_DECODER_GET_MATCHER(MatcherT, fn, name, bitstring) Decoder::detail::detail<MatcherT<V>>::GetMatcher(&V::fn, name, Decoder::detail::detail<MatcherT<V>>::GetMaskAndExpect(bitstring), Decoder::detail::detail<MatcherT<V>>::template GetArgInfo<mp::parameter_count_v<decltype(&V::fn)>>(bitstring))
|
#define DYNARMIC_DECODER_GET_MATCHER(MatcherT, fn, name, bitstring) Decoder::detail::detail<MatcherT<V>>::GetMatcher(&V::fn, name, Decoder::detail::detail<MatcherT<V>>::GetMaskAndExpect(bitstring), Decoder::detail::detail<MatcherT<V>>::template GetArgInfo<mcl::parameter_count_v<decltype(&V::fn)>>(bitstring))
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
} // namespace Dynarmic::Decoder
|
} // namespace Dynarmic::Decoder
|
||||||
|
|
|
@ -51,12 +51,12 @@ include(CreateDirectoryGroups)
|
||||||
create_target_directory_groups(dynarmic_tests)
|
create_target_directory_groups(dynarmic_tests)
|
||||||
create_target_directory_groups(dynarmic_print_info)
|
create_target_directory_groups(dynarmic_print_info)
|
||||||
|
|
||||||
target_link_libraries(dynarmic_tests PRIVATE dynarmic boost catch fmt mp xbyak)
|
target_link_libraries(dynarmic_tests PRIVATE dynarmic boost catch fmt mcl xbyak)
|
||||||
target_include_directories(dynarmic_tests PRIVATE . ../src)
|
target_include_directories(dynarmic_tests PRIVATE . ../src)
|
||||||
target_compile_options(dynarmic_tests PRIVATE ${DYNARMIC_CXX_FLAGS})
|
target_compile_options(dynarmic_tests PRIVATE ${DYNARMIC_CXX_FLAGS})
|
||||||
target_compile_definitions(dynarmic_tests PRIVATE FMT_USE_USER_DEFINED_LITERALS=1 CATCH_CONFIG_ENABLE_BENCHMARKING=1)
|
target_compile_definitions(dynarmic_tests PRIVATE FMT_USE_USER_DEFINED_LITERALS=1 CATCH_CONFIG_ENABLE_BENCHMARKING=1)
|
||||||
|
|
||||||
target_link_libraries(dynarmic_print_info PRIVATE dynarmic boost catch fmt mp)
|
target_link_libraries(dynarmic_print_info PRIVATE dynarmic boost catch fmt mcl)
|
||||||
target_include_directories(dynarmic_print_info PRIVATE . ../src)
|
target_include_directories(dynarmic_print_info PRIVATE . ../src)
|
||||||
target_compile_options(dynarmic_print_info PRIVATE ${DYNARMIC_CXX_FLAGS})
|
target_compile_options(dynarmic_print_info PRIVATE ${DYNARMIC_CXX_FLAGS})
|
||||||
target_compile_definitions(dynarmic_print_info PRIVATE FMT_USE_USER_DEFINED_LITERALS=1)
|
target_compile_definitions(dynarmic_print_info PRIVATE FMT_USE_USER_DEFINED_LITERALS=1)
|
||||||
|
|
Loading…
Reference in a new issue