任意の型、個数の引数を受け取るmax revison 2

signedとunsignedを渡したときの動作を直感に合うようにしたり、
文字列や配列などを引数にできるようにするなど、いろいろ修正

struct gless
{
  typedef bool result_type;
  template <typename T, typename U>
  bool operator() (const T&a, const U&b,
                   typename boost::enable_if<is_signed<T> >::type* =0,
                   typename boost::enable_if<is_signed<U> >::type* =0 ) const
    { return a < b; }
  template <typename T, typename U>
  bool operator() (const T&a, const U&b,
                   typename  boost::enable_if<is_signed<T> >::type* =0,
                   typename boost::disable_if<is_signed<U> >::type* =0 ) const
    { return a<T() || a < b; }
  template <typename T, typename U>
  bool operator() (const T&a, const U&b,
                   typename boost::disable_if<is_signed<T> >::type* =0,
                   typename  boost::enable_if<is_signed<U> >::type* =0 ) const
    { return !(b<U() || b < a); }
  template <typename T, typename U>
  bool operator() (const T&a, const U&b,
                   typename boost::disable_if<is_signed<T> >::type* =0,
                   typename boost::disable_if<is_signed<U> >::type* =0 ) const
    { return a < b; }
  bool operator() (const char*a, const char*b) const
    { return std::strcmp(a, b) < 0; }
  bool operator() (const wchar_t*a, const wchar_t*b) const
    { return std::wcscmp(a, b) < 0; }
};

template <typename... T> struct vmax_t;
template <typename T>
struct vmax_t<T>
{ typedef T type; };

template <std::size_t N>
struct vmax_t<char[N]>
{ typedef const char* type; };

template <std::size_t N>
struct vmax_t<wchar_t[N]>
{ typedef const wchar_t* type; };

template <class T, std::size_t N>
struct vmax_t<T[N]>
{ typedef T type; };

template <class I>
struct vmax_t<std::pair<I,I> >
{ typedef typename std::iterator_traits<I>::value_type type; };

template <typename T, typename... U>
struct vmax_t<T,U...>
{
  typedef typename vmax_t<U...>::type temp_type;
  typedef typename vmax_t<T>::type temp_type2;
  typedef decltype(0?*(temp_type2*)(0):*(temp_type*)(0)) type;
};


template <typename P, typename T>
typename vmax_t<T>::type vmax_if(const P& p, const T& x)
{ return x; }

template <typename P, std::size_t N>
typename vmax_t<char[N]>::type vmax_if(const P& p, const char(&x)[N])
{ return x; }

template <typename P, std::size_t N>
typename vmax_t<wchar_t[N]>::type vmax_if(const P& p, const wchar_t(&x)[N])
{ return x; }

template <typename P, typename T, std::size_t N>
typename vmax_t<T[N]>::type vmax_if(const P& p, const T (&x)[N])
{ return *std::max_element(x, x+N, p); }

template <typename P, typename I>
typename vmax_t<std::pair<I,I> >::type vmax_if(const P& p, const std::pair<I,I>& iter)
{ return *std::max_element(iter.first, iter.second, p); }

template <typename P, typename T, typename... U>
typename vmax_t<T,U...>::type vmax_if(const P& p, const T& x, const U&... y)
{
  const typename vmax_t<U...>::type& z = vmax_if(p, y...);
  const typename vmax_t<T>::type& u = vmax_if(p, x);
  return p(u,z)?z:u;
}

template <typename... U>
typename vmax_t<U...>::type vmax(const U&... y)
{ return  vmax_if(gless(), y...); }

任意の型、個数の引数を受け取るmin

template <class T, std::size_t N, bool isunsigned = false>
struct Signed
{ typedef T type; };

template <class T>
struct Signed<T,1,true>
{ typedef signed char type; };

template <class T>
struct Signed<T,sizeof(short),true>
{ typedef short type; };

template <>
struct Signed<unsigned int,sizeof(int),true>
{ typedef int type; };

template <class T>
struct Signed<T,sizeof(long),true>
{ typedef long type; };

template <class T>
struct Signed<T,sizeof(long long),true>
{ typedef long long type; };

template <typename... T> struct vmin_t;
template <typename T>
struct vmin_t<T>
{ typedef T type; };

template <std::size_t N>
struct vmin_t<char[N]>
{ typedef const char* type; };

template <std::size_t N>
struct vmin_t<wchar_t[N]>
{ typedef const wchar_t* type; };

template <class T, std::size_t N>
struct vmin_t<T[N]>
{ typedef T type; };

template <class I>
struct vmin_t<std::pair<I,I> >
{ typedef typename std::iterator_traits<I>::value_type type; };

template <typename T, typename... U>
struct vmin_t<T,U...>
{
  typedef typename vmin_t<U...>::type temp_type;
  typedef typename vmin_t<T>::type temp_type2;
  typedef decltype(0?*(temp_type2*)(0):*(temp_type*)(0)) tmp_type;
  typedef typename Signed<tmp_type, sizeof(tmp_type),
   boost::is_unsigned<tmp_type>::value &&
    (boost::is_signed<temp_type2>::value || boost::is_signed<temp_type>::value) >::type type;
};

template <typename P, typename T>
typename vmin_t<T>::type vmin_if(const P& p, const T& x)
{ return x; }

template <typename P, std::size_t N>
typename vmin_t<char[N]>::type vmin_if(const P& p, const char(&x)[N])
{ return x; }

template <typename P, std::size_t N>
typename vmin_t<wchar_t[N]>::type vmin_if(const P& p, const wchar_t(&x)[N])
{ return x; }

template <typename P, typename T, std::size_t N>
typename vmin_t<T[N]>::type vmin_if(const P& p, const T (&x)[N])
{ return *std::min_element(x, x+N, p); }

template <typename P, typename I>
typename vmin_t<std::pair<I,I> >::type vmin_if(const P& p, const std::pair<I,I>& iter)
{ return *std::min_element(iter.first, iter.second, p); }

template <typename P, typename T, typename... U>
typename vmin_t<T,U...>::type vmin_if(const P& p, const T& x, const U&... y)
{
  const typename vmin_t<U...>::type& z = vmin_if(p, y...);
  const typename vmin_t<T>::type& u = vmin_if(p, x);
  return p(u,z)?u:z;
}

template <typename... U>
typename vmin_t<U...>::type vmin(const U&... y)
{ return  vmin_if(gless(), y...); }