Last active
March 7, 2019 08:48
-
-
Save andijcr/405bf98c60987165deda8fc358bfa349 to your computer and use it in GitHub Desktop.
lazy_loading::DelayProxy : an approach to delay the creation of an object while still permitting to code with it
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
#include <functional> | |
#include <memory> | |
#include <optional> | |
#include <type_traits> | |
#include <utility> | |
namespace lazy { | |
template <typename T> class DelayProxy { | |
std::unique_ptr<T> subject{}; | |
public: | |
template <typename... P> void setup(P &&... v) { | |
subject = std::make_unique<T>(std::forward<P>(v)...); | |
} | |
void reset() { subject.reset(); } | |
template <typename Fn, typename FnRet = std::invoke_result_t<Fn, T &>, | |
typename Ret = std::conditional_t<!std::is_void_v<FnRet>, std::optional<FnRet>, void>> | |
auto operator()(Fn fun) noexcept(std::is_nothrow_invocable_v<Fn, T &>) | |
-> Ret { | |
if (subject) | |
return std::invoke(fun, *subject); | |
if constexpr (!std::is_void_v<FnRet>) | |
return Ret{}; | |
} | |
}; | |
} |
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
#include "lazy_proxy.h" | |
#include <iostream> | |
using namespace lazy; | |
struct SomeClass { | |
int a; | |
int c; | |
SomeClass(int _a, int _c) : a{_a}, c{_c} {} | |
}; | |
void fun() { | |
DelayProxy<SomeClass> delay; | |
auto res = delay([&](auto &sc) -> int { | |
std::cout << "not invoked\n"; | |
std::cout << sc.a << " " << sc.c << "\n"; | |
return sc.a + sc.c; | |
}); | |
std::cout << res.value_or(-1) << "\n"; | |
delay.setup(3, 2); | |
delay([&](auto &sc) { | |
std::cout << "actually invoked\n"; | |
std::cout << sc.a << " " << sc.c << "\n"; | |
}); | |
auto res_v = delay([&](auto &sc) -> int { | |
std::cout << "actually invoked\n"; | |
sc.a *= 3; | |
std::cout << sc.a << " " << sc.c << "\n"; | |
return sc.a + sc.c; | |
}); | |
std::cout << res_v.value_or(-1) << "\n"; | |
delay.setup(7, 11); | |
delay([&](auto &sc) { | |
std::cout << "actually invoked\n"; | |
std::cout << sc.a << " " << sc.c << "\n"; | |
}); | |
std::cout << "now will reset\n"; | |
delay.reset(); | |
auto res_v2 = delay([&](auto &sc) -> int { | |
std::cout << "again, not invoked\n"; | |
sc.a *= 3; | |
std::cout << sc.a << " " << sc.c << "\n"; | |
return sc.a + sc.c; | |
}); | |
std::cout << res_v2.value_or(-1) << "\n"; | |
} | |
int main(){ | |
fun(); | |
} |
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
$ ./lazy_loading | |
-1 | |
actually invoked | |
3 2 | |
actually invoked | |
9 2 | |
11 | |
actually invoked | |
7 11 | |
now will reset | |
-1 | |
$ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment