Last active
August 29, 2015 14:25
-
-
Save hjanetzek/ae30cf83023c8a926d1c to your computer and use it in GitHub Desktop.
This file contains 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
/* | |
clang++-3.6 -DVARIADIC_WRAPPER -O3 -Wall -Wpedantic -std=c++11 variadic.cpp | |
./a.out | |
objdump -j .rodata -j .text -d -S a.out > a.txt | |
clang++-3.6 -O3 -Wall -Wpedantic -std=c++11 variadic.cpp | |
./a.out | |
objdump -j .rodata -j .text -d -S a.out > b.txt | |
meld a.txt b.txt | |
g++ -DVARIADIC_WRAPPER -O3 -Wall -Wpedantic -std=c++11 variadic.cpp | |
./a.out | |
objdump -j .rodata -j .text -d -S a.out > a2.txt | |
g++ -O3 -Wall -Wpedantic -std=c++11 variadic.cpp | |
./a.out | |
objdump -j .rodata -j .text -d -S a.out > b2.txt | |
meld a2.txt b2.txt | |
*/ | |
#include <tuple> | |
#include <iostream> | |
#include <functional> | |
//#define VARIADIC_WRAPPER 1 | |
//#define NO_INLINE | |
#define NO_INLINE __attribute__((noinline)) | |
#ifdef VARIADIC_WRAPPER | |
NO_INLINE void foo(int x, int y) { | |
std::cout << "A" << x << ":" << y << std::endl; | |
} | |
template<int ...> | |
struct seq {}; | |
template<int N, int ...S> | |
struct gens : gens<N-1, N-1, S...> {}; | |
template<int ...S> | |
struct gens<0, S...> { | |
typedef seq<S...> type; | |
}; | |
template <typename F, F f, typename ...Args> | |
struct State { | |
using Type = std::tuple<Args...>; | |
Type params; | |
NO_INLINE void operator()(Args... _param) { | |
auto _params = std::make_tuple(_param...); | |
if (_params != params) { | |
params = _params; | |
call(typename gens<sizeof...(Args)>::type()); | |
} | |
} | |
template<int ...S> | |
void call(seq<S...>) { | |
f(std::get<S>(params) ...); | |
} | |
}; | |
int main(void) { | |
State<decltype((foo)), foo, int, int> state; | |
state(1,2); | |
state(1,2); | |
state(2,2); | |
} | |
#else | |
NO_INLINE void baz(int x, int y) { | |
std::cout << "B" << x << ":" << y << std::endl; | |
} | |
template <typename T> | |
class State { | |
public: | |
void init(const typename T::Type& _default) { | |
T::set(_default); | |
m_current = _default; | |
} | |
NO_INLINE void operator()(const typename T::Type& _value) { | |
if (m_current != _value) { | |
m_current = _value; | |
T::set(m_current); | |
} | |
} | |
private: | |
typename T::Type m_current; | |
}; | |
struct Test { | |
struct Type { | |
int x; int y; | |
bool operator!=(const Type& _other) { return x != _other.x || y != _other.y;} | |
}; | |
inline static void set(const Type& _type) { | |
baz(_type.x, _type.y); | |
} | |
}; | |
int main(void) { | |
State<Test> state; | |
state({1,2}); | |
state({1,2}); | |
state({2,2}); | |
} | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment