2016-05-17 03:04:11 +12:00
|
|
|
#pragma once
|
2016-03-19 06:57:51 +13:00
|
|
|
|
|
|
|
#ifndef TCG_SFINAE_H
|
|
|
|
#define TCG_SFINAE_H
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\file sfinae.h
|
|
|
|
|
|
|
|
\brief Contains template metafunctions that can be used to enable or
|
|
|
|
disable template class members.
|
|
|
|
|
|
|
|
\details SFINAE (Substitution Failure Is Not An Error) is a C++ \a feature
|
|
|
|
that allows the compiler to silently discard failures in template
|
|
|
|
function instantiations during function overload resolution.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#if defined(__APPLE_CC__)
|
|
|
|
#include <type_traits>
|
|
|
|
#endif
|
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
namespace tcg {
|
2016-03-19 06:57:51 +13:00
|
|
|
|
|
|
|
template <typename X, typename Y>
|
|
|
|
struct type_match {
|
2016-06-15 18:43:10 +12:00
|
|
|
enum { value = false };
|
2016-03-19 06:57:51 +13:00
|
|
|
};
|
|
|
|
|
|
|
|
template <typename X>
|
|
|
|
struct type_match<X, X> {
|
2016-06-15 18:43:10 +12:00
|
|
|
enum { value = true };
|
2016-03-19 06:57:51 +13:00
|
|
|
};
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
|
|
|
|
|
|
template <typename X, typename Y>
|
|
|
|
struct type_mismatch {
|
2016-06-15 18:43:10 +12:00
|
|
|
enum { value = true };
|
2016-03-19 06:57:51 +13:00
|
|
|
};
|
|
|
|
|
|
|
|
template <typename X>
|
|
|
|
struct type_mismatch<X, X> {
|
2016-06-15 18:43:10 +12:00
|
|
|
enum { value = false };
|
2016-03-19 06:57:51 +13:00
|
|
|
};
|
|
|
|
|
|
|
|
//========================================================================
|
|
|
|
|
|
|
|
template <typename T, typename B>
|
|
|
|
struct enable_if_exists {
|
2016-06-15 18:43:10 +12:00
|
|
|
typedef B type;
|
2016-03-19 06:57:51 +13:00
|
|
|
};
|
|
|
|
|
|
|
|
//========================================================================
|
|
|
|
|
|
|
|
template <bool, typename T = void>
|
2016-06-15 18:43:10 +12:00
|
|
|
struct enable_if {};
|
2016-03-19 06:57:51 +13:00
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
struct enable_if<true, T> {
|
2016-06-15 18:43:10 +12:00
|
|
|
typedef T type;
|
2016-03-19 06:57:51 +13:00
|
|
|
};
|
|
|
|
|
|
|
|
//========================================================================
|
|
|
|
|
|
|
|
template <bool, typename T = void>
|
|
|
|
struct disable_if {
|
2016-06-15 18:43:10 +12:00
|
|
|
typedef T type;
|
2016-03-19 06:57:51 +13:00
|
|
|
};
|
|
|
|
|
|
|
|
template <typename T>
|
2016-06-15 18:43:10 +12:00
|
|
|
struct disable_if<true, T> {};
|
2016-03-19 06:57:51 +13:00
|
|
|
|
|
|
|
//========================================================================
|
|
|
|
|
|
|
|
template <bool, typename TrueT, typename FalseT = void>
|
|
|
|
struct choose_if;
|
|
|
|
|
|
|
|
template <typename TrueT, typename FalseT>
|
|
|
|
struct choose_if<true, TrueT, FalseT> {
|
2016-06-15 18:43:10 +12:00
|
|
|
typedef TrueT type;
|
2016-03-19 06:57:51 +13:00
|
|
|
};
|
|
|
|
|
|
|
|
template <typename TrueT, typename FalseT>
|
|
|
|
struct choose_if<false, TrueT, FalseT> {
|
2016-06-15 18:43:10 +12:00
|
|
|
typedef FalseT type;
|
2016-03-19 06:57:51 +13:00
|
|
|
};
|
|
|
|
|
|
|
|
//========================================================================
|
|
|
|
|
|
|
|
template <typename T, typename MatchT, typename NotMatchedT = void>
|
|
|
|
struct choose_if_match {
|
2016-06-15 18:43:10 +12:00
|
|
|
typedef NotMatchedT type;
|
2016-03-19 06:57:51 +13:00
|
|
|
};
|
|
|
|
|
|
|
|
template <typename MatchT, typename NotMatchedT>
|
|
|
|
struct choose_if_match<MatchT, MatchT, NotMatchedT> {
|
2016-06-15 18:43:10 +12:00
|
|
|
typedef MatchT type;
|
2016-03-19 06:57:51 +13:00
|
|
|
};
|
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
} // namespace tcg
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
#endif // TCG_SFINAE_H
|