21namespace plot::impl::compat {
26 nonesuch( nonesuch
const& ) =
delete;
27 void operator = ( nonesuch
const& ) =
delete;
30 template<
class... >
using void_t = void;
32 template <
class Default,
class AlwaysVoid,
33 template<
class...>
class Op,
class... Args>
35 using value_t = std::false_type;
39 template <
class Default,
template<
class...>
class Op,
class... Args>
40 struct detector<Default, std::void_t<Op<Args...>>, Op, Args...> {
41 using value_t = std::true_type;
42 using type = Op<Args...>;
46 template <
template<
class...>
class Op,
class... Args>
47 using is_detected =
typename detail::detector<nonesuch, void, Op, Args...>::value_t;
49 template <
template<
class...>
class Op,
class... Args>
50 using detected_t =
typename detail::detector<nonesuch, void, Op, Args...>::type;
52 template <
class Default,
template<
class...>
class Op,
class... Args>
53 using detected_or = detail::detector<Default, void, Op, Args...>;
56 template<
template<
class...>
class Op,
class... Args >
57 constexpr bool is_detected_v = is_detected<Op, Args...>::value;
58 template<
class Default,
template<
class...>
class Op,
class... Args >
59 using detected_or_t =
typename detected_or<Default, Op, Args...>::type;
60 template <
class Expected,
template<
class...>
class Op,
class... Args>
61 using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>;
62 template <
class Expected,
template<
class...>
class Op,
class... Args>
63 constexpr bool is_detected_exact_v = is_detected_exact<Expected, Op, Args...>::value;
64 template <
class To,
template<
class...>
class Op,
class... Args>
65 using is_detected_convertible = std::is_convertible<detected_t<Op, Args...>, To>;
66 template <
class To,
template<
class...>
class Op,
class... Args>
67 constexpr bool is_detected_convertible_v = is_detected_convertible<To, Op, Args...>::value;
70namespace plot::impl::detail {
71 template <std::size_t S,
class callable_t, std::size_t ...Is>
72 constexpr void static_for( callable_t&& callback, std::integer_sequence<std::size_t, Is...> ){
73 ( callback( std::integral_constant<std::size_t, S + Is>{ } ),... );
80 template <
class tuple_t, std::
size_t S = 0,
class callable_t >
81 constexpr void static_for( callable_t&& callback ){
82 constexpr std::size_t N = std::tuple_size<tuple_t>::value;
83 detail::static_for<S, callable_t>(
84 std::forward<callable_t>(callback),
85 std::make_integer_sequence<std::size_t, N - S>{ } );
90 using plot::impl::compat::is_detected;
91 template<
class T>
using value_t =
typename T::value_type;
92 template<
class T>
using get_value_type = compat::detected_or<compat::nonesuch, value_t, T>;
93 template<
class T>
using has_value_type = is_detected<value_t, T>;
95 template <
class T,
class TagOrClass,
class E =
void>
struct is_value_type {
96 constexpr static bool value =
false;
99 template <
class T,
class TagOrClass>
struct is_value_type <T, TagOrClass,
100 typename std::enable_if<has_value_type<T>::value>::type > {
101 constexpr static bool value = std::is_convertible<typename impl::get_value_type<T>::type, TagOrClass>::value;
104 template <
class T,
class TagOrClass>
struct is_value_type <T, TagOrClass,
105 typename std::enable_if<!has_value_type<T>::value>::type > {
106 constexpr static bool value = std::is_convertible<T, TagOrClass>::value;
112 struct optional :
public std::optional<T> {
113 using std::optional<T>::optional;
119 template<
class S,
class... T >
struct tpos;
122 template<
class search_pattern,
int position,
int count,
bool branch,
class prev_head,
class arguments>
struct tuple_pos;
124 template<
class S,
int P,
int C,
bool B,
class not_used,
class... Tail >
125 struct tuple_pos<S, P,C, B, not_used, std::tuple<Tail...>>
126 : tuple_pos<S, P,C, false, not_used, std::tuple<Tail...>> { };
128 template<
class S,
int P,
int C,
class not_used,
class Head,
class... Tail >
129 struct tuple_pos<S, P,C,false, not_used, std::tuple<Head, Tail...>>
130 : tuple_pos<S, P+1,C, impl::is_value_type<Head,S>::value,
131 Head, std::tuple<Tail...>> { };
133 template<
class S,
int P,
int C,
class Type,
class... Tail >
134 struct tuple_pos<S, P,C, true, Type, std::tuple<Tail...>>
135 : std::integral_constant<int,P>{
136 static constexpr int position = P;
138 static constexpr bool present =
true;
141 template<
class S,
class H,
int P,
int C>
142 struct tuple_pos<S, P,C, false, H, std::tuple<>>
143 : std::integral_constant<int,-1> {
145 static constexpr bool present =
false;
148 template<
class S,
class... args_t >
struct tpos
149 : detail::tuple_pos<const S&, -1, 0, false, void, std::tuple<args_t...>>{ };
152 template <
class T,
class... args_t,
153 class idx_t = tpos<
typename T::value_type, args_t...>>
154 typename std::enable_if<impl::has_value_type<T>::value, arg::optional<T>
155 >::type get( args_t... args ){
156 auto tuple = std::forward_as_tuple( args... );
157 if constexpr ( idx_t::present )
158 return std::get<idx_t::value>( tuple );
163 template <
class T,
class... args_t,
class idx_t = tpos<T, args_t...>>
164 constexpr typename std::enable_if<!impl::has_value_type<T>::value,
165 typename idx_t::type>::type get( args_t... args ){
166 auto tuple = std::forward_as_tuple( args... );
167 if constexpr ( idx_t::present )
168 return std::get<idx_t::value>( tuple );
173 template <
class T,
class... args_t,
class idx_t = tpos<T, args_t...>>
174 typename std::enable_if<!impl::has_value_type<T>::value,
175 typename idx_t::type>::type required(
const char msg[3], args_t... args ) {
176 auto tuple = std::forward_as_tuple( args... );
177 if constexpr ( idx_t::present )
178 return std::get<idx_t::value>( tuple );
180 static_assert( idx_t::present );
185 template <
int idx,
class... args_t>
186 typename std::tuple_element<idx, std::tuple<args_t...> >::type&
187 getn(args_t&&... args ){
188 auto tuple = std::forward_as_tuple(args...);
189 return std::get<idx>( tuple );
193 template<
typename T>
struct fn_t;
194 template<
typename R,
typename ...Args>
195 struct fn_t<std::function<R(Args...)>> {
196 static const std::size_t nargs =
sizeof...(Args);
197 typedef R result_type;
199 template <std::
size_t I>
201 typedef typename std::tuple_element<I, std::tuple<Args...>>::type type;