⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 reduce.hpp

📁 Boost provides free peer-reviewed portable C++ source libraries. We emphasize libraries that work
💻 HPP
📖 第 1 页 / 共 3 页
字号:
/*    Copyright 2005-2007 Adobe Systems Incorporated       Use, modification and distribution are subject to the Boost Software License,    Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at    http://www.boost.org/LICENSE_1_0.txt).    See http://opensource.adobe.com/gil for most recent version including documentation.*//*************************************************************************************************/#ifndef GIL_REDUCE_HPP#define GIL_REDUCE_HPP#include <boost/mpl/insert_range.hpp>#include <boost/mpl/range_c.hpp>#include <boost/mpl/vector_c.hpp>#include <boost/mpl/back.hpp>#include <boost/mpl/vector.hpp>#include <boost/mpl/long.hpp>#include <boost/mpl/logical.hpp>#include <boost/mpl/transform.hpp>#include <boost/mpl/insert.hpp>#include <boost/mpl/transform.hpp>#include "../../metafunctions.hpp"#include "../../typedefs.hpp"#include "dynamic_at_c.hpp"/////////////////////////////////////////////////////////////////////////////////////////// \file               /// \brief Constructs for static-to-dynamic integer convesion/// \author Lubomir Bourdev and Hailin Jin \n///         Adobe Systems Incorporated/// \date 2005-2007 \n Last updated on May 4, 2006///////////////////////////////////////////////////////////////////////////////////////////#ifdef GIL_REDUCE_CODE_BLOAT// Max number of cases in the cross-expension of binary operation for it to be reduced as unary#define GIL_BINARY_REDUCE_LIMIT 226namespace boost { namespace mpl {////////////////////////////////////////////////////////// Mapping vector - represents the mapping of one type vector to another///  It is not a full-blown MPL Random Access Type sequence; just has at_c and size implemented////// SrcTypes, DstTypes: MPL Random Access Type Sequences////// Implements size and at_c to behave as if this is an MPL vector of integers///////////////////////////////////////////////////////template <typename SrcTypes, typename DstTypes>struct mapping_vector {};template <typename SrcTypes, typename DstTypes, long K>struct at_c<mapping_vector<SrcTypes,DstTypes>, K> {    static const std::size_t value=size<DstTypes>::value - order<DstTypes, typename at_c<SrcTypes,K>::type>::type::value +1;    typedef size_t<value> type;};template <typename SrcTypes, typename DstTypes>struct size<mapping_vector<SrcTypes,DstTypes> > {    typedef typename size<SrcTypes>::type type;    static const std::size_t value=type::value;};////////////////////////////////////////////////////////// copy_to_vector - copies a sequence (mpl::set) to vector.////// Temporary solution because I couldn't get mpl::copy to do this./// This is what I tried:/// mpl::copy<SET, mpl::back_inserter<mpl::vector<> > >::type;/// It works when SET is mpl::vector, but not when SET is mpl::set...///////////////////////////////////////////////////////namespace detail {    template <typename SFirst, std::size_t NLeft>    struct copy_to_vector_impl {    private:        typedef typename deref<SFirst>::type T;        typedef typename next<SFirst>::type next;        typedef typename copy_to_vector_impl<next, NLeft-1>::type rest;    public:        typedef typename push_front<rest, T>::type type;    };    template <typename SFirst>     struct copy_to_vector_impl<SFirst,1> {        typedef vector<typename deref<SFirst>::type> type;    };}template <typename Src>struct copy_to_vector {    typedef typename detail::copy_to_vector_impl<typename begin<Src>::type, size<Src>::value>::type type;};template <>struct copy_to_vector<set<> > {    typedef vector0<> type;};} } // boost::mplnamespace boost { namespace gil {////////////////////////////////////////////////////////// /// unary_reduce, binary_reduce - given an MPL Random Access Sequence,/// dynamically specified index to that container, the bits of an instance of the corresponding type and/// a generic operation, invokes the operation on the given type//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// \brief Unary reduce.////// Given a set of types and an operation, reduces each type in the set (to reduced_t), then removes duplicates (to unique_t)/// To apply the operation, first constructs a lookup table that maps each element from Types to its place in unique_t and uses it to map/// the index to anther index (in map_index). Then invokes apply_operation_base on the unique types with the new index.//////////////////////////////////////////////////////////template <typename Types, typename Op>struct unary_reduce_impl {    typedef typename mpl::transform<Types, detail::reduce<Op, mpl::_1> >::type reduced_t;    typedef typename mpl::copy<reduced_t, mpl::inserter<mpl::set<>, mpl::insert<mpl::_1,mpl::_2> > >::type unique_t;    static const bool is_single=mpl::size<unique_t>::value==1;};template <typename Types, typename Op, bool IsSingle=unary_reduce_impl<Types,Op>::is_single>struct unary_reduce : public unary_reduce_impl<Types,Op> {    typedef typename unary_reduce_impl<Types,Op>::reduced_t reduced_t;    typedef typename unary_reduce_impl<Types,Op>::unique_t unique_t;    static unsigned short inline map_index(std::size_t index) {        typedef typename mpl::mapping_vector<reduced_t, unique_t> indices_t;        return gil::at_c<indices_t, unsigned short>(index);    }    template <typename Bits> GIL_FORCEINLINE static typename Op::result_type applyc(const Bits& bits, std::size_t index, Op op) {        return apply_operation_basec<unique_t>(bits,map_index(index),op);    }    template <typename Bits> GIL_FORCEINLINE static typename Op::result_type apply(Bits& bits, std::size_t index, Op op) {        return apply_operation_base<unique_t>(bits,map_index(index),op);    }};template <typename Types, typename Op>struct unary_reduce<Types,Op,true> : public unary_reduce_impl<Types,Op> {    typedef typename unary_reduce_impl<Types,Op>::unique_t unique_t;    static unsigned short inline map_index(std::size_t index) { return 0; }    template <typename Bits> GIL_FORCEINLINE static typename Op::result_type applyc(const Bits& bits, std::size_t index, Op op) {        return op(*gil_reinterpret_cast_c<const typename mpl::front<unique_t>::type*>(&bits));    }    template <typename Bits> GIL_FORCEINLINE static typename Op::result_type apply(Bits& bits, std::size_t index, Op op) {        return op(*gil_reinterpret_cast<typename       mpl::front<unique_t>::type*>(&bits));    }};////////////////////////////////////////////////////////// /// \brief Binary reduce.////// Given two sets of types, Types1 and Types2, first performs unary reduction on each. Then checks if the product of their sizes is above/// the GIL_BINARY_REDUCE_LIMIT limit. If so, the operation is too complex to be binary-reduced and uses a specialization of binary_reduce_impl/// to simply call the binary apply_operation_base (which performs two nested 1D apply operations)/// If the operation is not too complex, uses the other specialization of binary_reduce_impl to create a cross-product of the input types/// and performs unary reduction on the result (bin_reduced_t). To apply the binary operation, it simply invokes a unary apply_operation_base/// on the reduced cross-product types//////////////////////////////////////////////////////////namespace detail {    struct pair_generator {        template <typename Vec2> struct apply {            typedef std::pair<const typename mpl::at_c<Vec2,0>::type*, const typename mpl::at_c<Vec2,1>::type*> type;        };    };    // When the types are not too large, applies reduce on their cross product    template <typename Unary1, typename Unary2, typename Op, bool IsComplex>    struct binary_reduce_impl {    //private:        typedef typename mpl::copy_to_vector<typename Unary1::unique_t>::type vec1_types;        typedef typename mpl::copy_to_vector<typename Unary2::unique_t>::type vec2_types;        typedef mpl::cross_vector<mpl::vector2<vec1_types, vec2_types>, pair_generator> BIN_TYPES;        typedef unary_reduce<BIN_TYPES,Op> bin_reduced_t;                static unsigned short inline map_index(std::size_t index1, std::size_t index2) {            unsigned short r1=Unary1::map_index(index1);            unsigned short r2=Unary2::map_index(index2);            return bin_reduced_t::map_index(r2*mpl::size<vec1_types>::value + r1);        }    public:        typedef typename bin_reduced_t::unique_t unique_t;        template <typename Bits1, typename Bits2>        static typename Op::result_type inline apply(const Bits1& bits1, std::size_t index1, const Bits2& bits2, std::size_t index2, Op op) {            std::pair<const void*,const void*> pr(&bits1, &bits2);            return apply_operation_basec<unique_t>(pr, map_index(index1,index2),op);        }    };    // When the types are large performs a double-dispatch. Binary reduction is not done.    template <typename Unary1, typename Unary2, typename Op>    struct binary_reduce_impl<Unary1,Unary2,Op,true> {        template <typename Bits1, typename Bits2>        static typename Op::result_type inline apply(const Bits1& bits1, std::size_t index1, const Bits2& bits2, std::size_t index2, Op op) {            return apply_operation_base<Unary1::unique_t,Unary2::unique_t>(bits1, index1, bits2, index2, op);        }    };}template <typename Types1, typename Types2, typename Op>struct binary_reduce {//private:    typedef unary_reduce<Types1,Op> unary1_t;    typedef unary_reduce<Types2,Op> unary2_t;    static const std::size_t CROSS_SIZE = mpl::size<typename unary1_t::unique_t>::value *                                           mpl::size<typename unary2_t::unique_t>::value;    typedef detail::binary_reduce_impl<unary1_t,unary2_t,Op, (CROSS_SIZE>GIL_BINARY_REDUCE_LIMIT)> impl;public:    template <typename Bits1, typename Bits2>    static typename Op::result_type inline apply(const Bits1& bits1, std::size_t index1, const Bits2& bits2, std::size_t index2, Op op) {        return impl::apply(bits1,index1,bits2,index2,op);    }};template <typename Types, typename UnaryOp>GIL_FORCEINLINE typename UnaryOp::result_type apply_operation(variant<Types>& arg, UnaryOp op) {    return unary_reduce<Types,UnaryOp>::template apply(arg._bits, arg._index ,op);}template <typename Types, typename UnaryOp>GIL_FORCEINLINE typename UnaryOp::result_type apply_operation(const variant<Types>& arg, UnaryOp op) {    return unary_reduce<Types,UnaryOp>::template applyc(arg._bits, arg._index ,op);}template <typename Types1, typename Types2, typename BinaryOp>GIL_FORCEINLINE typename BinaryOp::result_type apply_operation(const variant<Types1>& arg1, const variant<Types2>& arg2, BinaryOp op) {        return binary_reduce<Types1,Types2,BinaryOp>::template apply(arg1._bits, arg1._index, arg2._bits, arg2._index, op);}#undef GIL_BINARY_REDUCE_LIMIT} }  // namespace gil

⌨️ 快捷键说明

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