Created
November 13, 2017 20:29
-
-
Save mtao/cff91eccb16da687ef0752b46a943ef0 to your computer and use it in GitHub Desktop.
a bizarre (working) attempt at getting c++ to "see" the functions on the lhs of an equals sign.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <tuple> | |
#include <functional> | |
#include <iostream> | |
template <int N> | |
struct int_c {constexpr static int value = N;}; | |
template <typename CallType> | |
void f() {}; | |
template <int... N> | |
auto seq(std::integer_sequence<int,N...>) { | |
return std::make_tuple(N...); | |
} | |
template <int N> | |
auto f(int_c<N> ) { | |
return seq(std::make_integer_sequence<int,N>()); | |
} | |
struct Return {}; | |
template <typename CallType> | |
struct func { | |
template <typename... Args, int... N> | |
auto add(std::integer_sequence<int,N...>, Args... args) { | |
return std::make_tuple((args + N)...); | |
} | |
template <typename... Args> | |
auto operator()(Args... args) { | |
if constexpr(std::is_same<CallType, Return>::value) { | |
return std::make_tuple(std::forward<Args>(args)...); | |
} else { | |
return add(std::make_integer_sequence<int,CallType::value>(), std::forward<Args>(args)...); | |
} | |
} | |
}; | |
template <template<typename> typename Func, typename... Args> | |
struct left_aware_func { | |
left_aware_func(Args... a): inputs{std::forward<Args>(a)...} {} | |
constexpr static int size() { return sizeof...(Args); } | |
std::tuple<Args...> inputs; | |
}; | |
template <template<typename> typename Func, typename... Args> | |
auto make_laf(Args... a) { | |
return left_aware_func<Func,Args...>(std::forward<Args>(a)...); | |
} | |
template <typename CallType, typename... Args> | |
struct tied_caller { | |
tied_caller(tied_caller<CallType, Args...>&& other) = default; | |
tied_caller(Args&... a) { | |
set_ptrs(std::make_integer_sequence<int,sizeof...(Args)>(),std::forward<Args&>(a)...); | |
} | |
template <int... N> | |
void set_ptrs( std::integer_sequence<int,N...>, Args&... a) { | |
(set_ptr(std::get<N>(args),a),...); | |
} | |
template <typename T> | |
void set_ptr(T*& a, T& b) { | |
a = &b; | |
} | |
constexpr static int size() { | |
return sizeof...(Args); | |
} | |
template <template<typename> typename Func, typename... Args2> | |
tied_caller& operator=(const left_aware_func<Func,Args2...>& laf) { | |
return assign_laf(laf, std::make_integer_sequence<int,sizeof...(Args2)>()); | |
} | |
template <template<typename> typename Func, typename... Args2, int... N> | |
tied_caller& assign_laf(const left_aware_func<Func,Args2...>& laf, std::integer_sequence<int,N...>) { | |
return operator=(Func<CallType>()(std::get<N>(laf.inputs)...)); | |
} | |
tied_caller& operator=(const std::tuple<Args...>& t) { | |
assign(t,std::make_integer_sequence<int,size()>()); | |
return *this; | |
} | |
template <typename A, typename B> | |
void set(A* a, const B& b) { | |
*a = b; | |
} | |
template <typename... Args2, int... N> | |
void assign(const std::tuple<Args2...> &t, std::integer_sequence<int,N...>) { | |
(set(std::get<N>(args),std::get<N>(t)), ...); | |
} | |
std::tuple<typename std::add_pointer<Args>::type...> args; | |
}; | |
template <typename... Args> | |
auto tied_call(Args&... args) { | |
return tied_caller<int_c<sizeof...(Args)>,Args...>(std::forward<Args&>(args)...); | |
}; | |
template <typename T, typename... Args> | |
auto tied_callc(Args&... args) { | |
return tied_caller<T,Args...>(std::forward<Args&>(args)...); | |
}; | |
int main() { | |
int a, b, c; | |
tied_call(a,b) = std::make_tuple<int,int>(2,3); | |
std::cout << a << " " << b << std::endl; | |
tied_call(a,b) = make_laf<func>(0,0); | |
std::cout << a << " " << b << std::endl; | |
tied_call(a,b) = make_laf<func>(10,11); | |
std::cout << a << " " << b << std::endl; | |
tied_call(a,b,c) = make_laf<func>(0,0,0); | |
std::cout << a << " " << b << " " << c << std::endl; | |
tied_call(a,b,c) = make_laf<func>(4,3,2); | |
std::cout << a << " " << b << " " << c << std::endl; | |
tied_callc<Return>(a,b,c) = make_laf<func>(4,3,2); | |
std::cout << a << " " << b << " " << c << std::endl; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment