Skip to content

Instantly share code, notes, and snippets.

@xkikeg
Last active August 29, 2015 14:04
Show Gist options
  • Save xkikeg/2b1ca23aa5a6469738ba to your computer and use it in GitHub Desktop.
Save xkikeg/2b1ca23aa5a6469738ba to your computer and use it in GitHub Desktop.
型の包含関係を調べるテンプレート
// for test
#include <memory>
#include <string>
#include <vector>
#include "type_inclusion.hh"
#define TO_STR(x) TO_STR_(x)
#define TO_STR_(x) #x
#define STATIC_ASSERT_SIMPLE(x) static_assert(x, TO_STR(x));
STATIC_ASSERT_SIMPLE((!is_one_of_types<int>::value));
STATIC_ASSERT_SIMPLE((!is_one_of_types<int, float>::value));
STATIC_ASSERT_SIMPLE((!is_one_of_types<int, char, float>::value));
STATIC_ASSERT_SIMPLE((is_one_of_types<int, int>::value));
STATIC_ASSERT_SIMPLE((is_one_of_types<int, char, int>::value));
STATIC_ASSERT_SIMPLE((is_one_of_types<int, int, char>::value));
STATIC_ASSERT_SIMPLE((is_one_of_types<std::unique_ptr<int>, std::unique_ptr<int> >::value));
STATIC_ASSERT_SIMPLE((!is_one_of_types<std::unique_ptr<int>, std::unique_ptr<char> >::value));
STATIC_ASSERT_SIMPLE((includes<includes_holder<>, includes_holder<> >::value));
STATIC_ASSERT_SIMPLE((includes<includes_holder<int>, includes_holder<int> >::value));
STATIC_ASSERT_SIMPLE((!includes<includes_holder<int>, includes_holder<long long> >::value));
STATIC_ASSERT_SIMPLE((includes<includes_holder<int, long long>, includes_holder<long long, int> >::value));
STATIC_ASSERT_SIMPLE((includes<includes_holder<int, long long>, includes_holder<int, long long> >::value));
STATIC_ASSERT_SIMPLE((includes<includes_holder<int, long long, char>, includes_holder<long long, int> >::value));
STATIC_ASSERT_SIMPLE((!includes<includes_holder<int, long long>, includes_holder<int, long long, char> >::value));
STATIC_ASSERT_SIMPLE((!includes<includes_holder<int, std::string>, includes_holder<int, std::string, long long, char> >::value));
STATIC_ASSERT_SIMPLE((!includes<includes_holder<int, std::string>, includes_holder<int, std::vector<int>, long long, char> >::value));
int main(){
return 0;
}
#include <type_traits>
template<typename ...Args>
struct is_one_of_types;
template<typename T>
struct is_one_of_types<T> : public std::false_type {};
template<typename T, typename U, typename ...Args>
struct is_one_of_types<T, U, Args...> : public
std::conditional<std::is_same<T, U>::value,
std::true_type,
is_one_of_types<T, Args...> >::type {};
template<typename ...Args>
struct includes_holder {
template<typename U>
static typename std::conditional<
is_one_of_types<U, Args...>::value,
std::true_type, std::false_type>::type has_type();
};
template<typename Lhs, typename Rhs>
struct includes;
template<typename Lhs>
struct includes<Lhs, includes_holder<> > : public std::true_type {};
template<typename Lhs, typename T, typename ...Args>
struct includes<Lhs, includes_holder<T, Args...> > : public
std::conditional<
decltype(Lhs::template has_type<T>())::value && includes<Lhs, includes_holder<Args...> >::value,
std::true_type, std::false_type>::type {};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment