Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifndef TCG_TRAITS_H
Toshihiro Shimizu 890ddd
#define TCG_TRAITS_H
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// tcg includes
Toshihiro Shimizu 890ddd
#include "sfinae.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// STD includes
Toshihiro Shimizu 890ddd
#include <iterator></iterator>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
namespace tcg
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//****************************************************************************
Toshihiro Shimizu 890ddd
//    TCG traits for generic type concepts
Toshihiro Shimizu 890ddd
//****************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename t=""></typename>
Toshihiro Shimizu 890ddd
struct traits {
Toshihiro Shimizu 890ddd
	typedef T *pointer_type;
Toshihiro Shimizu 890ddd
	typedef T pointed_type;
Toshihiro Shimizu 890ddd
	typedef T &reference_type;
Toshihiro Shimizu 890ddd
	typedef T referenced_type;
Toshihiro Shimizu 890ddd
	typedef T element_type;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename t=""></typename>
Toshihiro Shimizu 890ddd
struct traits<t *=""> {</t>
Toshihiro Shimizu 890ddd
	typedef T **pointer_type;
Toshihiro Shimizu 890ddd
	typedef T pointed_type;
Toshihiro Shimizu 890ddd
	typedef T *&reference_type;
Toshihiro Shimizu 890ddd
	typedef T *referenced_type;
Toshihiro Shimizu 890ddd
	typedef T *element_type;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename t=""></typename>
Toshihiro Shimizu 890ddd
struct traits<t[]> : public traits<t *=""> {</t></t[]>
Toshihiro Shimizu 890ddd
	typedef T element_type;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename t=""></typename>
Toshihiro Shimizu 890ddd
struct traits<t &=""> : public traits<t> {</t></t>
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <>
Toshihiro Shimizu 890ddd
struct traits<void> {</void>
Toshihiro Shimizu 890ddd
	typedef void *pointer_type;
Toshihiro Shimizu 890ddd
	typedef void pointed_type;
Toshihiro Shimizu 890ddd
	typedef void reference_type;
Toshihiro Shimizu 890ddd
	typedef void referenced_type;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//****************************************************************************
Toshihiro Shimizu 890ddd
//    Qualifier removers
Toshihiro Shimizu 890ddd
//****************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename t=""></typename>
Toshihiro Shimizu 890ddd
struct remove_const {
Toshihiro Shimizu 890ddd
	typedef T type;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
template <typename t=""></typename>
Toshihiro Shimizu 890ddd
struct remove_const<const t=""> {</const>
Toshihiro Shimizu 890ddd
	typedef T type;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename t=""></typename>
Toshihiro Shimizu 890ddd
struct remove_ref {
Toshihiro Shimizu 890ddd
	typedef T type;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
template <typename t=""></typename>
Toshihiro Shimizu 890ddd
struct remove_ref<t &=""> {</t>
Toshihiro Shimizu 890ddd
	typedef T type;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename t=""></typename>
Toshihiro Shimizu 890ddd
struct remove_cref {
Toshihiro Shimizu 890ddd
	typedef typename remove_const<typename remove_ref<t="">::type>::type type;</typename>
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//****************************************************************************
Toshihiro Shimizu 890ddd
//    TCG traits for function types
Toshihiro Shimizu 890ddd
//****************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename func=""></typename>
Toshihiro Shimizu 890ddd
class function_traits
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	template <typename bool="" f,=""></typename>
Toshihiro Shimizu 890ddd
	struct result;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	template <typename f=""></typename>
Toshihiro Shimizu 890ddd
	struct result<f, true=""> {</f,>
Toshihiro Shimizu 890ddd
		typedef typename F::result_type type;
Toshihiro Shimizu 890ddd
	};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	template <typename f=""></typename>
Toshihiro Shimizu 890ddd
	struct result<f, false=""> {</f,>
Toshihiro Shimizu 890ddd
		typedef struct {
Toshihiro Shimizu 890ddd
		} type;
Toshihiro Shimizu 890ddd
	};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	template <typename q=""></typename>
Toshihiro Shimizu 890ddd
	static typename enable_if_exists
Toshihiro Shimizu 890ddd
									 char>::type
Toshihiro Shimizu 890ddd
	result_fun(Q *);
Toshihiro Shimizu 890ddd
	static double result_fun(...);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	template <typename bool="" f,=""></typename>
Toshihiro Shimizu 890ddd
	struct argument;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	template <typename f=""></typename>
Toshihiro Shimizu 890ddd
	struct argument<f, true=""> {</f,>
Toshihiro Shimizu 890ddd
		typedef typename F::argument_type type;
Toshihiro Shimizu 890ddd
	};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	template <typename f=""></typename>
Toshihiro Shimizu 890ddd
	struct argument<f, false=""> {</f,>
Toshihiro Shimizu 890ddd
		typedef void type;
Toshihiro Shimizu 890ddd
	};
Toshihiro Shimizu 890ddd
	template <typename q=""></typename>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	static typename enable_if_exists
Toshihiro Shimizu 890ddd
									 char>::type
Toshihiro Shimizu 890ddd
	argument_fun(Q *);
Toshihiro Shimizu 890ddd
	static double argument_fun(...);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	template <typename bool="" f,=""></typename>
Toshihiro Shimizu 890ddd
	struct first_arg;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	template <typename f=""></typename>
Toshihiro Shimizu 890ddd
	struct first_arg<f, true=""> {</f,>
Toshihiro Shimizu 890ddd
		typedef typename F::first_argument_type type;
Toshihiro Shimizu 890ddd
	};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	template <typename f=""></typename>
Toshihiro Shimizu 890ddd
	struct first_arg<f, false=""> {</f,>
Toshihiro Shimizu 890ddd
		typedef void type;
Toshihiro Shimizu 890ddd
	};
Toshihiro Shimizu 890ddd
	template <typename q=""></typename>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	static typename enable_if_exists
Toshihiro Shimizu 890ddd
									 char>::type
Toshihiro Shimizu 890ddd
	first_arg_fun(Q *);
Toshihiro Shimizu 890ddd
	static double first_arg_fun(...);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	template <typename bool="" f,=""></typename>
Toshihiro Shimizu 890ddd
	struct second_arg;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	template <typename f=""></typename>
Toshihiro Shimizu 890ddd
	struct second_arg<f, true=""> {</f,>
Toshihiro Shimizu 890ddd
		typedef typename F::second_argument_type type;
Toshihiro Shimizu 890ddd
	};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	template <typename f=""></typename>
Toshihiro Shimizu 890ddd
	struct second_arg<f, false=""> {</f,>
Toshihiro Shimizu 890ddd
		typedef void type;
Toshihiro Shimizu 890ddd
	};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	template <typename q=""></typename>
Toshihiro Shimizu 890ddd
	static typename enable_if_exists
Toshihiro Shimizu 890ddd
									 char>::type
Toshihiro Shimizu 890ddd
	second_arg_fun(Q *);
Toshihiro Shimizu 890ddd
	static double second_arg_fun(...);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	enum { has_result = (sizeof(result_fun(typename tcg::traits<func>::pointer_type())) == sizeof(char)),</func>
Toshihiro Shimizu 890ddd
		   has_argument = (sizeof(argument_fun(typename tcg::traits<func>::pointer_type())) == sizeof(char)),</func>
Toshihiro Shimizu 890ddd
		   has_first_arg = (sizeof(first_arg_fun(typename tcg::traits<func>::pointer_type())) == sizeof(char)),</func>
Toshihiro Shimizu 890ddd
		   has_second_arg = (sizeof(second_arg_fun(typename tcg::traits<func>::pointer_type())) == sizeof(char)) };</func>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	typedef typename result<func, has_result="">::type ret_type;</func,>
Toshihiro Shimizu 890ddd
	typedef typename argument<func, has_argument="">::type arg_type;</func,>
Toshihiro Shimizu 890ddd
	typedef typename first_arg<func, has_first_arg="">::type arg1_type;</func,>
Toshihiro Shimizu 890ddd
	typedef typename second_arg<func, has_second_arg="">::type arg2_type;</func,>
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename ret=""></typename>
Toshihiro Shimizu 890ddd
struct function_traits<ret()> {</ret()>
Toshihiro Shimizu 890ddd
	enum { has_result = true,
Toshihiro Shimizu 890ddd
		   has_argument = false,
Toshihiro Shimizu 890ddd
		   has_first_arg = false,
Toshihiro Shimizu 890ddd
		   has_second_arg = false };
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	typedef Ret ret_type;
Toshihiro Shimizu 890ddd
	typedef void arg_type;
Toshihiro Shimizu 890ddd
	typedef void arg1_type;
Toshihiro Shimizu 890ddd
	typedef void arg2_type;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename ret=""></typename>
Toshihiro Shimizu 890ddd
struct function_traits<ret (*)()=""> : public function_traits<ret()> {</ret()></ret>
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename ret=""></typename>
Toshihiro Shimizu 890ddd
struct function_traits<ret(&)()> : public function_traits<ret()> {</ret()></ret(&)()>
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename arg="" ret,="" typename=""></typename>
Toshihiro Shimizu 890ddd
struct function_traits<ret(arg)> {</ret(arg)>
Toshihiro Shimizu 890ddd
	enum { has_result = true,
Toshihiro Shimizu 890ddd
		   has_argument = true,
Toshihiro Shimizu 890ddd
		   has_first_arg = false,
Toshihiro Shimizu 890ddd
		   has_second_arg = false };
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	typedef Ret ret_type;
Toshihiro Shimizu 890ddd
	typedef Arg arg_type;
Toshihiro Shimizu 890ddd
	typedef void arg1_type;
Toshihiro Shimizu 890ddd
	typedef void arg2_type;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename arg="" ret,="" typename=""></typename>
Toshihiro Shimizu 890ddd
struct function_traits<ret (*)(arg)=""> : public function_traits<ret(arg)> {</ret(arg)></ret>
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename arg="" ret,="" typename=""></typename>
Toshihiro Shimizu 890ddd
struct function_traits<ret(&)(arg)> : public function_traits<ret(arg)> {</ret(arg)></ret(&)(arg)>
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename arg1,="" arg2="" ret,="" typename=""></typename>
Toshihiro Shimizu 890ddd
struct function_traits<ret(arg1, arg2)=""> {</ret(arg1,>
Toshihiro Shimizu 890ddd
	enum { has_result = true,
Toshihiro Shimizu 890ddd
		   has_first_arg = true,
Toshihiro Shimizu 890ddd
		   has_second_arg = true };
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	typedef Ret ret_type;
Toshihiro Shimizu 890ddd
	typedef Arg1 arg1_type;
Toshihiro Shimizu 890ddd
	typedef Arg2 arg2_type;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename arg1,="" arg2="" ret,="" typename=""></typename>
Toshihiro Shimizu 890ddd
struct function_traits<ret (*)(arg1,="" arg2)=""> : public function_traits<ret(arg1, arg2)=""> {</ret(arg1,></ret>
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename arg1,="" arg2="" ret,="" typename=""></typename>
Toshihiro Shimizu 890ddd
struct function_traits<ret(&)(arg1, arg2)=""> : public function_traits<ret(arg1, arg2)=""> {</ret(arg1,></ret(&)(arg1,>
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//******************************************************************************
Toshihiro Shimizu 890ddd
//    TCG traits for output container readers
Toshihiro Shimizu 890ddd
//******************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename outputdata="typename" reader,="" reader::value_type="" typename=""></typename>
Toshihiro Shimizu 890ddd
struct container_reader_traits {
Toshihiro Shimizu 890ddd
	typedef Reader reader_type;
Toshihiro Shimizu 890ddd
	typedef OutputData value_type;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	static void openContainer(reader_type &reader) { reader.openContainer(); }
Toshihiro Shimizu 890ddd
	static void addElement(reader_type &reader, const value_type &data) { reader.addElement(data); }
Toshihiro Shimizu 890ddd
	static void closeContainer(reader_type &reader) { reader.closeContainer(); }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//************************************************************************************
Toshihiro Shimizu 890ddd
//    Notable Test  traits
Toshihiro Shimizu 890ddd
//************************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename t=""></typename>
Toshihiro Shimizu 890ddd
struct is_floating_point {
Toshihiro Shimizu 890ddd
	enum { value = false };
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <>
Toshihiro Shimizu 890ddd
struct is_floating_point<float> {</float>
Toshihiro Shimizu 890ddd
	enum { value = true };
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <>
Toshihiro Shimizu 890ddd
struct is_floating_point<double> {</double>
Toshihiro Shimizu 890ddd
	enum { value = true };
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <>
Toshihiro Shimizu 890ddd
struct is_floating_point<long double=""> {</long>
Toshihiro Shimizu 890ddd
	enum { value = true };
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename t=""></typename>
Toshihiro Shimizu 890ddd
struct is_function {
Toshihiro Shimizu 890ddd
	enum { value = function_traits<t>::has_result };</t>
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename t=""></typename>
Toshihiro Shimizu 890ddd
struct is_functor {
Toshihiro Shimizu 890ddd
	template <typename q=""></typename>
Toshihiro Shimizu 890ddd
	static typename enable_if_exists
Toshihiro Shimizu 890ddd
									 char>::type
Toshihiro Shimizu 890ddd
	result(Q *);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	static double result(...);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	enum { value = (sizeof(result(typename tcg::traits<t>::pointer_type())) == sizeof(char)) };</t>
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
} // namespace tcg
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#endif // TCG_TRAITS_H