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 + -
显示快捷键?