Last active
October 21, 2016 08:44
-
-
Save MizukiSonoko/0fd001d1c864ce756395762d331d953d 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> | |
#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