Shinya Kitaoka 810553
#pragma once
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
Shinya Kitaoka 120a6e
namespace tcg {
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 {
Shinya Kitaoka 120a6e
  typedef T *pointer_type;
Shinya Kitaoka 120a6e
  typedef T pointed_type;
Shinya Kitaoka 120a6e
  typedef T &reference_type;
Shinya Kitaoka 120a6e
  typedef T referenced_type;
Shinya Kitaoka 120a6e
  typedef T element_type;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename t=""></typename>
Toshihiro Shimizu 890ddd
struct traits<t *=""> {</t>
Shinya Kitaoka 120a6e
  typedef T **pointer_type;
Shinya Kitaoka 120a6e
  typedef T pointed_type;
Shinya Kitaoka 120a6e
  typedef T *&reference_type;
Shinya Kitaoka 120a6e
  typedef T *referenced_type;
Shinya Kitaoka 120a6e
  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[]>
Shinya Kitaoka 120a6e
  typedef T element_type;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename t=""></typename>
Shinya Kitaoka 120a6e
struct traits<t &=""> : public traits<t> {};</t></t>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <>
Toshihiro Shimizu 890ddd
struct traits<void> {</void>
Shinya Kitaoka 120a6e
  typedef void *pointer_type;
Shinya Kitaoka 120a6e
  typedef void pointed_type;
Shinya Kitaoka 120a6e
  typedef void reference_type;
Shinya Kitaoka 120a6e
  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 {
Shinya Kitaoka 120a6e
  typedef T type;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
template <typename t=""></typename>
Toshihiro Shimizu 890ddd
struct remove_const<const t=""> {</const>
Shinya Kitaoka 120a6e
  typedef T type;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename t=""></typename>
Toshihiro Shimizu 890ddd
struct remove_ref {
Shinya Kitaoka 120a6e
  typedef T type;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
template <typename t=""></typename>
Toshihiro Shimizu 890ddd
struct remove_ref<t &=""> {</t>
Shinya Kitaoka 120a6e
  typedef T type;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename t=""></typename>
Toshihiro Shimizu 890ddd
struct remove_cref {
Shinya Kitaoka 120a6e
  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>
Shinya Kitaoka 120a6e
class function_traits {
Shinya Kitaoka 120a6e
  template <typename bool="" f,=""></typename>
Shinya Kitaoka 120a6e
  struct result;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  template <typename f=""></typename>
Shinya Kitaoka 120a6e
  struct result<f, true=""> {</f,>
Shinya Kitaoka 120a6e
    typedef typename F::result_type type;
Shinya Kitaoka 120a6e
  };
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  template <typename f=""></typename>
Shinya Kitaoka 120a6e
  struct result<f, false=""> {</f,>
Shinya Kitaoka 120a6e
    typedef struct { } type; };
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  template <typename q=""></typename>
Shinya Kitaoka 120a6e
  static typename enable_if_exists<typename char="" q::result_type,="">::type</typename>
Shinya Kitaoka 120a6e
  result_fun(Q *);
Shinya Kitaoka 120a6e
  static double result_fun(...);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  template <typename bool="" f,=""></typename>
Shinya Kitaoka 120a6e
  struct argument;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  template <typename f=""></typename>
Shinya Kitaoka 120a6e
  struct argument<f, true=""> {</f,>
Shinya Kitaoka 120a6e
    typedef typename F::argument_type type;
Shinya Kitaoka 120a6e
  };
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  template <typename f=""></typename>
Shinya Kitaoka 120a6e
  struct argument<f, false=""> {</f,>
Shinya Kitaoka 120a6e
    typedef void type;
Shinya Kitaoka 120a6e
  };
Shinya Kitaoka 120a6e
  template <typename q=""></typename>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  static typename enable_if_exists<typename char="" q::argument_type,="">::type</typename>
Shinya Kitaoka 120a6e
  argument_fun(Q *);
Shinya Kitaoka 120a6e
  static double argument_fun(...);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  template <typename bool="" f,=""></typename>
Shinya Kitaoka 120a6e
  struct first_arg;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  template <typename f=""></typename>
Shinya Kitaoka 120a6e
  struct first_arg<f, true=""> {</f,>
Shinya Kitaoka 120a6e
    typedef typename F::first_argument_type type;
Shinya Kitaoka 120a6e
  };
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  template <typename f=""></typename>
Shinya Kitaoka 120a6e
  struct first_arg<f, false=""> {</f,>
Shinya Kitaoka 120a6e
    typedef void type;
Shinya Kitaoka 120a6e
  };
Shinya Kitaoka 120a6e
  template <typename q=""></typename>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  static typename enable_if_exists<typename char="" q::first_argument_type,="">::type</typename>
Shinya Kitaoka 120a6e
  first_arg_fun(Q *);
Shinya Kitaoka 120a6e
  static double first_arg_fun(...);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  template <typename bool="" f,=""></typename>
Shinya Kitaoka 120a6e
  struct second_arg;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  template <typename f=""></typename>
Shinya Kitaoka 120a6e
  struct second_arg<f, true=""> {</f,>
Shinya Kitaoka 120a6e
    typedef typename F::second_argument_type type;
Shinya Kitaoka 120a6e
  };
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  template <typename f=""></typename>
Shinya Kitaoka 120a6e
  struct second_arg<f, false=""> {</f,>
Shinya Kitaoka 120a6e
    typedef void type;
Shinya Kitaoka 120a6e
  };
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  template <typename q=""></typename>
Shinya Kitaoka 120a6e
  static typename enable_if_exists<typename char="" q::second_argument_type,="">::type</typename>
Shinya Kitaoka 120a6e
  second_arg_fun(Q *);
Shinya Kitaoka 120a6e
  static double second_arg_fun(...);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  enum {
Shinya Kitaoka 120a6e
    has_result =
Shinya Kitaoka 120a6e
        (sizeof(result_fun(typename tcg::traits<func>::pointer_type())) ==</func>
Shinya Kitaoka 120a6e
         sizeof(char)),
Shinya Kitaoka 120a6e
    has_argument =
Shinya Kitaoka 120a6e
        (sizeof(argument_fun(typename tcg::traits<func>::pointer_type())) ==</func>
Shinya Kitaoka 120a6e
         sizeof(char)),
Shinya Kitaoka 120a6e
    has_first_arg =
Shinya Kitaoka 120a6e
        (sizeof(first_arg_fun(typename tcg::traits<func>::pointer_type())) ==</func>
Shinya Kitaoka 120a6e
         sizeof(char)),
Shinya Kitaoka 120a6e
    has_second_arg =
Shinya Kitaoka 120a6e
        (sizeof(second_arg_fun(typename tcg::traits<func>::pointer_type())) ==</func>
Shinya Kitaoka 120a6e
         sizeof(char))
Shinya Kitaoka 120a6e
  };
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  typedef typename result<func, has_result="">::type ret_type;</func,>
Shinya Kitaoka 120a6e
  typedef typename argument<func, has_argument="">::type arg_type;</func,>
Shinya Kitaoka 120a6e
  typedef typename first_arg<func, has_first_arg="">::type arg1_type;</func,>
Shinya Kitaoka 120a6e
  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()>
Shinya Kitaoka 120a6e
  enum {
Shinya Kitaoka 120a6e
    has_result     = true,
Shinya Kitaoka 120a6e
    has_argument   = false,
Shinya Kitaoka 120a6e
    has_first_arg  = false,
Shinya Kitaoka 120a6e
    has_second_arg = false
Shinya Kitaoka 120a6e
  };
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  typedef Ret ret_type;
Shinya Kitaoka 120a6e
  typedef void arg_type;
Shinya Kitaoka 120a6e
  typedef void arg1_type;
Shinya Kitaoka 120a6e
  typedef void arg2_type;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename ret=""></typename>
Shinya Kitaoka 120a6e
struct function_traits<ret (*)()=""> : public function_traits<ret()> {};</ret()></ret>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename ret=""></typename>
Shinya Kitaoka 120a6e
struct function_traits<ret (&)()=""> : public function_traits<ret()> {};</ret()></ret>
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)>
Shinya Kitaoka 120a6e
  enum {
Shinya Kitaoka 120a6e
    has_result     = true,
Shinya Kitaoka 120a6e
    has_argument   = true,
Shinya Kitaoka 120a6e
    has_first_arg  = false,
Shinya Kitaoka 120a6e
    has_second_arg = false
Shinya Kitaoka 120a6e
  };
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  typedef Ret ret_type;
Shinya Kitaoka 120a6e
  typedef Arg arg_type;
Shinya Kitaoka 120a6e
  typedef void arg1_type;
Shinya Kitaoka 120a6e
  typedef void arg2_type;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename arg="" ret,="" typename=""></typename>
Shinya Kitaoka 120a6e
struct function_traits<ret (*)(arg)=""> : public function_traits<ret(arg)> {};</ret(arg)></ret>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename arg="" ret,="" typename=""></typename>
Shinya Kitaoka 120a6e
struct function_traits<ret (&)(arg)=""> : public function_traits<ret(arg)> {};</ret(arg)></ret>
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,>
Shinya Kitaoka 120a6e
  enum { has_result = true, has_first_arg = true, has_second_arg = true };
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  typedef Ret ret_type;
Shinya Kitaoka 120a6e
  typedef Arg1 arg1_type;
Shinya Kitaoka 120a6e
  typedef Arg2 arg2_type;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename arg1,="" arg2="" ret,="" typename=""></typename>
Shinya Kitaoka 120a6e
struct function_traits<ret (*)(arg1,="" arg2)=""></ret>
Shinya Kitaoka 120a6e
    : public function_traits<ret(arg1, arg2)=""> {};</ret(arg1,>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename arg1,="" arg2="" ret,="" typename=""></typename>
Shinya Kitaoka 120a6e
struct function_traits<ret (&)(arg1,="" arg2)=""></ret>
Shinya Kitaoka 120a6e
    : public function_traits<ret(arg1, arg2)=""> {};</ret(arg1,>
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 {
Shinya Kitaoka 120a6e
  typedef Reader reader_type;
Shinya Kitaoka 120a6e
  typedef OutputData value_type;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  static void openContainer(reader_type &reader) { reader.openContainer(); }
Shinya Kitaoka 120a6e
  static void addElement(reader_type &reader, const value_type &data) {
Shinya Kitaoka 120a6e
    reader.addElement(data);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  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 {
Shinya Kitaoka 120a6e
  enum { value = false };
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <>
Toshihiro Shimizu 890ddd
struct is_floating_point<float> {</float>
Shinya Kitaoka 120a6e
  enum { value = true };
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <>
Toshihiro Shimizu 890ddd
struct is_floating_point<double> {</double>
Shinya Kitaoka 120a6e
  enum { value = true };
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <>
Toshihiro Shimizu 890ddd
struct is_floating_point<long double=""> {</long>
Shinya Kitaoka 120a6e
  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 {
Shinya Kitaoka 120a6e
  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 {
Shinya Kitaoka 120a6e
  template <typename q=""></typename>
Shinya Kitaoka 120a6e
  static typename enable_if_exists<typename char="" q::result_type,="">::type result(</typename>
Shinya Kitaoka 120a6e
      Q *);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  static double result(...);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  enum {
Shinya Kitaoka 120a6e
    value = (sizeof(result(typename tcg::traits<t>::pointer_type())) ==</t>
Shinya Kitaoka 120a6e
             sizeof(char))
Shinya Kitaoka 120a6e
  };
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
}  // namespace tcg
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
#endif  // TCG_TRAITS_H