tahoma2d/toonz/sources/include/tcg/algorithm.h

181 lines
5.7 KiB
C
Raw Normal View History

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