Skip to content

Instantly share code, notes, and snippets.

@mrk21
Last active August 29, 2015 14:11
Show Gist options
  • Save mrk21/50f361bf3614b27a87ef to your computer and use it in GitHub Desktop.
Save mrk21/50f361bf3614b27a87ef to your computer and use it in GitHub Desktop.
Variadic Templates: Test
#include <iostream>
#include <memory>
#include <functional>
#include <type_traits>
#include <boost/optional.hpp>
struct manager {
int id = 0;
};
struct item {
using manager_t = boost::optional<manager &>;
item(int , manager_t m = boost::none) { this->display("item(int [, manager])", m); }
item( std::string, manager_t m = boost::none) { this->display("item( std::string[, manager])", m); }
item(int, std::string, manager_t m = boost::none) { this->display("item(int, std::string[, manager])", m); }
void display(std::string name, manager_t m) {
std::cout << name;
if (m) std::cout << " with manager(id: " << m->id << ")";
std::cout << std::endl;
}
};
struct data {
using block_type = std::function<void(manager &)>;
std::shared_ptr<manager> manager_;
std::shared_ptr<item> item_;
template <typename... Types>
void init(Types... args) {
this->item_ = std::make_shared<item>(
Arg<Types>::value(this, args)...
);
}
template <typename T, bool Enabler = std::is_convertible<T, block_type>::value>
struct Arg {
static T const & value(data *, T const & v) {
return v;
}
};
template <typename T>
struct Arg<T, true> {
static manager & value(data * that, block_type block) {
that->manager_ = std::make_shared<manager>();
if (block) block(*that->manager_);
return *that->manager_;
}
};
};
int main() {
data d;
d.init(1 ); d.init(1 , [](manager & m){ m.id = 1; });
d.init( "a"); d.init( "a", [](manager & m){ m.id = 2; });
d.init(1,"a"); d.init(1,"a", [](manager & m){ m.id = 3; });
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment