Shinya Kitaoka 810553
#pragma once
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifndef TCG_SFINAE_H
Toshihiro Shimizu 890ddd
#define TCG_SFINAE_H
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*!
Toshihiro Shimizu 890ddd
  \file     sfinae.h
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  \brief    Contains template metafunctions that can be used to enable or
Toshihiro Shimizu 890ddd
            disable template class members.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  \details  SFINAE (Substitution Failure Is Not An Error) is a C++ \a feature
Toshihiro Shimizu 890ddd
            that allows the compiler to silently discard failures in template
Toshihiro Shimizu 890ddd
            function instantiations during function overload resolution.
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#if defined(__APPLE_CC__)
Toshihiro Shimizu 890ddd
#include <type_traits></type_traits>
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
namespace tcg
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename typename="" x,="" y=""></typename>
Toshihiro Shimizu 890ddd
struct type_match {
Toshihiro Shimizu 890ddd
	enum { value = false };
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename x=""></typename>
Toshihiro Shimizu 890ddd
struct type_match<x, x=""> {</x,>
Toshihiro Shimizu 890ddd
	enum { value = true };
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename typename="" x,="" y=""></typename>
Toshihiro Shimizu 890ddd
struct type_mismatch {
Toshihiro Shimizu 890ddd
	enum { value = true };
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename x=""></typename>
Toshihiro Shimizu 890ddd
struct type_mismatch<x, x=""> {</x,>
Toshihiro Shimizu 890ddd
	enum { value = false };
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//========================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename b="" t,="" typename=""></typename>
Toshihiro Shimizu 890ddd
struct enable_if_exists {
Toshihiro Shimizu 890ddd
	typedef B type;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//========================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <bool, t="void" typename=""></bool,>
Toshihiro Shimizu 890ddd
struct enable_if {
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename t=""></typename>
Toshihiro Shimizu 890ddd
struct enable_if<true, t=""> {</true,>
Toshihiro Shimizu 890ddd
	typedef T type;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//========================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <bool, t="void" typename=""></bool,>
Toshihiro Shimizu 890ddd
struct disable_if {
Toshihiro Shimizu 890ddd
	typedef T type;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename t=""></typename>
Toshihiro Shimizu 890ddd
struct disable_if<true, t=""> {</true,>
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//========================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <bool, falset="void" truet,="" typename=""></bool,>
Toshihiro Shimizu 890ddd
struct choose_if;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename falset="" truet,="" typename=""></typename>
Toshihiro Shimizu 890ddd
struct choose_if<true, falset="" truet,=""> {</true,>
Toshihiro Shimizu 890ddd
	typedef TrueT type;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename falset="" truet,="" typename=""></typename>
Toshihiro Shimizu 890ddd
struct choose_if<false, falset="" truet,=""> {</false,>
Toshihiro Shimizu 890ddd
	typedef FalseT type;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//========================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename matcht,="" notmatchedt="void" t,="" typename=""></typename>
Toshihiro Shimizu 890ddd
struct choose_if_match {
Toshihiro Shimizu 890ddd
	typedef NotMatchedT type;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename matcht,="" notmatchedt="" typename=""></typename>
Toshihiro Shimizu 890ddd
struct choose_if_match<matcht, matcht,="" notmatchedt=""> {</matcht,>
Toshihiro Shimizu 890ddd
	typedef MatchT type;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
} // namespace tcg
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#endif // TCG_SFINAE_H