Created
May 3, 2013 03:46
-
-
Save jbandela/5507074 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
#include <iostream> | |
#include <string> | |
// Reusable | |
template<int i, class T> | |
struct optional_type{ | |
enum{ pos = i}; | |
typedef T value_type; | |
T val_; | |
const T& value()const{return val_;} | |
optional_type(T rv):val_(rv){} | |
optional_type():val_(){} | |
}; | |
template<int i, class T> | |
struct required_type{ | |
enum{ pos = i}; | |
typedef T value_type; | |
T val_; | |
const T& value()const{return val_;} | |
required_type(T rv):val_(rv){} | |
private: | |
required_type(); | |
}; | |
template<int i, class T,class F> | |
struct defaulted_type{ | |
enum{ pos = i}; | |
typedef T value_type; | |
F f; | |
T val_; | |
const T& value()const{return val_;} | |
defaulted_type(T rv):val_(rv){} | |
defaulted_type():val_(f()){} | |
}; | |
template<class... Args> | |
struct arg_holder:public Args...{ | |
template<class T> | |
const typename T::value_type& get()const{ | |
const T* ret = this; | |
return ret ->value(); | |
} | |
template<class... T> | |
arg_holder(T... t):T(t)...{}; | |
template<class R = void, class F = R (*)(typename Args::value_type...)> | |
R forward_to_function(F f)const{ | |
f(get<Args>()...); | |
} | |
}; | |
// What you need to implement for a function | |
struct user_arg_default{ | |
std::string operator()(){return "Somebody";}; | |
}; | |
typedef optional_type<0,int> value; | |
typedef defaulted_type<1,std::string,user_arg_default> user; | |
typedef required_type<2,int> required; | |
// Use the values directly | |
void greet(const arg_holder<value,user,required>& a){ | |
std::cout << "Hello " << a.get<user>() << " the value is " << a.get<value>() | |
<< " Required " << a.get<required>() << std::endl; | |
} | |
// Regular function | |
void greet2(int v, std::string u, int r){ | |
std::cout << "Hello from great2 " << u << " the value is " << v | |
<< " Required " << r << std::endl; | |
} | |
// wrapper to send named parameters to regular function | |
void greet2(const arg_holder<value,user,required>& a){ | |
a.forward_to_function(greet2); | |
} | |
int main(){ | |
greet({required(11)}); | |
greet({required(11),value(10)}); | |
greet({user("John"),required(11),value(10)}); | |
greet({required(11),user("John")}); | |
// the required parameter is required, if you uncomment below, you will get an error | |
//greet({}); | |
//greet({value(10)}); | |
//greet({user("John"),value(10)}); | |
//greet({user("John")}); | |
greet2({required(11),user("John")}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment