Skip to content

Instantly share code, notes, and snippets.

@ecatmur
Created January 31, 2013 14:23
Show Gist options
  • Save ecatmur/4683170 to your computer and use it in GitHub Desktop.
Save ecatmur/4683170 to your computer and use it in GitHub Desktop.
#include <iostream>
template<typename T, typename U> class wrapped_value {
T t;
U u;
wrapped_value(T t, U u): t(std::move(t)), u(std::move(u)) {}
public:
explicit operator bool() const { return u; }
friend T &unwrap(wrapped_value &w) { return w.t; }
template<typename T2, typename V> friend class wrapped_value;
template<typename F> auto bind(F &&f)
-> wrapped_value<T, decltype(f(std::declval<U>()))> {
return {std::move(t), f(u)}; }
};
template<typename T> wrapped_value<T, T> wrap(T &&t) { return {t}; }
template<typename T> class wrapped_value<T, T> {
T t;
wrapped_value(T t): t(std::move(t)) {}
public:
friend wrapped_value wrap<>(T &&t);
template<typename F> auto bind(F &&f)
-> wrapped_value<T, decltype(f(std::declval<T>()))> {
auto &&v = f(t); return {std::move(t), v}; }
};
template<typename T, typename U, typename V>
auto operator>(wrapped_value<T, U> &&w, V &&v)
-> wrapped_value<T, decltype(std::declval<U>() > v)> {
return w.bind([v](const U &u) { return u > v; }); }
int main() {
for (auto i: {9, 10, 11, 12}) {
if (auto value = wrap(i * 10).bind([](int x) { return x > 100; }))
std::cout << i << ' ' << unwrap(value) << '\n';
if (auto value = wrap(i * 11) > 99)
std::cout << i << ' ' << unwrap(value) << '\n';
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment