| #pragma once |
| |
| #ifndef TCG_TRAITS_H |
| #define TCG_TRAITS_H |
| |
| |
| #include "sfinae.h" |
| |
| |
| #include <iterator> |
| |
| |
| |
| namespace tcg |
| { |
| |
| |
| |
| |
| |
| 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; |
| }; |
| |
| |
| |
| |
| |
| 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; |
| }; |
| |
| |
| |
| |
| |
| 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)> { |
| }; |
| |
| |
| |
| |
| |
| 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(); } |
| }; |
| |
| |
| |
| |
| |
| 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)) }; |
| }; |
| |
| } |
| |
| #endif |