basic_indirect_range_adaptor.hpp

来自「用STL的方式封装了WindowsAPI、COM调用、ACE、ATL、MFC、W」· HPP 代码 · 共 648 行 · 第 1/2 页

HPP
648
字号
        {
            if(pf(val))
            {
                m_b = true;

                return false; // break out of loop
            }

            return true;
        }
    private:
        ss_bool_t   &m_b;
        P           m_pr;
    };

    template<   ss_typename_param_k P
            ,   ss_typename_param_k V
            >
    struct exists_if_2_function
    {
    public:
        exists_if_2_function(ss_bool_t &b, P pr, V &result)
            : m_b(b)
            , m_pr(pr)
            , m_result(result)
        {
            STLSOFT_ASSERT(!b);
        }

    public:
        template <ss_typename_param_k T2>
        ss_bool_t operator ()(T2 val) const
        {
            if(pf(val))
            {
                m_b         =   true;
                m_result    =   val;

                return false; // break out of loop
            }

            return true;
        }
    private:
        ss_bool_t   &m_b;
        P           m_pr;
        V           &m_result;
    };

    template <ss_typename_param_k F>
    struct for_each_function
    {
    public:
        for_each_function(F f)
            : m_f(f)
        {}
    public:
        template <ss_typename_param_k T>
        ss_bool_t operator ()(T v) const
        {
            return (m_f(v), true);
        }
    private:
        F   m_f;
    };

    template<   ss_typename_param_k V
            ,   ss_typename_param_k P
            >
    struct minmax_element_2_function
    {
    public:
        minmax_element_2_function(ss_bool_t &bRetrieved, P pr, V &result)
            : m_bRetrieved(bRetrieved)
            , m_pr(pr)
            , m_result(result)
        {}
    public:
        template <ss_typename_param_k T>
        ss_bool_t operator ()(T val) const
        {
            if(!m_bRetrieved)
            {
                m_result = val;

                m_bRetrieved = true;
            }
            else
            {
                if(m_pr(m_result, val))
                {
                    m_result = val;
                }
            }

            return true;
        }
    private:
        ss_bool_t   &m_bRetrieved;
        P           m_pr;
        V           &m_result;
    };

} // anonymous namespace

#endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */

/* /////////////////////////////////////////////////////////////////////////
 * Classes
 */

/// Runtime adaptor that adapts a Basic Indirect range to an Indirect range.
template <ss_typename_param_k R>
class indirect_range_adaptor
    : public indirect_range_tag
{
public:
    typedef R                                   range_type;
    typedef ss_typename_type_k R::value_type    value_type;

public:
    /// Constructor
    ///
    /// \param r The Basic Indirect range instance to be adapted
    indirect_range_adaptor(range_type r)
        : m_r(r)
    {}

    /// Returns the sum of \c val and the value of each element in the range
    template <ss_typename_param_k T>
    T accumulate(T val) const
    {
        T   total   =   val;

        m_r.for_each_cancelable(accumulate_1_function<T>(total));

        return total;
    }

    /// Returns the sum of \c val and the value of pr applied to each element in the range
    template<   ss_typename_param_k T
            ,   ss_typename_param_k P
            >
    T accumulate(T val, P pr) const
    {
        T   total   =   val;

        m_r.for_each_cancelable(accumulate_2_function<T, P>(total, pr));

        return total;
    }

    /// Copies each element in the range to the output iterator \c o
    template <ss_typename_param_k O>
    O copy(O o) const
    {
        copy_function<O>    cf(o);

        m_r.for_each_cancelable(cf);

        return cf;
    }

    /// Copies each element in the range that satisfies predicate \c pr to the output iterator \c o
    template<   ss_typename_param_k O
            ,   ss_typename_param_k P
            >
    O copy_if(O o, P pr) const
    {
        copy_if_function<O, P>  cf(o, pr);

        m_r.for_each_cancelable(cf);

        return cf;
    }

    /// Returns the number of elements in the range that evaluate equal to \c val
    template <ss_typename_param_k T>
    size_t count(T const &val) const
    {
        size_t  n   =   0;

        m_r.for_each_cancelable(count_function<T>(n, val));

        return n;
    }

    /// Returns the number of elements in the range matching the predicate \c pr
    template <ss_typename_param_k P>
    size_t count_if(P pr) const
    {
        size_t  n   =   0;

        m_r.for_each_cancelable(count_if_function<P>(n, pr));

        return n;
    }

    /// Returns the number of elements in the range
    ptrdiff_t distance() const
    {
        ptrdiff_t   n = 0;

        m_r.for_each_cancelable(distance_function(n));

        return n;
    }

    /// Applied the functor \c f to each element in the array
    template <ss_typename_param_k F>
    F for_each(F f)
    {
        m_r.for_each_cancelable(for_each_function<F>(f));

        return f;
    }

    /// Returns true if the element \c val exists in the range
    template <ss_typename_param_k T>
    ss_bool_t exists(T const &val) const
    {
        ss_bool_t   bExists = false;

        m_r.for_each_cancelable(exists_function<T>(bExists, val));

        return bExists;
    }

    /// Returns true if any element in given predicate \c pr evaluates true
    /// any element in the range
    template <ss_typename_param_k P>
    ss_bool_t exists_if(P pr) const
    {
        ss_bool_t   bExists = false;

        m_r.for_each_cancelable(exists_if_1_function<P>(bExists, pr));

        return bExists;
    }

    /// Returns true if any element in given predicate \c pr evaluates true
    /// any element in the range, and places the matching element in \c result
    template<   ss_typename_param_k P
            ,   ss_typename_param_k T>
    ss_bool_t exists_if(P pr, T &result) const
    {
        ss_bool_t   bExists = false;

        m_r.for_each_cancelable(exists_if_2_function<P, T>(bExists, pr, result));

        return bExists;
    }

    /// Returns the value of the maximum elements in the range
    value_type max_element() const
    {
        return minmax_element(std::less<value_type>());
    }

    /// Returns the value of the maximum elements in the range, as determined by
    /// the comparand predicate \c pr
    template <ss_typename_param_k P>
    value_type max_element(P pr) const
    {
        return minmax_element(pr);
    }

    /// Returns the value of the minimum elements in the range
    value_type min_element() const
    {
        return minmax_element(std::greater<value_type>());
    }

    /// Returns the value of the minimum elements in the range, as determined by
    /// the comparand predicate \c pr
    template <ss_typename_param_k P>
    value_type min_element(P pr) const
    {
        return minmax_element(std::not2(pr));
    }

private:
    template <ss_typename_param_k P>
    value_type minmax_element(P pr) const
    {
        ss_bool_t   bRetrieved;
        value_type  result;

        m_r.for_each_cancelable(minmax_element_2_function<value_type, P>(bRetrieved, pr, result));

        STLSOFT_ASSERT(bRetrieved);

        return result;
    }

private:
    range_type  m_r;
};

////////////////////////////////////////////////////////////////////////////
// Unit-testing

#ifdef STLSOFT_UNITTEST
# include "./unittest/basic_indirect_range_adaptor_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_BASIC_INDIRECT_RANGE_ADAPTOR */

/* ////////////////////////////////////////////////////////////////////// */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?