1 /*============================================================================= 2 Copyright (c) 2001-2011 Joel de Guzman 3 4 Distributed under the Boost Software License, Version 1.0. (See accompanying 5 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6 ==============================================================================*/ 7 #if !defined(FUSION_TRANSFORM_VIEW_07162005_1037) 8 #define FUSION_TRANSFORM_VIEW_07162005_1037 9 10 #include <boost/fusion/support/config.hpp> 11 #include <boost/static_assert.hpp> 12 #include <boost/fusion/support/detail/access.hpp> 13 #include <boost/fusion/support/is_view.hpp> 14 #include <boost/fusion/support/category_of.hpp> 15 #include <boost/fusion/view/transform_view/transform_view_iterator.hpp> 16 #include <boost/fusion/view/transform_view/transform_view_fwd.hpp> 17 #include <boost/fusion/view/transform_view/detail/begin_impl.hpp> 18 #include <boost/fusion/view/transform_view/detail/end_impl.hpp> 19 #include <boost/fusion/view/transform_view/detail/at_impl.hpp> 20 #include <boost/fusion/view/transform_view/detail/value_at_impl.hpp> 21 #include <boost/fusion/view/detail/strictest_traversal.hpp> 22 #include <boost/fusion/container/vector/vector10.hpp> 23 #include <boost/fusion/sequence/intrinsic/size.hpp> 24 #include <boost/fusion/support/sequence_base.hpp> 25 #include <boost/fusion/sequence/intrinsic/begin.hpp> 26 #include <boost/fusion/sequence/intrinsic/end.hpp> 27 #include <boost/fusion/sequence/intrinsic/size.hpp> 28 #include <boost/mpl/bool.hpp> 29 30 namespace boost { namespace fusion 31 { 32 struct void_; 33 struct transform_view_tag; 34 struct transform_view2_tag; 35 struct fusion_sequence_tag; 36 37 // Binary Version 38 template <typename Sequence1, typename Sequence2, typename F> 39 struct transform_view : sequence_base<transform_view<Sequence1, Sequence2, F> > 40 { 41 BOOST_STATIC_ASSERT(result_of::size<Sequence1>::value == result_of::size<Sequence2>::value); 42 typedef transform_view2_tag fusion_tag; 43 typedef fusion_sequence_tag tag; // this gets picked up by MPL 44 typedef mpl::true_ is_view; 45 46 typedef typename traits::category_of<Sequence1>::type category1; 47 typedef typename traits::category_of<Sequence2>::type category2; 48 typedef typename detail::strictest_traversal< 49 fusion::vector2<Sequence1, Sequence2> >::type category; 50 typedef typename result_of::begin<Sequence1>::type first1_type; 51 typedef typename result_of::begin<Sequence2>::type first2_type; 52 typedef typename result_of::end<Sequence1>::type last1_type; 53 typedef typename result_of::end<Sequence2>::type last2_type; 54 typedef typename result_of::size<Sequence1>::type size; 55 typedef Sequence1 sequence1_type; 56 typedef Sequence2 sequence2_type; 57 typedef F transform_type; 58 59 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED transform_viewboost::fusion::transform_view60 transform_view(Sequence1& in_seq1, Sequence2& in_seq2, F const& binop) 61 : f(binop) 62 , seq1(in_seq1) 63 , seq2(in_seq2) 64 {} 65 66 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED first1boost::fusion::transform_view67 first1_type first1() const { return fusion::begin(seq1); } 68 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED first2boost::fusion::transform_view69 first2_type first2() const { return fusion::begin(seq2); } 70 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED last1boost::fusion::transform_view71 last1_type last1() const { return fusion::end(seq1); } 72 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED last2boost::fusion::transform_view73 last2_type last2() const { return fusion::end(seq2); } 74 75 transform_type f; 76 typename mpl::if_<traits::is_view<Sequence1>, Sequence1, Sequence1&>::type seq1; 77 typename mpl::if_<traits::is_view<Sequence2>, Sequence2, Sequence2&>::type seq2; 78 79 private: 80 // silence MSVC warning C4512: assignment operator could not be generated 81 transform_view& operator= (transform_view const&); 82 }; 83 84 // Unary Version 85 template <typename Sequence, typename F> 86 #if defined(BOOST_NO_PARTIAL_SPECIALIZATION_IMPLICIT_DEFAULT_ARGS) 87 struct transform_view<Sequence, F, void_> : sequence_base<transform_view<Sequence, F, void_> > 88 #else 89 struct transform_view<Sequence, F> : sequence_base<transform_view<Sequence, F> > 90 #endif 91 { 92 typedef transform_view_tag fusion_tag; 93 typedef fusion_sequence_tag tag; // this gets picked up by MPL 94 typedef mpl::true_ is_view; 95 96 typedef typename traits::category_of<Sequence>::type category; 97 typedef typename result_of::begin<Sequence>::type first_type; 98 typedef typename result_of::end<Sequence>::type last_type; 99 typedef typename result_of::size<Sequence>::type size; 100 typedef Sequence sequence_type; 101 typedef F transform_type; 102 103 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED transform_viewboost::fusion::transform_view104 transform_view(Sequence& in_seq, F const& in_f) 105 : seq(in_seq) 106 , f(in_f) 107 {} 108 109 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED firstboost::fusion::transform_view110 first_type first() const { return fusion::begin(seq); } 111 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED lastboost::fusion::transform_view112 last_type last() const { return fusion::end(seq); } 113 typename mpl::if_<traits::is_view<Sequence>, Sequence, Sequence&>::type seq; 114 transform_type f; 115 116 private: 117 // silence MSVC warning C4512: assignment operator could not be generated 118 transform_view& operator= (transform_view const&); 119 }; 120 }} 121 122 #endif 123 124 125