Skip to content

Commit f4b20e9

Browse files
Metaprogramming using Boost.CallableTraits and Boost.MP11 (#444)
--------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
1 parent 64e5e43 commit f4b20e9

File tree

7 files changed

+28
-224
lines changed

7 files changed

+28
-224
lines changed

phlex/metaprogramming/CMakeLists.txt

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,6 @@ cet_make_library(
1212

1313
install(FILES delegate.hpp type_deduction.hpp DESTINATION include/phlex/metaprogramming)
1414

15-
install(
16-
FILES
17-
detail/basic_concepts.hpp
18-
detail/ctor_reflect_types.hpp
19-
detail/number_output_objects.hpp
20-
detail/number_parameters.hpp
21-
detail/parameter_types.hpp
22-
detail/return_type.hpp
23-
DESTINATION include/phlex/metaprogramming/detail
24-
)
15+
install(FILES detail/ctor_reflect_types.hpp DESTINATION include/phlex/metaprogramming/detail)
2516

2617
add_library(phlex::metaprogramming ALIAS phlex_metaprogramming_int)

phlex/metaprogramming/detail/basic_concepts.hpp

Lines changed: 0 additions & 9 deletions
This file was deleted.

phlex/metaprogramming/detail/number_output_objects.hpp

Lines changed: 0 additions & 63 deletions
This file was deleted.

phlex/metaprogramming/detail/number_parameters.hpp

Lines changed: 0 additions & 40 deletions
This file was deleted.

phlex/metaprogramming/detail/parameter_types.hpp

Lines changed: 0 additions & 32 deletions
This file was deleted.

phlex/metaprogramming/detail/return_type.hpp

Lines changed: 0 additions & 31 deletions
This file was deleted.

phlex/metaprogramming/type_deduction.hpp

Lines changed: 27 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,28 @@
22
#define PHLEX_METAPROGRAMMING_TYPE_DEDUCTION_HPP
33

44
#include "phlex/metaprogramming/detail/ctor_reflect_types.hpp"
5-
#include "phlex/metaprogramming/detail/number_output_objects.hpp"
6-
#include "phlex/metaprogramming/detail/number_parameters.hpp"
7-
#include "phlex/metaprogramming/detail/parameter_types.hpp"
8-
#include "phlex/metaprogramming/detail/return_type.hpp"
5+
6+
#include "boost/callable_traits.hpp"
7+
#include "boost/mp11/algorithm.hpp"
8+
#include "boost/mp11/list.hpp"
99

1010
#include <atomic>
1111
#include <iterator>
1212
#include <tuple>
1313
#include <type_traits>
1414

1515
namespace phlex::experimental {
16+
namespace ct = boost::callable_traits;
17+
namespace mp11 = boost::mp11;
1618
template <typename T>
17-
using return_type = decltype(detail::return_type_impl(std::declval<T>()));
19+
using return_type = ct::return_type_t<T>;
1820

21+
// A simple mp_if doesn't work because both branches always need to be valid.
22+
// With eval_if and eval_if_not the false branch doesn't need to be valid, but
23+
// does need to be expressed in this F, Args... format.
1924
template <typename T>
20-
using function_parameter_types = decltype(detail::parameter_types_impl(std::declval<T>()));
25+
using function_parameter_types = mp11::
26+
mp_eval_if_not<std::is_member_function_pointer<T>, ct::args_t<T>, mp11::mp_rest, ct::args_t<T>>;
2127

2228
template <std::size_t I, typename T>
2329
using function_parameter_type = std::tuple_element_t<I, function_parameter_types<T>>;
@@ -26,37 +32,29 @@ namespace phlex::experimental {
2632
using constructor_parameter_types = typename refl::as_tuple<T>;
2733

2834
template <typename T>
29-
constexpr std::size_t number_parameters = detail::number_parameters_impl<T>;
35+
constexpr std::size_t number_parameters = mp11::mp_size<function_parameter_types<T>>::value;
3036

37+
// Wrapping in a tuple then "flattening" (which just removes one nested inner layer of tuple)
38+
// ensures a single T by itself becomes std::tuple<T> without changing anything that's already
39+
// a tuple.
3140
template <typename T>
32-
constexpr std::size_t number_output_objects = detail::number_output_objects_impl<T>;
33-
34-
using detail::number_types;
35-
36-
namespace detail {
37-
template <typename Head, typename... Tail>
38-
std::tuple<Tail...> skip_first_type_impl(std::tuple<Head, Tail...> const&);
41+
constexpr std::size_t number_types = mp11::mp_size<mp11::mp_flatten<std::tuple<T>>>::value;
3942

40-
template <typename Head, typename... Tail>
41-
std::tuple<Tail...> skip_first_type_impl(std::pair<Head, Tail...> const&);
42-
}
43+
template <typename T>
44+
constexpr std::size_t number_output_objects =
45+
std::same_as<void, return_type<T>> ? 0 : number_types<return_type<T>>;
4346

47+
// mp_apply<std::tuple, ..> converts other wrapper types (e.g. std::pair) to tuple
4448
template <typename Tuple>
45-
using skip_first_type = decltype(detail::skip_first_type_impl(std::declval<Tuple>()));
49+
using skip_first_type = mp11::mp_rest<mp11::mp_apply<std::tuple, Tuple>>;
4650

4751
template <typename T, typename... Args>
4852
struct check_parameters {
4953
using input_parameters = function_parameter_types<T>;
5054
static_assert(std::tuple_size<input_parameters>{} >= sizeof...(Args));
51-
52-
template <std::size_t... Is>
53-
static constexpr bool check_params_for(std::index_sequence<Is...>)
54-
{
55-
return std::conjunction_v<std::is_same<std::tuple_element_t<Is, input_parameters>, Args>...>;
56-
}
57-
55+
static constexpr bool value =
56+
mp11::mp_starts_with<input_parameters, std::tuple<Args...>>::value;
5857
constexpr operator bool() noexcept { return value; }
59-
static constexpr bool value = check_params_for(std::index_sequence_for<Args...>{});
6058
};
6159

6260
// ===================================================================
@@ -66,20 +64,10 @@ namespace phlex::experimental {
6664
template <typename T>
6765
struct is_non_const_lvalue_reference<T const&> : std::false_type {};
6866

67+
// mp_similar<std::atomic<int>, T> just checks if T is an atomic (of any type)
6968
template <typename T>
70-
class remove_atomic {
71-
public:
72-
using type = T;
73-
};
74-
75-
template <typename T>
76-
class remove_atomic<std::atomic<T>> {
77-
public:
78-
using type = T;
79-
};
80-
81-
template <typename T>
82-
using remove_atomic_t = remove_atomic<T>::type;
69+
using remove_atomic_t =
70+
mp11::mp_eval_if_not<mp11::mp_similar<std::atomic<int>, T>, T, mp11::mp_front, T>;
8371

8472
template <typename T>
8573
concept container = requires {

0 commit comments

Comments
 (0)