Shinya Kitaoka 810553
#pragma once
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifndef TCG_ALGORITHM_H
Toshihiro Shimizu 890ddd
#define TCG_ALGORITHM_H
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// tcg includes
Toshihiro Shimizu 890ddd
#include "traits.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// STD includes
Toshihiro Shimizu 890ddd
#include <functional></functional>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*!
Toshihiro Shimizu 890ddd
  \file     algorithm.h
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  \brief    This file contains useful algorithms complementary to those
Toshihiro Shimizu 890ddd
            in the standard \p \<algorithm\> and in \p boost::algorithm.</algorithm\>
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace tcg {
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//***************************************************************************
Toshihiro Shimizu 890ddd
//    Binary find  algorithms
Toshihiro Shimizu 890ddd
//***************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*!
Toshihiro Shimizu 890ddd
  \brief    Performs a binary search for the a value in a sorted,
Toshihiro Shimizu 890ddd
            random access iterators range, and returns its position.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  \return   The \a first range position whose value is \a equivalent to
Toshihiro Shimizu 890ddd
            the specified one.
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
template <typename ranit,="" t="" typename=""></typename>
Shinya Kitaoka 120a6e
RanIt binary_find(RanIt begin,     //!< Start of the sorted range.
Shinya Kitaoka 120a6e
                  RanIt end,       //!< End of the sorted range.
Shinya Kitaoka 120a6e
                  const T &value)  //!< Value to look up.
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  RanIt it = std::lower_bound(begin, end, value);
Shinya Kitaoka 120a6e
  return (it != end && !(value < *it)) ? it : end;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*!
Toshihiro Shimizu 890ddd
  \brief    Performs a binary search for the a value in a sorted,
Toshihiro Shimizu 890ddd
            random access iterators range, and returns its position.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  \return   The \a first range position whose value is \a equivalent to
Toshihiro Shimizu 890ddd
            the specified one.
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
template <typename compare="" ranit,="" t,="" typename=""></typename>
Shinya Kitaoka 120a6e
RanIt binary_find(RanIt begin,     //!< Start of the sorted range.
Shinya Kitaoka 120a6e
                  RanIt end,       //!< End of the sorted range.
Shinya Kitaoka 120a6e
                  const T &value,  //!< Value to look up.
Shinya Kitaoka 120a6e
                  Compare comp)    //!< Comparator functor sorting the range.
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  RanIt it = std::lower_bound(begin, end, value, comp);
Shinya Kitaoka 120a6e
  return (it != end && !comp(value, *it)) ? it : end;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//***************************************************************************
Toshihiro Shimizu 890ddd
//    Min/Max iterator range  algorithms
Toshihiro Shimizu 890ddd
//***************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*!
Toshihiro Shimizu 890ddd
  \brief    Calculates the minimal transformed element from the
Toshihiro Shimizu 890ddd
            input iterators range.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  \return   The position of the minimal transform.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  \details  This function is similar to std::min_element(), but
Toshihiro Shimizu 890ddd
            operating a unary transforming function on dereferenced
Toshihiro Shimizu 890ddd
            objects.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
            Furthermore, the minimal transformed value is cached
Toshihiro Shimizu 890ddd
            during computation.
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
template <typename comp="" forit,="" func,="" typename=""></typename>
Shinya Kitaoka 120a6e
ForIt min_transform(
Shinya Kitaoka 120a6e
    ForIt begin,  //!< Start of the input iterators range.
Shinya Kitaoka 120a6e
    ForIt end,    //!< End of the input iterators range.
Shinya Kitaoka 120a6e
    Func func,    //!< The transforming function.
Shinya Kitaoka 120a6e
    Comp comp)    //!< The comparator object for transformed values.
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  typedef typename tcg::function_traits<func>::ret_type ret_type;</func>
Shinya Kitaoka 120a6e
  typedef typename tcg::remove_cref<ret_type>::type value_type;</ret_type>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (begin == end) return end;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  ForIt minPos       = begin;
Shinya Kitaoka 120a6e
  value_type minimum = func(*begin);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (; begin != end; ++begin) {
Shinya Kitaoka 120a6e
    const value_type &candidate = func(*begin);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    if (comp(candidate, minimum)) minPos = begin, minimum = candidate;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return minPos;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*!
Toshihiro Shimizu 890ddd
  \brief    Calculates the minimal transformed element from the
Toshihiro Shimizu 890ddd
            input iterators range.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  \return   The position of the minimal transform.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  \remark   This variation uses \p operator< as comparator for the
Toshihiro Shimizu 890ddd
            transformed values.
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
template <typename forit,="" func="" typename=""></typename>
Shinya Kitaoka 120a6e
ForIt min_transform(ForIt begin,  //!< Start of the input iterators range.
Shinya Kitaoka 120a6e
                    ForIt end,    //!< End of the input iterators range.
Shinya Kitaoka 120a6e
                    Func func)    //!< The transforming function.
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  typedef typename tcg::function_traits<func>::ret_type ret_type;</func>
Shinya Kitaoka 120a6e
  typedef typename tcg::remove_cref<ret_type>::type value_type;</ret_type>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return min_transform(begin, end, func, std::less<value_type>());</value_type>
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*!
Toshihiro Shimizu 890ddd
  \brief    Calculates the maximal transformed element from the
Toshihiro Shimizu 890ddd
            input iterators range.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  \return   The position of the maximal transform.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  \sa       See min_transform() for a detailed explanation.
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
template <typename comp="" forit,="" func,="" typename=""></typename>
Shinya Kitaoka 120a6e
ForIt max_transform(
Shinya Kitaoka 120a6e
    ForIt begin,  //!< Start of the input iterators range.
Shinya Kitaoka 120a6e
    ForIt end,    //!< End of the input iterators range.
Shinya Kitaoka 120a6e
    Func func,    //!< The transforming function.
Shinya Kitaoka 120a6e
    Comp comp)    //!< The comparator object for transformed values.
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  typedef typename tcg::function_traits<func>::ret_type ret_type;</func>
Shinya Kitaoka 120a6e
  typedef typename tcg::remove_cref<ret_type>::type value_type;</ret_type>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (begin == end) return end;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  ForIt maxPos       = begin;
Shinya Kitaoka 120a6e
  value_type maximum = func(*begin);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (; begin != end; ++begin) {
Shinya Kitaoka 120a6e
    const value_type &candidate = func(*begin);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    if (comp(maximum, candidate)) maxPos = begin, maximum = candidate;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return maxPos;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*!
Toshihiro Shimizu 890ddd
  \brief    Calculates the maximal transformed element from the
Toshihiro Shimizu 890ddd
            input iterators range.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  \return   The position of the maximal transform.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  \sa       See min_transform() for a detailed explanation.
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
template <typename forit,="" func="" typename=""></typename>
Shinya Kitaoka 120a6e
ForIt max_transform(ForIt begin,  //!< Start of the input iterators range.
Shinya Kitaoka 120a6e
                    ForIt end,    //!< End of the input iterators range.
Shinya Kitaoka 120a6e
                    Func func)    //!< The transforming function.
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  typedef typename tcg::function_traits<func>::ret_type ret_type;</func>
Shinya Kitaoka 120a6e
  typedef typename tcg::remove_cref<ret_type>::type value_type;</ret_type>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return max_transform(begin, end, func, std::less<value_type>());</value_type>
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
}  // namespace tcg
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
#endif  // TCG_ALGORITHM_H