Skip to content

Instantly share code, notes, and snippets.

@jbandela
Created May 3, 2013 03:46
Show Gist options
  • Save jbandela/5507074 to your computer and use it in GitHub Desktop.
Save jbandela/5507074 to your computer and use it in GitHub Desktop.
#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