mirror of
https://github.com/azahar-emu/mcl
synced 2025-11-06 15:10:05 +01:00
Import mp
This commit is contained in:
parent
537c4144a1
commit
8b12832172
1
.gitignore
vendored
1
.gitignore
vendored
@ -1 +1,2 @@
|
||||
*build*/
|
||||
.DS_Store
|
||||
|
||||
25
include/mcl/mp/metafunction/apply.hpp
Normal file
25
include/mcl/mp/metafunction/apply.hpp
Normal file
@ -0,0 +1,25 @@
|
||||
// This file is part of the mcl project.
|
||||
// Copyright (c) 2022 merryhime
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace mcl::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 mcl::mp
|
||||
18
include/mcl/mp/metafunction/bind.hpp
Normal file
18
include/mcl/mp/metafunction/bind.hpp
Normal file
@ -0,0 +1,18 @@
|
||||
// This file is part of the mcl project.
|
||||
// Copyright (c) 2022 merryhime
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace mcl::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 mcl::mp
|
||||
|
||||
#define MCL_MP_BIND(...) ::mcl::mp::bind<__VA_ARGS__>::template type
|
||||
22
include/mcl/mp/metafunction/identity.hpp
Normal file
22
include/mcl/mp/metafunction/identity.hpp
Normal file
@ -0,0 +1,22 @@
|
||||
// This file is part of the mcl project.
|
||||
// Copyright (c) 2022 merryhime
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace mcl::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 mcl::mp
|
||||
25
include/mcl/mp/metafunction/map.hpp
Normal file
25
include/mcl/mp/metafunction/map.hpp
Normal file
@ -0,0 +1,25 @@
|
||||
// This file is part of the mcl project.
|
||||
// Copyright (c) 2022 merryhime
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace mcl::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 mcl::mp
|
||||
19
include/mcl/mp/metavalue/bit_and.hpp
Normal file
19
include/mcl/mp/metavalue/bit_and.hpp
Normal file
@ -0,0 +1,19 @@
|
||||
// This file is part of the mcl project.
|
||||
// Copyright (c) 2022 merryhime
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "mcl/mp/metavalue/lift_value.hpp"
|
||||
|
||||
namespace mcl::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 mcl::mp
|
||||
19
include/mcl/mp/metavalue/bit_not.hpp
Normal file
19
include/mcl/mp/metavalue/bit_not.hpp
Normal file
@ -0,0 +1,19 @@
|
||||
// This file is part of the mcl project.
|
||||
// Copyright (c) 2022 merryhime
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "mcl/mp/metavalue/lift_value.hpp"
|
||||
|
||||
namespace mcl::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 mcl::mp
|
||||
19
include/mcl/mp/metavalue/bit_or.hpp
Normal file
19
include/mcl/mp/metavalue/bit_or.hpp
Normal file
@ -0,0 +1,19 @@
|
||||
// This file is part of the mcl project.
|
||||
// Copyright (c) 2022 merryhime
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "mcl/mp/metavalue/lift_value.hpp"
|
||||
|
||||
namespace mcl::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 mcl::mp
|
||||
19
include/mcl/mp/metavalue/bit_xor.hpp
Normal file
19
include/mcl/mp/metavalue/bit_xor.hpp
Normal file
@ -0,0 +1,19 @@
|
||||
// This file is part of the mcl project.
|
||||
// Copyright (c) 2022 merryhime
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "mcl/mp/metavalue/lift_value.hpp"
|
||||
|
||||
namespace mcl::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 mcl::mp
|
||||
42
include/mcl/mp/metavalue/conjunction.hpp
Normal file
42
include/mcl/mp/metavalue/conjunction.hpp
Normal file
@ -0,0 +1,42 @@
|
||||
// This file is part of the mcl project.
|
||||
// Copyright (c) 2022 merryhime
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "mcl/mp/metavalue/logic_if.hpp"
|
||||
#include "mcl/mp/metavalue/value.hpp"
|
||||
|
||||
namespace mcl::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 mcl::mp
|
||||
42
include/mcl/mp/metavalue/disjunction.hpp
Normal file
42
include/mcl/mp/metavalue/disjunction.hpp
Normal file
@ -0,0 +1,42 @@
|
||||
// This file is part of the mcl project.
|
||||
// Copyright (c) 2022 merryhime
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "mcl/mp/metavalue/logic_if.hpp"
|
||||
#include "mcl/mp/metavalue/value.hpp"
|
||||
|
||||
namespace mcl::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 mcl::mp
|
||||
15
include/mcl/mp/metavalue/lift_value.hpp
Normal file
15
include/mcl/mp/metavalue/lift_value.hpp
Normal file
@ -0,0 +1,15 @@
|
||||
// This file is part of the mcl project.
|
||||
// Copyright (c) 2022 merryhime
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace mcl::mp {
|
||||
|
||||
/// Lifts a value into a type (a metavalue)
|
||||
template<auto V>
|
||||
using lift_value = std::integral_constant<decltype(V), V>;
|
||||
|
||||
} // namespace mcl::mp
|
||||
19
include/mcl/mp/metavalue/logic_and.hpp
Normal file
19
include/mcl/mp/metavalue/logic_and.hpp
Normal file
@ -0,0 +1,19 @@
|
||||
// This file is part of the mcl project.
|
||||
// Copyright (c) 2022 merryhime
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "mcl/mp/metavalue/value.hpp"
|
||||
|
||||
namespace mcl::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 mcl::mp
|
||||
21
include/mcl/mp/metavalue/logic_if.hpp
Normal file
21
include/mcl/mp/metavalue/logic_if.hpp
Normal file
@ -0,0 +1,21 @@
|
||||
// This file is part of the mcl project.
|
||||
// Copyright (c) 2022 merryhime
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#include "mcl/mp/metavalue/value.hpp"
|
||||
|
||||
namespace mcl::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 mcl::mp
|
||||
19
include/mcl/mp/metavalue/logic_not.hpp
Normal file
19
include/mcl/mp/metavalue/logic_not.hpp
Normal file
@ -0,0 +1,19 @@
|
||||
// This file is part of the mcl project.
|
||||
// Copyright (c) 2022 merryhime
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "mcl/mp/metavalue/value.hpp"
|
||||
|
||||
namespace mcl::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 mcl::mp
|
||||
19
include/mcl/mp/metavalue/logic_or.hpp
Normal file
19
include/mcl/mp/metavalue/logic_or.hpp
Normal file
@ -0,0 +1,19 @@
|
||||
// This file is part of the mcl project.
|
||||
// Copyright (c) 2022 merryhime
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "mcl/mp/metavalue/value.hpp"
|
||||
|
||||
namespace mcl::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 mcl::mp
|
||||
19
include/mcl/mp/metavalue/product.hpp
Normal file
19
include/mcl/mp/metavalue/product.hpp
Normal file
@ -0,0 +1,19 @@
|
||||
// This file is part of the mcl project.
|
||||
// Copyright (c) 2022 merryhime
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "mcl/mp/metavalue/lift_value.hpp"
|
||||
|
||||
namespace mcl::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 mcl::mp
|
||||
19
include/mcl/mp/metavalue/sum.hpp
Normal file
19
include/mcl/mp/metavalue/sum.hpp
Normal file
@ -0,0 +1,19 @@
|
||||
// This file is part of the mcl project.
|
||||
// Copyright (c) 2022 merryhime
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "mcl/mp/metavalue/lift_value.hpp"
|
||||
|
||||
namespace mcl::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 mcl::mp
|
||||
30
include/mcl/mp/metavalue/value.hpp
Normal file
30
include/mcl/mp/metavalue/value.hpp
Normal file
@ -0,0 +1,30 @@
|
||||
// This file is part of the mcl project.
|
||||
// Copyright (c) 2022 merryhime
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <type_traits>
|
||||
|
||||
namespace mcl::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 size_t (and value v).
|
||||
template<size_t v>
|
||||
using size_value = value<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 mcl::mp
|
||||
15
include/mcl/mp/metavalue/value_cast.hpp
Normal file
15
include/mcl/mp/metavalue/value_cast.hpp
Normal file
@ -0,0 +1,15 @@
|
||||
// This file is part of the mcl project.
|
||||
// Copyright (c) 2022 merryhime
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace mcl::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 mcl::mp
|
||||
15
include/mcl/mp/metavalue/value_equal.hpp
Normal file
15
include/mcl/mp/metavalue/value_equal.hpp
Normal file
@ -0,0 +1,15 @@
|
||||
// This file is part of the mcl project.
|
||||
// Copyright (c) 2022 merryhime
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace mcl::mp {
|
||||
|
||||
/// Do two metavalues contain the same value?
|
||||
template<class V1, class V2>
|
||||
using value_equal = std::bool_constant<V1::value == V2::value>;
|
||||
|
||||
} // namespace mcl::mp
|
||||
19
include/mcl/mp/misc/argument_count.hpp
Normal file
19
include/mcl/mp/misc/argument_count.hpp
Normal file
@ -0,0 +1,19 @@
|
||||
// This file is part of the mcl project.
|
||||
// Copyright (c) 2022 merryhime
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "mcl/mp/metavalue/lift_value.hpp"
|
||||
|
||||
namespace mcl::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 mcl::mp
|
||||
25
include/mcl/mp/typelist/append.hpp
Normal file
25
include/mcl/mp/typelist/append.hpp
Normal file
@ -0,0 +1,25 @@
|
||||
// This file is part of the mcl project.
|
||||
// Copyright (c) 2022 merryhime
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace mcl::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 mcl::mp
|
||||
47
include/mcl/mp/typelist/cartesian_product.hpp
Normal file
47
include/mcl/mp/typelist/cartesian_product.hpp
Normal file
@ -0,0 +1,47 @@
|
||||
// This file is part of the mcl project.
|
||||
// Copyright (c) 2022 merryhime
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "mcl/mp/metafunction/bind.hpp"
|
||||
#include "mcl/mp/metafunction/map.hpp"
|
||||
#include "mcl/mp/typelist/append.hpp"
|
||||
#include "mcl/mp/typelist/concat.hpp"
|
||||
#include "mcl/mp/typelist/list.hpp"
|
||||
|
||||
namespace mcl::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<MCL_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 mcl::mp
|
||||
94
include/mcl/mp/typelist/concat.hpp
Normal file
94
include/mcl/mp/typelist/concat.hpp
Normal file
@ -0,0 +1,94 @@
|
||||
// This file is part of the mcl project.
|
||||
// Copyright (c) 2022 merryhime
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "mcl/mp/typelist/list.hpp"
|
||||
|
||||
namespace mcl::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 mcl::mp
|
||||
23
include/mcl/mp/typelist/contains.hpp
Normal file
23
include/mcl/mp/typelist/contains.hpp
Normal file
@ -0,0 +1,23 @@
|
||||
// This file is part of the mcl project.
|
||||
// Copyright (c) 2022 merryhime
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "mcl/mp/metavalue/value.hpp"
|
||||
|
||||
namespace mcl::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 mcl::mp
|
||||
33
include/mcl/mp/typelist/drop.hpp
Normal file
33
include/mcl/mp/typelist/drop.hpp
Normal file
@ -0,0 +1,33 @@
|
||||
// This file is part of the mcl project.
|
||||
// Copyright (c) 2022 merryhime
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <type_traits>
|
||||
|
||||
namespace mcl::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 mcl::mp
|
||||
18
include/mcl/mp/typelist/get.hpp
Normal file
18
include/mcl/mp/typelist/get.hpp
Normal file
@ -0,0 +1,18 @@
|
||||
// This file is part of the mcl project.
|
||||
// Copyright (c) 2022 merryhime
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <tuple>
|
||||
|
||||
#include "mcl/mp/metafunction/apply.hpp"
|
||||
|
||||
namespace mcl::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 mcl::mp
|
||||
25
include/mcl/mp/typelist/head.hpp
Normal file
25
include/mcl/mp/typelist/head.hpp
Normal file
@ -0,0 +1,25 @@
|
||||
// This file is part of the mcl project.
|
||||
// Copyright (c) 2022 merryhime
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace mcl::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 mcl::mp
|
||||
20
include/mcl/mp/typelist/length.hpp
Normal file
20
include/mcl/mp/typelist/length.hpp
Normal file
@ -0,0 +1,20 @@
|
||||
// This file is part of the mcl project.
|
||||
// Copyright (c) 2022 merryhime
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "mcl/mp/metafunction/apply.hpp"
|
||||
#include "mcl/mp/misc/argument_count.hpp"
|
||||
|
||||
namespace mcl::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 mcl::mp
|
||||
29
include/mcl/mp/typelist/lift_sequence.hpp
Normal file
29
include/mcl/mp/typelist/lift_sequence.hpp
Normal file
@ -0,0 +1,29 @@
|
||||
// This file is part of the mcl project.
|
||||
// Copyright (c) 2022 merryhime
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#include "mcl/mp/typelist/list.hpp"
|
||||
|
||||
namespace mcl::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 mcl::mp
|
||||
13
include/mcl/mp/typelist/list.hpp
Normal file
13
include/mcl/mp/typelist/list.hpp
Normal file
@ -0,0 +1,13 @@
|
||||
// This file is part of the mcl project.
|
||||
// Copyright (c) 2022 merryhime
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace mcl::mp {
|
||||
|
||||
/// Contains a list of types
|
||||
template<class... E>
|
||||
struct list {};
|
||||
|
||||
} // namespace mcl::mp
|
||||
24
include/mcl/mp/typelist/lower_to_tuple.hpp
Normal file
24
include/mcl/mp/typelist/lower_to_tuple.hpp
Normal file
@ -0,0 +1,24 @@
|
||||
// This file is part of the mcl project.
|
||||
// Copyright (c) 2022 merryhime
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <tuple>
|
||||
|
||||
namespace mcl::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 mcl::mp
|
||||
25
include/mcl/mp/typelist/prepend.hpp
Normal file
25
include/mcl/mp/typelist/prepend.hpp
Normal file
@ -0,0 +1,25 @@
|
||||
// This file is part of the mcl project.
|
||||
// Copyright (c) 2022 merryhime
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace mcl::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 mcl::mp
|
||||
25
include/mcl/mp/typelist/tail.hpp
Normal file
25
include/mcl/mp/typelist/tail.hpp
Normal file
@ -0,0 +1,25 @@
|
||||
// This file is part of the mcl project.
|
||||
// Copyright (c) 2022 merryhime
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace mcl::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 mcl::mp
|
||||
@ -8,7 +8,7 @@
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include "mcl/macro/anonymous_variable.h"
|
||||
#include "mcl/(.*).hpp"
|
||||
|
||||
namespace mcl::detail {
|
||||
|
||||
|
||||
70
include/mcl/type_traits/function_info.hpp
Normal file
70
include/mcl/type_traits/function_info.hpp
Normal file
@ -0,0 +1,70 @@
|
||||
// This file is part of the mcl project.
|
||||
// Copyright (c) 2022 merryhime
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <tuple>
|
||||
|
||||
#include "mcl/mp/typelist/list.hpp"
|
||||
|
||||
namespace mcl {
|
||||
|
||||
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 = mp::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 mcl
|
||||
48
include/mcl/type_traits/integer_of_size.hpp
Normal file
48
include/mcl/type_traits/integer_of_size.hpp
Normal file
@ -0,0 +1,48 @@
|
||||
// This file is part of the mcl project.
|
||||
// Copyright (c) 2022 merryhime
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "mp/stdint.hpp"
|
||||
|
||||
namespace mcl {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<size_t size>
|
||||
struct integer_of_size_impl {};
|
||||
|
||||
template<>
|
||||
struct integer_of_size_impl<8> {
|
||||
using unsigned_type = u8;
|
||||
using signed_type = s8;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct integer_of_size_impl<16> {
|
||||
using unsigned_type = u16;
|
||||
using signed_type = s16;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct integer_of_size_impl<32> {
|
||||
using unsigned_type = u32;
|
||||
using signed_type = s32;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct integer_of_size_impl<64> {
|
||||
using unsigned_type = u64;
|
||||
using signed_type = s64;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<size_t size>
|
||||
using unsigned_integer_of_size = typename detail::integer_of_size_impl<size>::unsigned_type;
|
||||
|
||||
template<size_t size>
|
||||
using signed_integer_of_size = typename detail::integer_of_size_impl<size>::signed_type;
|
||||
|
||||
} // namespace mcl
|
||||
22
include/mcl/type_traits/is_instance_of_template.hpp
Normal file
22
include/mcl/type_traits/is_instance_of_template.hpp
Normal file
@ -0,0 +1,22 @@
|
||||
// This file is part of the mcl project.
|
||||
// Copyright (c) 2022 merryhime
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "mcl/mp/metavalue/value.hpp"
|
||||
|
||||
namespace mcl {
|
||||
|
||||
/// Is type T an instance of template class C?
|
||||
template<template<class...> class, class>
|
||||
struct is_instance_of_template : mp::false_type {};
|
||||
|
||||
template<template<class...> class C, class... As>
|
||||
struct is_instance_of_template<C, C<As...>> : mp::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 mcl
|
||||
@ -5,17 +5,55 @@ add_library(mcl
|
||||
../include/mcl/bit/rotate.hpp
|
||||
../include/mcl/bit/swap.hpp
|
||||
../include/mcl/bit_cast.hpp
|
||||
../include/mcl/bitsizeof.hpp
|
||||
../include/mcl/concepts/bit_integral.hpp
|
||||
../include/mcl/concepts/is_any_of.hpp
|
||||
../include/mcl/concepts/same_as.hpp
|
||||
../include/mcl/container/intrusive_list.hpp
|
||||
../include/mcl/hint/assume.hpp
|
||||
../include/mcl/iterator/reverse.hpp
|
||||
../include/mcl/macro/anonymous_variable.hpp
|
||||
../include/mcl/macro/architecture.hpp
|
||||
../include/mcl/macro/concatenate_tokens.hpp
|
||||
../include/mcl/mp/metafunction/apply.hpp
|
||||
../include/mcl/mp/metafunction/bind.hpp
|
||||
../include/mcl/mp/metafunction/identity.hpp
|
||||
../include/mcl/mp/metafunction/map.hpp
|
||||
../include/mcl/mp/metavalue/bit_and.hpp
|
||||
../include/mcl/mp/metavalue/bit_not.hpp
|
||||
../include/mcl/mp/metavalue/bit_or.hpp
|
||||
../include/mcl/mp/metavalue/bit_xor.hpp
|
||||
../include/mcl/mp/metavalue/conjunction.hpp
|
||||
../include/mcl/mp/metavalue/disjunction.hpp
|
||||
../include/mcl/mp/metavalue/lift_value.hpp
|
||||
../include/mcl/mp/metavalue/logic_and.hpp
|
||||
../include/mcl/mp/metavalue/logic_if.hpp
|
||||
../include/mcl/mp/metavalue/logic_not.hpp
|
||||
../include/mcl/mp/metavalue/logic_or.hpp
|
||||
../include/mcl/mp/metavalue/product.hpp
|
||||
../include/mcl/mp/metavalue/sum.hpp
|
||||
../include/mcl/mp/metavalue/value.hpp
|
||||
../include/mcl/mp/metavalue/value_cast.hpp
|
||||
../include/mcl/mp/metavalue/value_equal.hpp
|
||||
../include/mcl/mp/misc/argument_count.hpp
|
||||
../include/mcl/mp/typelist/append.hpp
|
||||
../include/mcl/mp/typelist/cartesian_product.hpp
|
||||
../include/mcl/mp/typelist/concat.hpp
|
||||
../include/mcl/mp/typelist/contains.hpp
|
||||
../include/mcl/mp/typelist/drop.hpp
|
||||
../include/mcl/mp/typelist/get.hpp
|
||||
../include/mcl/mp/typelist/head.hpp
|
||||
../include/mcl/mp/typelist/length.hpp
|
||||
../include/mcl/mp/typelist/lift_sequence.hpp
|
||||
../include/mcl/mp/typelist/list.hpp
|
||||
../include/mcl/mp/typelist/lower_to_tuple.hpp
|
||||
../include/mcl/mp/typelist/prepend.hpp
|
||||
../include/mcl/mp/typelist/tail.hpp
|
||||
../include/mcl/scope_exit.hpp
|
||||
../include/mcl/stdint.hpp
|
||||
../include/mcl/stdint.hpp
|
||||
../include/mcl/type_traits/function_info.hpp
|
||||
../include/mcl/type_traits/integer_of_size.hpp
|
||||
../include/mcl/type_traits/is_instance_of_template.hpp
|
||||
assert.cpp
|
||||
)
|
||||
target_include_directories(mcl PUBLIC ../include/)
|
||||
|
||||
@ -1,5 +1,8 @@
|
||||
add_executable(mcl-tests
|
||||
main.cpp
|
||||
mp/metavalue_tests.cpp
|
||||
mp/typelist_tests.cpp
|
||||
type_traits/type_traits_tests.cpp
|
||||
)
|
||||
target_include_directories(mcl-tests PUBLIC .)
|
||||
target_compile_options(mcl-tests PRIVATE ${STAMINA_CXX_FLAGS})
|
||||
|
||||
90
tests/mp/metavalue_tests.cpp
Normal file
90
tests/mp/metavalue_tests.cpp
Normal file
@ -0,0 +1,90 @@
|
||||
// This file is part of the mcl project.
|
||||
// Copyright (c) 2022 merryhime
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#include <mcl/mp/metavalue/bit_and.hpp>
|
||||
#include <mcl/mp/metavalue/bit_not.hpp>
|
||||
#include <mcl/mp/metavalue/bit_or.hpp>
|
||||
#include <mcl/mp/metavalue/bit_xor.hpp>
|
||||
#include <mcl/mp/metavalue/conjunction.hpp>
|
||||
#include <mcl/mp/metavalue/disjunction.hpp>
|
||||
#include <mcl/mp/metavalue/lift_value.hpp>
|
||||
#include <mcl/mp/metavalue/logic_and.hpp>
|
||||
#include <mcl/mp/metavalue/logic_not.hpp>
|
||||
#include <mcl/mp/metavalue/logic_or.hpp>
|
||||
#include <mcl/mp/metavalue/product.hpp>
|
||||
#include <mcl/mp/metavalue/sum.hpp>
|
||||
#include <mcl/mp/metavalue/value.hpp>
|
||||
#include <mcl/mp/metavalue/value_cast.hpp>
|
||||
#include <mcl/mp/metavalue/value_equal.hpp>
|
||||
|
||||
using namespace mcl::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>);
|
||||
104
tests/mp/typelist_tests.cpp
Normal file
104
tests/mp/typelist_tests.cpp
Normal file
@ -0,0 +1,104 @@
|
||||
// This file is part of the mcl project.
|
||||
// Copyright (c) 2022 merryhime
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#include <cstddef>
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include <mcl/mp/metavalue/value.hpp>
|
||||
#include <mcl/mp/typelist/append.hpp>
|
||||
#include <mcl/mp/typelist/cartesian_product.hpp>
|
||||
#include <mcl/mp/typelist/concat.hpp>
|
||||
#include <mcl/mp/typelist/contains.hpp>
|
||||
#include <mcl/mp/typelist/drop.hpp>
|
||||
#include <mcl/mp/typelist/get.hpp>
|
||||
#include <mcl/mp/typelist/head.hpp>
|
||||
#include <mcl/mp/typelist/length.hpp>
|
||||
#include <mcl/mp/typelist/lift_sequence.hpp>
|
||||
#include <mcl/mp/typelist/list.hpp>
|
||||
#include <mcl/mp/typelist/lower_to_tuple.hpp>
|
||||
#include <mcl/mp/typelist/prepend.hpp>
|
||||
#include <mcl/mp/typelist/tail.hpp>
|
||||
|
||||
using namespace mcl::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<>>);
|
||||
39
tests/type_traits/type_traits_tests.cpp
Normal file
39
tests/type_traits/type_traits_tests.cpp
Normal file
@ -0,0 +1,39 @@
|
||||
// This file is part of the mcl project.
|
||||
// Copyright (c) 2022 merryhime
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
|
||||
#include <mcl/type_traits/function_info.hpp>
|
||||
#include <mcl/type_traits/is_instance_of_template.hpp>
|
||||
|
||||
using namespace mcl;
|
||||
|
||||
// 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>>);
|
||||
Loading…
x
Reference in New Issue
Block a user