Check that static method exists
struct SOME_STRUCT {
static int doIt(int a, float b) {
return 0;
}
};
template<typename T> struct HAS_DO_IT {
static int has(int (*doIt)(int, float)) {}
static char has(...) {}
static const int value = sizeof(decltype(has(T::doIt))) == sizeof(int);
};
TEST_CASE("A") {
printf("%d", HAS_DO_IT<SOME_STRUCT>::value);
}
Things to remember for template type deduction
template<typename T> struct DEDUCTED_TYPE {
typedef T type;
};
TEST_CASE("Type Deduction") {
// i
std::cout << typeid(DEDUCTED_TYPE<int>::type).name() << std::endl;
// Pi
std::cout << typeid(DEDUCTED_TYPE<int*>::type).name() << std::endl;
// i
std::cout << typeid(DEDUCTED_TYPE<int&>::type).name() << std::endl;
// i
std::cout << typeid(DEDUCTED_TYPE<const int>::type).name() << std::endl;
// PKI
std::cout << typeid(DEDUCTED_TYPE<const int*>::type).name() << std::endl;
// i
std::cout << typeid(DEDUCTED_TYPE<const int&>::type).name() << std::endl;
// i
std::cout << typeid(DEDUCTED_TYPE<volatile const int>::type).name() << std::endl;
// PVKi
std::cout << typeid(DEDUCTED_TYPE<volatile const int*>::type).name() << std::endl;
// i
std::cout << typeid(DEDUCTED_TYPE<volatile const int&>::type).name() << std::endl;
// i
std::cout << typeid(DEDUCTED_TYPE<volatile const int&&>::type).name() << std::endl;
}
Template Class Members
struct Bla {
int id;
};
template<typename M, M member, typename T>
struct MemberSetter1 {
using type = typename std::decay<decltype(T{}.*member)>::type;
template<class C, typename Z>
static Z* getPointerType(Z C::*v){return 0;}
using member_type = typename
std::decay<decltype(getPointerType(member))>::type;
static void set(T &t, type value) {
t.*member = value;
}
static type get(T &t) {
return t.*member;
}
};
TEST_CASE("BIND_TAG_#1") {
Bla b;
// Here template types get deduced to:
// M = int Bla::*
// member = &Bla::id
// MemberSetter::member_type becomes int, first way to obtain member type
// MemberSetter::type becomes int, second way to obtain member type
MemberSetter1<decltype(&Bla::id), &Bla::id, Bla> bind;
bind.set(b, 1);
std::cout << bind.get(b) << std::endl;
}
Deducing Function Argument Type
template <typename A>
static A* deduceType(Result<bool> (*)(A&, ConstBufferIterator)) {return 0;}
using argument_type = typename
std::remove_pointer<decltype(deduceType(Class::static_method))>::type;
Feature Flags
enum class FF {
A, B, C
};
template<bool v, FF a, FF b, FF ... rem>
struct _$_HasFF : _$_HasFF<v || a == b, a, rem...> {
};
template<bool v, FF a, FF b>
struct _$_HasFF<v, a, b> {
static const bool value = v || a == b;
};
template <FF a, FF...rem>
struct HasFF : _$_HasFF<false, a, rem...>{
};
TEST_CASE("Feature Flags") {
std::cout << HasFF<FF::C, FF::A, FF::B>::value << std::endl;
}
Iterating over variadic template arguments in function
template<size_t L,size_t i, typename BINDING, typename ... REMAINING_BINDINGS>
static typename std::enable_if<i < L, bool>::type requiredBindingsAreSet(bool (&fields)[L]) {
if(L == i) {
return true;
} else if(!fields[i] && BINDING::isRequired)
return false;
else
requiredBindingsAreSet<L, i+1, REMAINING_BINDINGS...>(fields);
}
template<size_t L,size_t i>
static typename std::enable_if<L == i, bool>::type requiredBindingsAreSet(bool (&fields)[L]) {
return true;
}