1 /*=============================================================================
2     Copyright (c) 2009 Hartmut Kaiser
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 
8 #if !defined(BOOST_FUSION_NVIEW_SEP_23_2009_0948PM)
9 #define BOOST_FUSION_NVIEW_SEP_23_2009_0948PM
10 
11 #include <boost/fusion/support/config.hpp>
12 #include <boost/mpl/if.hpp>
13 
14 #include <boost/type_traits/add_reference.hpp>
15 #include <boost/type_traits/add_const.hpp>
16 
17 #include <boost/fusion/support/is_view.hpp>
18 #include <boost/fusion/support/sequence_base.hpp>
19 #include <boost/fusion/container/vector.hpp>
20 #include <boost/fusion/sequence/intrinsic/size.hpp>
21 #include <boost/fusion/view/transform_view.hpp>
22 
23 #include <boost/config.hpp>
24 
25 namespace boost { namespace fusion
26 {
27     namespace detail
28     {
29         struct addref
30         {
31             template<typename Sig>
32             struct result;
33 
34             template<typename U>
35             struct result<addref(U)> : add_reference<U> {};
36 
37 #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
38             template <typename T>
39             BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
40             typename add_reference<T>::type
operator ()boost::fusion::detail::addref41             operator()(T& x) const
42             {
43                 return x;
44             }
45 #else
46             template <typename T>
47             BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
48             typename result<addref(T)>::type
operator ()boost::fusion::detail::addref49             operator()(T&& x) const
50             {
51                 return x;
52             }
53 #endif
54         };
55 
56         struct addconstref
57         {
58             template<typename Sig>
59             struct result;
60 
61             template<typename U>
62             struct result<addconstref(U)>
63               : add_reference<typename add_const<U>::type>
64             {};
65 
66             template <typename T>
67             BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
68             typename add_reference<typename add_const<T>::type>::type
operator ()boost::fusion::detail::addconstref69             operator()(T& x) const
70             {
71                 return x;
72             }
73 
74             template <typename T>
75             BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
76             typename add_reference<typename add_const<T>::type>::type
operator ()boost::fusion::detail::addconstref77             operator()(T const& x) const
78             {
79                 return x;
80             }
81         };
82     }
83 
84     struct nview_tag;
85     struct random_access_traversal_tag;
86     struct fusion_sequence_tag;
87 
88     template<typename Sequence, typename Indicies>
89     struct nview
90       : sequence_base<nview<Sequence, Indicies> >
91     {
92         typedef nview_tag fusion_tag;
93         typedef fusion_sequence_tag tag; // this gets picked up by MPL
94         typedef random_access_traversal_tag category;
95 
96         typedef mpl::true_ is_view;
97         typedef Indicies index_type;
98         typedef typename result_of::size<Indicies>::type size;
99 
100         typedef typename mpl::if_<
101             is_const<Sequence>, detail::addconstref, detail::addref
102         >::type transform_type;
103         typedef transform_view<Sequence, transform_type> transform_view_type;
104         typedef typename result_of::as_vector<transform_view_type>::type
105             sequence_type;
106 
107         BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
nviewboost::fusion::nview108         explicit nview(Sequence& val)
109           : seq(sequence_type(transform_view_type(val, transform_type())))
110         {}
111 
112         sequence_type seq;
113     };
114 
115 }}
116 
117 // define the nview() generator functions
118 #include <boost/fusion/view/nview/detail/nview_impl.hpp>
119 
120 #endif
121 
122 
123