algorithms.hpp
来自「用STL的方式封装了WindowsAPI、COM调用、ACE、ATL、MFC、W」· HPP 代码 · 共 1,555 行 · 第 1/3 页
HPP
1,555 行
return r_for_each_impl(r, f, r);
}
/* *********************************************************
* generate
*/
template< ss_typename_param_k R
, ss_typename_param_k F
>
inline void r_generate_impl(R r, F f, iterable_range_tag const &)
{
std::generate(r.begin(), r.end(), f);
}
/// Sets each element in the range to the result of the given function
///
/// \param r The range
/// \param f The generator function
///
/// \note: Supports Iterable Range type
template< ss_typename_param_k R
, ss_typename_param_k F
>
inline void r_generate(R r, F f)
{
r_generate_impl(r, f, r);
}
/* *********************************************************
* max_element (1)
*/
template <ss_typename_param_k R>
inline ss_typename_type_k R::value_type r_max_element_1_impl(R r, notional_range_tag const &)
{
typedef ss_typename_type_k R::value_type value_type_t;
value_type_t max_ = value_type_t();
for(; r; ++r)
{
if(max_ < *r)
{
max_ = *r;
}
}
return max_;
}
template <ss_typename_param_k I>
inline I r_max_element_1_impl_iterable(I from, I to)
{
if(from == to)
{
throw empty_range_exception("Cannot determine maximum element of empty range");
}
return std::max_element(from, to);
}
template <ss_typename_param_k R>
inline ss_typename_type_k R::value_type r_max_element_1_impl(R r, iterable_range_tag const &)
{
return *r_max_element_1_impl_iterable(r.begin(), r.end());
}
template <ss_typename_param_k R>
inline ss_typename_type_k R::value_type r_max_element_1_impl(R r, basic_indirect_range_tag const &)
{
return indirect_range_adaptor<R>(r).max_element();
}
template <ss_typename_param_k R>
inline ss_typename_type_k R::value_type r_max_element_1_impl(R r, indirect_range_tag const &)
{
return r.max_element();
}
/// Evaluates the maximum element in the range
///
/// \param r The range. Cannot be closed
///
/// \note: Supports Notional, Iterable and Indirect Range types
/// \note: The behaviour is undefined if the range is closed
template <ss_typename_param_k R>
inline ss_typename_type_k R::value_type r_max_element(R r)
{
STLSOFT_ASSERT(r_distance(r) > 0);
return r_max_element_1_impl(r, r);
}
/* *********************************************************
* max_element (2)
*/
template< ss_typename_param_k I
, ss_typename_param_k F
>
inline I r_max_element_2_impl_iterable(I from, I to, F f)
{
if(from == to)
{
throw empty_range_exception("Cannot determine maximum element of empty range");
}
return std::max_element(from, to, f);
}
template< ss_typename_param_k R
, ss_typename_param_k F
>
inline ss_typename_type_k R::value_type r_max_element_2_impl(R r, F f, iterable_range_tag const &)
{
return *r_max_element_2_impl_iterable(r.begin(), r.end(), f);
}
template< ss_typename_param_k R
, ss_typename_param_k F
>
inline ss_typename_type_k R::value_type r_max_element_2_impl(R r, F f, notional_range_tag const &)
{
typedef ss_typename_type_k R::value_type value_type_t;
value_type_t max_ = value_type_t();
for(; r; ++r)
{
if(f(max_, *r))
{
max_ = *r;
}
}
return max_;
}
template< ss_typename_param_k R
, ss_typename_param_k F
>
inline ss_typename_type_k R::value_type r_max_element_2_impl(R r, F f, basic_indirect_range_tag const &)
{
return indirect_range_adaptor<R>(r).max_element(f);
}
template< ss_typename_param_k R
, ss_typename_param_k F
>
inline ss_typename_type_k R::value_type r_max_element_2_impl(R r, F f, indirect_range_tag const &)
{
return r.max_element(f);
}
/// Evaluates the maximum element in the range evaluated according to the given function
///
/// \param r The range. Cannot be closed
/// \param f The function used to evaluate the ordering
///
/// \note: Supports Notional, Iterable and Indirect Range types
/// \note: The behaviour is undefined if the range is closed
template< ss_typename_param_k R
, ss_typename_param_k F
>
inline ss_typename_type_k R::value_type r_max_element(R r, F f)
{
STLSOFT_ASSERT(r_distance(r) > 0);
return r_max_element_2_impl(r, f, r);
}
/* *********************************************************
* min_element (1)
*/
template <ss_typename_param_k R>
inline ss_typename_type_k R::value_type r_min_element_1_impl(R r, notional_range_tag const &)
{
typedef ss_typename_type_k R::value_type value_type_t;
if(!r)
{
return value_type_t();
}
else
{
value_type_t min_ = *r;
for(; ++r; )
{
if(*r < min_)
{
min_ = *r;
}
}
return min_;
}
}
template <ss_typename_param_k I>
inline I r_min_element_1_impl_iterable(I from, I to)
{
if(from == to)
{
throw empty_range_exception("Cannot determine minimum element of empty range");
}
return std::min_element(from, to);
}
template <ss_typename_param_k R>
inline ss_typename_type_k R::value_type r_min_element_1_impl(R r, iterable_range_tag const &)
{
return *r_min_element_1_impl_iterable(r.begin(), r.end());
}
template <ss_typename_param_k R>
inline ss_typename_type_k R::value_type r_min_element_1_impl(R r, basic_indirect_range_tag const &)
{
return indirect_range_adaptor<R>(r).min_element();
}
template <ss_typename_param_k R>
inline ss_typename_type_k R::value_type r_min_element_1_impl(R r, indirect_range_tag const &)
{
return r.min_element();
}
/// Evaluates the minimum element in the range
///
/// \param r The range. Cannot be closed
///
/// \note: Supports Notional, Iterable and Indirect Range types
/// \note: The behaviour is undefined if the range is closed
template <ss_typename_param_k R>
inline ss_typename_type_k R::value_type r_min_element(R r)
{
STLSOFT_ASSERT(r_distance(r) > 0);
return r_min_element_1_impl(r, r);
}
/* *********************************************************
* min_element (2)
*/
template< ss_typename_param_k I
, ss_typename_param_k F
>
inline I r_min_element_2_impl_iterable(I from, I to, F f)
{
if(from == to)
{
throw empty_range_exception("Cannot determine minimum element of empty range");
}
return std::min_element(from, to, f);
}
template< ss_typename_param_k R
, ss_typename_param_k F
>
inline ss_typename_type_k R::value_type r_min_element_2_impl(R r, F f, iterable_range_tag const &)
{
return *r_min_element_2_impl_iterable(r.begin(), r.end(), f);
}
template< ss_typename_param_k R
, ss_typename_param_k F
>
inline ss_typename_type_k R::value_type r_min_element_2_impl(R r, F f, notional_range_tag const &)
{
typedef ss_typename_type_k R::value_type value_type_t;
value_type_t min_ = value_type_t();
for(; r; ++r)
{
if(f(min_, *r))
{
min_ = *r;
}
}
return min_;
}
template< ss_typename_param_k R
, ss_typename_param_k F
>
inline ss_typename_type_k R::value_type r_min_element_2_impl(R r, F f, basic_indirect_range_tag const &)
{
return indirect_range_adaptor<R>(r).min_element(f);
}
template< ss_typename_param_k R
, ss_typename_param_k F
>
inline ss_typename_type_k R::value_type r_min_element_2_impl(R r, F f, indirect_range_tag const &)
{
return r.min_element(f);
}
/// Evaluates the minimum element in the range evaluated according to the given function
///
/// \param r The range. Cannot be closed
/// \param f The function used to evaluate the ordering
///
/// \note: Supports Notional, Iterable and Indirect Range types
/// \note: The behaviour is undefined if the range is closed
template< ss_typename_param_k R
, ss_typename_param_k F
>
inline ss_typename_type_k R::value_type r_min_element(R r, F f)
{
STLSOFT_ASSERT(r_distance(r) > 0);
return r_min_element_2_impl(r, f, r);
}
/* *********************************************************
* replace
*/
template< ss_typename_param_k R
, ss_typename_param_k T
>
inline void r_replace_impl(R r, T oldVal, T newVal, iterable_range_tag const &)
{
std::replace(r.begin(), r.end(), oldVal, newVal);
}
template< ss_typename_param_k R
, ss_typename_param_k T
>
inline void r_replace_impl(R r, T oldVal, T newVal, indirect_range_tag const &)
{
r.replace(r, oldVal, newVal);
}
/// Replaces all elements of the given old value with the new value
///
/// \param r The range
/// \param oldVal The value to search for
/// \param newVal The value to replace any elements with \c oldVal
///
/// \note: Supports Iterable and Indirect Range types
template< ss_typename_param_k R
, ss_typename_param_k T
>
inline void r_replace(R r, T oldVal, T newVal)
{
r_replace_impl(r, oldVal, newVal, r);
}
/* *********************************************************
* replace_copy
*/
#if 0
template< ss_typename_param_k RI
, ss_typename_param_k RO
, ss_typename_param_k T
>
inline void r_replace_copy_impl(RI ri, RO ro, T oldVal, T newVal, iterable_range_tag const &, iterable_range_tag const &)
{
std::replace_copy(ri.begin(), ri.end(), ro.begin(), oldVal, newVal);
}
template< ss_typename_param_k RI
, ss_typename_param_k RO
, ss_typename_param_k T
>
inline void r_replace_copy_impl(RI ri, RO ro, T oldVal, T newVal, indirect_range_tag const &, indirect_range_tag const &)
{
ri.replace_copy(ro, oldVal, newVal);
}
/// Replaces all elements of the given old value with the new value
///
/// \param r The range
/// \param oldVal The value to search for
/// \param newVal The value to replace any elements with \c oldVal
///
/// \note: Supports Iterable and Indirect Range types
template< ss_typename_param_k RI
, ss_typename_param_k RO
, ss_typename_param_k T
>
inline void r_replace_copy(RI ri, RO ro, T oldVal, T newVal)
{
r_replace_copy_impl(ri, ro, oldVal, newVal, ri, ro);
}
#endif /* 0 */
/* *********************************************************
* replace_if
*/
template< ss_typename_param_k R
, ss_typename_param_k P
, ss_typename_param_k T
>
inline void r_replace_if_impl(R r, P pred, T newVal, iterable_range_tag const &)
{
std::replace_if(r.begin(), r.end(), pred, newVal);
}
template< ss_typename_param_k R
, ss_typename_param_k P
, ss_typename_param_k T
>
inline void r_replace_if_impl(R r, P pred, T newVal, indirect_range_tag const &)
{
r.replace_if(r, pred, newVal);
}
/// Replaces all elements matching the given predicate with the new value
///
/// \param r The range
/// \param pred The predicate for matching the old values to replace
/// \param newVal The value to replace any elements which match the given predicate
///
/// \note: Supports Iterable and Indirect Range types
template< ss_typename_param_k R
, ss_typename_param_k P
, ss_typename_param_k T
>
inline void r_replace_if(R r, P pred, T newVal)
{
r_replace_if_impl(r, pred, newVal, r);
}
/* *********************************************************
* replace_copy_if
*/
#if 0
template< ss_typename_param_k RI
, ss_typename_param_k RO
, ss_typename_param_k P
, ss_typename_param_k T
>
inline void r_replace_copy_if_impl(RI ri, RO ro, P pred, T newVal, iterable_range_tag const &, iterable_range_tag const &)
{
std::replace_copy_if(ri.begin(), ri.end(), ro.begin(), pred, newVal);
}
template< ss_typename_param_k RI
, ss_typename_param_k RO
, ss_typename_param_k P
, ss_typename_param_k T
>
inline void r_replace_copy_if_impl(RI ri, RO ro, P pred, T newVal, notional_range_tag const &, notional_range_tag const &)
{
for(; ri; ++ri, ++ro)
{
STLSOFT_ASSERT(!(!ro));
if(pred(*ri))
{
*ro = newVal;
}
}
}
template< ss_typename_param_k RI
, ss_typename_param_k RO
, ss_typename_param_k P
, ss_typename_param_k T
>
inline void r_replace_copy_if_impl(RI ri, RO ro, P pred, T newVal, indirect_range_tag const &, indirect_range_tag const &)
{
ri.replace_copy_if(ro, pred, newVal);
}
template< ss_typename_param_k RI
, ss_typename_param_k RO
, ss_typename_param_k P
, ss_typename_param_k T
>
inline void r_replace_copy_if(RI ri, RO ro, P pred, T newVal)
{
r_replace_copy_if_impl(ri, ro, pe, newVal, ri, ro);
}
#endif /* 0 */
////////////////////////////////////////////////////////////////////////////
// Unit-testing
#ifdef STLSOFT_UNITTEST
# include "./unittest/algorithms_unittest_.h"
#endif /* STLSOFT_UNITTEST */
/* ////////////////////////////////////////////////////////////////////// */
#ifndef RANGELIB_NO_NAMESPACE
# if defined(_STLSOFT_NO_NAMESPACE) || \
defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
} // namespace rangelib
# else
} // namespace rangelib_project
} // namespace stlsoft
# endif /* _STLSOFT_NO_NAMESPACE */
#endif /* !RANGELIB_NO_NAMESPACE */
/* ////////////////////////////////////////////////////////////////////// */
#endif /* !RANGELIB_INCL_RANGELIB_HPP_ALGORITHMS */
/* ////////////////////////////////////////////////////////////////////// */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?