Skip to content

Instantly share code, notes, and snippets.

@MizukiSonoko
Last active October 21, 2016 08:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MizukiSonoko/0fd001d1c864ce756395762d331d953d to your computer and use it in GitHub Desktop.
Save MizukiSonoko/0fd001d1c864ce756395762d331d953d to your computer and use it in GitHub Desktop.
#include <iostream>
#include <string>
#include <type_traits>
struct Rules {
struct violation {};
struct false_type { static const bool value = false; };
struct true_type { static const bool value = true; };
// Rule 1: has "std::string getName()"
template<typename T,std::string (T::*)()>
struct has_getName_helper_t { typedef violation type; };
template<typename T,typename U = violation>
struct has_getName : public false_type {};
template<typename T>
struct has_getName<T,typename has_getName_helper_t<T,&T::getName>::type> : public true_type {};
// Rule 2: has "int toInt(std::string)"
template<typename T,int (T::*)(std::string)>
struct has_toInt_helper_t { typedef violation type; };
template<typename T,typename U = violation>
struct has_toInt : public false_type {};
template<typename T>
struct has_toInt<T,typename has_toInt_helper_t<T,&T::toInt>::type> : public true_type {};
// Rule 2: has "int value"
template<typename T,int T::*>
struct has_int_value_helper_t { typedef violation type; };
template<typename T,typename U = violation>
struct has_int_value : public false_type {};
template<typename T>
struct has_int_value<T,typename has_int_value_helper_t<T,&T::value>::type> : public true_type {};
};
template<typename... rule_set>
struct Requires {
template<int, typename rule, typename... rule_set_>
struct next {
static const bool value = rule::value && next<sizeof...(rule_set_),rule_set_...>::value;
};
template<typename rule>
struct next< 1,rule> {
static const bool value = rule::value;
};
static const bool value = next<sizeof...(rule_set),rule_set...>::value;
};
template<typename rule>
struct Not{
static const bool value = !rule::value;
};
template<typename T> struct validator_all : public Requires<
Rules::has_getName<T>,
Rules::has_toInt<T>,
Rules::has_int_value<T>
> {};
template<typename T> struct validator_method : public Requires<
Rules::has_getName<T>,
Rules::has_toInt<T>
> {};
template<typename T> struct validator_variable : public Requires<
Rules::has_int_value<T>
> {};
template<typename T> struct validator_not_method: public Requires<
Not<Rules::has_getName<T>>,
Not<Rules::has_toInt<T>>
> {};
class A {
public:
int value;
};
class B {
public:
std::string getName(){ return "Mizuki"; }
int toInt(std::string s){ return std::atoi(s.c_str()); }
};
class C {
public:
int value;
std::string getName(){ return "Mizuki"; }
int toInt(std::string s){ return std::atoi(s.c_str()); }
};
int main(){
std::cout<<"Does A have require condition? "<< validator_all<A>::value << std::endl;
std::cout<<"Does B have require condition? "<< validator_all<B>::value << std::endl;
std::cout<<"Does C have require condition? "<< validator_all<C>::value << std::endl;
std::cout<<"Does A have require methods? "<< validator_method<A>::value << std::endl;
std::cout<<"Does B have require methods? "<< validator_method<B>::value << std::endl;
std::cout<<"Does C have require methods? "<< validator_method<C>::value << std::endl;
std::cout<<"Does A have require variable? "<< validator_variable<A>::value << std::endl;
std::cout<<"Does B have require variable? "<< validator_variable<B>::value << std::endl;
std::cout<<"Does C have require variable? "<< validator_variable<C>::value << std::endl;
std::cout<<"Does 'not' A have require metod? "<< validator_not_method<A>::value << std::endl;
std::cout<<"Does 'not' B have require metod? "<< validator_not_method<B>::value << std::endl;
std::cout<<"Does 'not' C have require metod? "<< validator_not_method<C>::value << std::endl;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment