early-access version 1255

This commit is contained in:
pineappleEA
2020-12-28 15:15:37 +00:00
parent 84b39492d1
commit 78b48028e1
6254 changed files with 1868140 additions and 0 deletions

19
externals/dynarmic/externals/mp/.travis.yml vendored Executable file
View File

@@ -0,0 +1,19 @@
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/dynarmic/externals/mp/LICENSE-0BSD vendored Executable file
View File

@@ -0,0 +1,12 @@
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.

121
externals/dynarmic/externals/mp/README.md vendored Executable file
View File

@@ -0,0 +1,121 @@
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::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).

View File

@@ -0,0 +1,26 @@
/* 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

View File

@@ -0,0 +1,19 @@
/* 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

View File

@@ -0,0 +1,23 @@
/* 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

View File

@@ -0,0 +1,26 @@
/* 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

View File

@@ -0,0 +1,20 @@
/* 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

View File

@@ -0,0 +1,20 @@
/* 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

View File

@@ -0,0 +1,20 @@
/* 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

View File

@@ -0,0 +1,20 @@
/* 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

View File

@@ -0,0 +1,43 @@
/* 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

View File

@@ -0,0 +1,43 @@
/* 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

View File

@@ -0,0 +1,16 @@
/* 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

View File

@@ -0,0 +1,20 @@
/* 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

View File

@@ -0,0 +1,21 @@
/* 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

View File

@@ -0,0 +1,20 @@
/* 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

View File

@@ -0,0 +1,20 @@
/* 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

View File

@@ -0,0 +1,20 @@
/* 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

View File

@@ -0,0 +1,20 @@
/* 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

View File

@@ -0,0 +1,31 @@
/* 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

View File

@@ -0,0 +1,16 @@
/* 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

View File

@@ -0,0 +1,16 @@
/* 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

View File

@@ -0,0 +1,20 @@
/* 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

View File

@@ -0,0 +1,64 @@
/* 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;
};
template<class C, class R, class... As>
struct function_info<R(C::*)(As...) const> : function_info<R(As...)> {
using class_type = C;
};
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 return_type = typename function_info<F>::return_type;
template<class F>
using class_type = typename function_info<F>::class_type;
} // namespace mp

View File

@@ -0,0 +1,50 @@
/* 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

View File

@@ -0,0 +1,23 @@
/* 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

View File

@@ -0,0 +1,26 @@
/* 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

View File

@@ -0,0 +1,50 @@
/* 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

View File

@@ -0,0 +1,56 @@
/* 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

View File

@@ -0,0 +1,25 @@
/* 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

View File

@@ -0,0 +1,34 @@
/* 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

View File

@@ -0,0 +1,19 @@
/* 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

View File

@@ -0,0 +1,26 @@
/* 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

View File

@@ -0,0 +1,21 @@
/* 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

View File

@@ -0,0 +1,30 @@
/* 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

View File

@@ -0,0 +1,14 @@
/* 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

View File

@@ -0,0 +1,25 @@
/* 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

View File

@@ -0,0 +1,26 @@
/* 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

View File

@@ -0,0 +1,26 @@
/* 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

View File

@@ -0,0 +1,12 @@
/* 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;
}

View File

@@ -0,0 +1,93 @@
/* 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>);

View File

@@ -0,0 +1,42 @@
/* 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>>);

View File

@@ -0,0 +1,113 @@
/* 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<>>);