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