Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <memory>
- #include <stdexcept>
- using namespace std;
- template <typename UnusedType>
- class OneTimer;
- template <typename ReturnType, typename ... ArgumentTypes>
- class OneTimer <ReturnType (ArgumentTypes ...)>
- {
- public:
- typedef ReturnType signature_type (ArgumentTypes ...);
- // OneTimer() : mInvoker() { }
- template <typename FunctionT>
- OneTimer(FunctionT f)
- : mInvoker(new free_function_holder<FunctionT>(f)), mUsable(true)
- {
- }
- template <typename FunctionType, typename ClassType>
- OneTimer(FunctionType ClassType::* f)
- : mInvoker(new member_function_holder<FunctionType, ArgumentTypes ...>(f)), mUsable(true)
- {
- }
- OneTimer(const OneTimer & other)
- : mInvoker(other.mInvoker->clone()), mUsable(other.mUsable)
- {
- }
- OneTimer & operator = (const OneTimer & other)
- {
- mInvoker = other.mInvoker->clone();
- mUsable = other.mUsable;
- }
- ReturnType operator ()(ArgumentTypes ... args)
- {
- if (mUsable) {
- mUsable = false;
- return mInvoker->invoke(args ...);
- }
- throw std::runtime_error("Poshel nahuy");
- }
- private:
- class function_holder_base
- {
- public:
- function_holder_base()
- {
- }
- virtual ~function_holder_base()
- {
- }
- virtual ReturnType invoke(ArgumentTypes ... args) = 0;
- virtual std::shared_ptr<function_holder_base> clone() = 0;
- private:
- function_holder_base(const function_holder_base & );
- void operator = (const function_holder_base &);
- };
- typedef std::shared_ptr<function_holder_base> invoker_t;
- template <typename FunctionT>
- class free_function_holder : public function_holder_base
- {
- public:
- free_function_holder(FunctionT func)
- : function_holder_base(),
- mFunction(func)
- {
- }
- virtual ReturnType invoke(ArgumentTypes ... args)
- {
- return mFunction(args ...);
- }
- virtual invoker_t clone()
- {
- return invoker_t(new free_function_holder(mFunction));
- }
- private:
- FunctionT mFunction;
- };
- template <typename FunctionType, typename ClassType, typename ... RestArgumentTypes>
- class member_function_holder : public function_holder_base
- {
- public:
- typedef FunctionType ClassType::* member_function_signature_t;
- member_function_holder(member_function_signature_t f)
- : mFunction(f)
- {}
- virtual ReturnType invoke(ClassType obj, RestArgumentTypes ... restArgs)
- {
- return (obj.*mFunction)(restArgs ...);
- }
- virtual invoker_t clone()
- {
- return invoker_t(new member_function_holder(mFunction));
- }
- private:
- member_function_signature_t mFunction;
- };
- bool mUsable;
- invoker_t mInvoker;
- };
- int random() {
- return 42;
- }
- struct {
- int i = 0;
- int operator()() {return ++i; }
- } functor1;
- class functor2 {
- static int i;
- public:
- static int get() { i += 3; return i; }
- };
- int functor2::i = 0;
- class functor3 {
- int i = 0;
- public:
- int get() { i += 10; return i; }
- } ff;
- int main() {
- OneTimer<int()> a = random; // pointer to a generic function
- // OneTimer<int()> a = []() { return 666; }; // lambda
- // OneTimer<int()> a = functor1; // functor
- // OneTimer<int()> a = &functor2::get; // pointer to a class function
- // OneTimer<int()> a = std::bind(&functor3::get, &ff); // function of a specific class object
- for (int i = 0; i < 10; ++i) {
- try {
- std::cout << a() << std::endl;
- } catch(std::runtime_error &e) {
- std::cerr << e.what() << std::endl;
- }
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement