Squashed 'externals/mp/' changes from 29cb5588d..649fde1e8
649fde1e8 typelist: Add drop 5efe868da travis: Drop GCC 7 from CI c3f890f17 Update to use new metavalue types c4dd1c9b9 metavalue: Add some common operations 7da45c71b Remove unnecessary public keyword for struct inheritance 287d8e7ec Correct typos in file headers git-subtree-dir: externals/mp git-subtree-split: 649fde1e814f9ce5b04d7ddeb940244d9f63cb2f
This commit is contained in:
parent
7b0c47d3f0
commit
1925d4dcc6
22 changed files with 460 additions and 24 deletions
|
@ -5,9 +5,6 @@ matrix:
|
||||||
- compiler: clang
|
- compiler: clang
|
||||||
env: CXX=clang
|
env: CXX=clang
|
||||||
dist: bionic
|
dist: bionic
|
||||||
- compiler: g++-7
|
|
||||||
env: CXX=g++-7
|
|
||||||
dist: bionic
|
|
||||||
- compiler: g++-8
|
- compiler: g++-8
|
||||||
env: CXX=g++-8
|
env: CXX=g++-8
|
||||||
addons:
|
addons:
|
||||||
|
|
26
README.md
26
README.md
|
@ -53,14 +53,15 @@ A metavalue is a type of template `std::integral_constant`.
|
||||||
|
|
||||||
### Constants
|
### Constants
|
||||||
|
|
||||||
* [`std::true_type`](https://en.cppreference.com/w/cpp/types/integral_constant)
|
* mp::true_type: Aliases to [`std::true_type`](https://en.cppreference.com/w/cpp/types/integral_constant)
|
||||||
* [`std::false_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
|
### Constructor
|
||||||
|
|
||||||
* [`std::integral_constant`](https://en.cppreference.com/w/cpp/types/integral_constant)
|
* mp::value: Aliases to [`std::integral_constant`](https://en.cppreference.com/w/cpp/types/integral_constant)
|
||||||
* [`std::bool_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::lift_value`: Lifts a value to become a metavalue
|
* 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
|
### Conversions
|
||||||
|
|
||||||
|
@ -69,9 +70,18 @@ A metavalue is a type of template `std::integral_constant`.
|
||||||
### Operations
|
### Operations
|
||||||
|
|
||||||
* `mp::value_equal`: Compares value equality, ignores type. Use `std::is_same` for strict comparison.
|
* `mp::value_equal`: Compares value equality, ignores type. Use `std::is_same` for strict comparison.
|
||||||
* [`std::negation`](https://en.cppreference.com/w/cpp/types/negation)
|
* `mp::logic_if`: Like std::conditional but has a bool metavalue as first argument.
|
||||||
* [`std::conjunction`](https://en.cppreference.com/w/cpp/types/conjunction)
|
* `mp::bit_not`: Bitwise not
|
||||||
* [`std::disjunction`](https://en.cppreference.com/w/cpp/types/disjunction)
|
* `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`
|
`metafunction`
|
||||||
--------------
|
--------------
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* Ehis file is part of the mp project.
|
/* This file is part of the mp project.
|
||||||
* Copyright (c) 2017 MerryMage
|
* Copyright (c) 2017 MerryMage
|
||||||
* SPDX-License-Identifier: 0BSD
|
* SPDX-License-Identifier: 0BSD
|
||||||
*/
|
*/
|
||||||
|
|
20
include/mp/metavalue/bit_and.h
Normal file
20
include/mp/metavalue/bit_and.h
Normal 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
|
20
include/mp/metavalue/bit_not.h
Normal file
20
include/mp/metavalue/bit_not.h
Normal 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
|
20
include/mp/metavalue/bit_or.h
Normal file
20
include/mp/metavalue/bit_or.h
Normal 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
|
20
include/mp/metavalue/bit_xor.h
Normal file
20
include/mp/metavalue/bit_xor.h
Normal 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
|
43
include/mp/metavalue/conjunction.h
Normal file
43
include/mp/metavalue/conjunction.h
Normal 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
|
43
include/mp/metavalue/disjunction.h
Normal file
43
include/mp/metavalue/disjunction.h
Normal 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
|
20
include/mp/metavalue/logic_and.h
Normal file
20
include/mp/metavalue/logic_and.h
Normal 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
|
21
include/mp/metavalue/logic_if.h
Normal file
21
include/mp/metavalue/logic_if.h
Normal 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
|
20
include/mp/metavalue/logic_not.h
Normal file
20
include/mp/metavalue/logic_not.h
Normal 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
|
20
include/mp/metavalue/logic_or.h
Normal file
20
include/mp/metavalue/logic_or.h
Normal 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
|
20
include/mp/metavalue/product.h
Normal file
20
include/mp/metavalue/product.h
Normal 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
|
20
include/mp/metavalue/sum.h
Normal file
20
include/mp/metavalue/sum.h
Normal 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
|
31
include/mp/metavalue/value.h
Normal file
31
include/mp/metavalue/value.h
Normal 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
|
|
@ -13,7 +13,7 @@
|
||||||
namespace mp {
|
namespace mp {
|
||||||
|
|
||||||
template<class F>
|
template<class F>
|
||||||
struct function_info : public function_info<decltype(&F::operator())> {};
|
struct function_info : function_info<decltype(&F::operator())> {};
|
||||||
|
|
||||||
template<class R, class... As>
|
template<class R, class... As>
|
||||||
struct function_info<R(As...)> {
|
struct function_info<R(As...)> {
|
||||||
|
@ -31,15 +31,15 @@ struct function_info<R(As...)> {
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class R, class... As>
|
template<class R, class... As>
|
||||||
struct function_info<R(*)(As...)> : public function_info<R(As...)> {};
|
struct function_info<R(*)(As...)> : function_info<R(As...)> {};
|
||||||
|
|
||||||
template<class C, class R, class... As>
|
template<class C, class R, class... As>
|
||||||
struct function_info<R(C::*)(As...)> : public function_info<R(As...)> {
|
struct function_info<R(C::*)(As...)> : function_info<R(As...)> {
|
||||||
using class_type = C;
|
using class_type = C;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class C, class R, class... As>
|
template<class C, class R, class... As>
|
||||||
struct function_info<R(C::*)(As...) const> : public function_info<R(As...)> {
|
struct function_info<R(C::*)(As...) const> : function_info<R(As...)> {
|
||||||
using class_type = C;
|
using class_type = C;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -5,16 +5,16 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <type_traits>
|
#include <mp/metavalue/value.h>
|
||||||
|
|
||||||
namespace mp {
|
namespace mp {
|
||||||
|
|
||||||
/// Is type T an instance of template class C?
|
/// Is type T an instance of template class C?
|
||||||
template <template <class...> class, class>
|
template <template <class...> class, class>
|
||||||
struct is_instance_of_template : public std::false_type {};
|
struct is_instance_of_template : false_type {};
|
||||||
|
|
||||||
template <template <class...> class C, class... As>
|
template <template <class...> class C, class... As>
|
||||||
struct is_instance_of_template<C, C<As...>> : public std::true_type {};
|
struct is_instance_of_template<C, C<As...>> : true_type {};
|
||||||
|
|
||||||
/// Is type T an instance of template class C?
|
/// Is type T an instance of template class C?
|
||||||
template<template <class...> class C, class T>
|
template<template <class...> class C, class T>
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
/* Ehis file is part of the mp project.
|
/* This file is part of the mp project.
|
||||||
* Copyright (c) 2017 MerryMage
|
* Copyright (c) 2017 MerryMage
|
||||||
* SPDX-License-Identifier: 0BSD
|
* SPDX-License-Identifier: 0BSD
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <type_traits>
|
#include <mp/metavalue/value.h>
|
||||||
|
|
||||||
namespace mp {
|
namespace mp {
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ struct contains;
|
||||||
|
|
||||||
template<template<class...> class LT, class... Ts, class T>
|
template<template<class...> class LT, class... Ts, class T>
|
||||||
struct contains<LT<Ts...>, T>
|
struct contains<LT<Ts...>, T>
|
||||||
: public std::bool_constant<(false || ... || std::is_same_v<Ts, T>)>
|
: bool_value<(false || ... || std::is_same_v<Ts, T>)>
|
||||||
{};
|
{};
|
||||||
|
|
||||||
/// Does list L contain an element which is same as type T?
|
/// Does list L contain an element which is same as type T?
|
||||||
|
|
34
include/mp/typelist/drop.h
Normal file
34
include/mp/typelist/drop.h
Normal 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
|
|
@ -7,17 +7,83 @@
|
||||||
|
|
||||||
#include <type_traits>
|
#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/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_cast.h>
|
||||||
#include <mp/metavalue/value_equal.h>
|
#include <mp/metavalue/value_equal.h>
|
||||||
|
|
||||||
using namespace mp;
|
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
|
// lift_value
|
||||||
|
|
||||||
static_assert(std::is_same_v<lift_value<3>, std::integral_constant<int, 3>>);
|
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>);
|
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
|
// value_cast
|
||||||
|
|
||||||
static_assert(std::is_same_v<value_cast<int, std::true_type>, std::integral_constant<int, 1>>);
|
static_assert(std::is_same_v<value_cast<int, std::true_type>, std::integral_constant<int, 1>>);
|
||||||
|
|
|
@ -10,10 +10,13 @@
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
|
#include <mp/metavalue/value.h>
|
||||||
|
|
||||||
#include <mp/typelist/append.h>
|
#include <mp/typelist/append.h>
|
||||||
#include <mp/typelist/cartesian_product.h>
|
#include <mp/typelist/cartesian_product.h>
|
||||||
#include <mp/typelist/concat.h>
|
#include <mp/typelist/concat.h>
|
||||||
#include <mp/typelist/contains.h>
|
#include <mp/typelist/contains.h>
|
||||||
|
#include <mp/typelist/drop.h>
|
||||||
#include <mp/typelist/get.h>
|
#include <mp/typelist/get.h>
|
||||||
#include <mp/typelist/head.h>
|
#include <mp/typelist/head.h>
|
||||||
#include <mp/typelist/length.h>
|
#include <mp/typelist/length.h>
|
||||||
|
@ -60,6 +63,14 @@ static_assert(!contains_v<list<>, int>);
|
||||||
static_assert(!contains_v<list<double>, int>);
|
static_assert(!contains_v<list<double>, int>);
|
||||||
static_assert(contains_v<list<double, int>, 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
|
// get
|
||||||
|
|
||||||
static_assert(std::is_same_v<get<0, list<int, double>>, int>);
|
static_assert(std::is_same_v<get<0, list<int, double>>, int>);
|
||||||
|
@ -81,13 +92,13 @@ static_assert(length_v<list<int, int, int>> == 3);
|
||||||
static_assert(
|
static_assert(
|
||||||
std::is_same_v<
|
std::is_same_v<
|
||||||
lift_sequence<std::make_index_sequence<3>>,
|
lift_sequence<std::make_index_sequence<3>>,
|
||||||
list<std::integral_constant<std::size_t, 0>, std::integral_constant<std::size_t, 1>, std::integral_constant<std::size_t, 2>>
|
list<size_value<0>, size_value<1>, size_value<2>>
|
||||||
>
|
>
|
||||||
);
|
);
|
||||||
|
|
||||||
// lower_to_tuple
|
// lower_to_tuple
|
||||||
|
|
||||||
static_assert(lower_to_tuple_v<list<std::integral_constant<std::size_t, 0>, std::integral_constant<std::size_t, 1>, std::integral_constant<std::size_t, 2>>> == std::tuple<std::size_t, std::size_t, std::size_t>(0, 1, 2));
|
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));
|
static_assert(lower_to_tuple_v<list<std::true_type, std::false_type>> == std::make_tuple(true, false));
|
||||||
|
|
||||||
// prepend
|
// prepend
|
||||||
|
|
Loading…
Reference in a new issue