1 // Copyright (c) 2001-2011 Hartmut Kaiser 2 // 3 // Distributed under the Boost Software License, Version 1.0. (See accompanying 4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 5 6 #if !defined(BOOST_PP_IS_ITERATING) 7 8 #if !defined(BOOST_SPIRIT_KARMA_GENERATE_ATTR_APR_23_2009_0541PM) 9 #define BOOST_SPIRIT_KARMA_GENERATE_ATTR_APR_23_2009_0541PM 10 11 #include <boost/spirit/home/karma/generate.hpp> 12 13 #include <boost/fusion/include/vector.hpp> 14 #include <boost/preprocessor/cat.hpp> 15 #include <boost/preprocessor/iterate.hpp> 16 #include <boost/preprocessor/repetition/enum.hpp> 17 #include <boost/preprocessor/repetition/enum_params.hpp> 18 #include <boost/preprocessor/repetition/enum_binary_params.hpp> 19 20 #define BOOST_PP_FILENAME_1 <boost/spirit/home/karma/generate_attr.hpp> 21 #define BOOST_PP_ITERATION_LIMITS (2, SPIRIT_ARGUMENTS_LIMIT) 22 #include BOOST_PP_ITERATE() 23 24 #endif 25 26 /////////////////////////////////////////////////////////////////////////////// 27 // 28 // Preprocessor vertical repetition code 29 // 30 /////////////////////////////////////////////////////////////////////////////// 31 #else // defined(BOOST_PP_IS_ITERATING) 32 33 #define N BOOST_PP_ITERATION() 34 #define BOOST_SPIRIT_KARMA_ATTRIBUTE_REFERENCE(z, n, A) \ 35 BOOST_PP_CAT(A, n) const& 36 37 namespace boost { namespace spirit { namespace karma 38 { 39 /////////////////////////////////////////////////////////////////////////// 40 template <typename OutputIterator, typename Properties, typename Expr 41 , BOOST_PP_ENUM_PARAMS(N, typename A)> 42 inline bool generate(detail::output_iterator<OutputIterator,Properties> & sink,Expr const & expr,BOOST_PP_ENUM_BINARY_PARAMS (N,A,const & attr))43 generate( 44 detail::output_iterator<OutputIterator, Properties>& sink 45 , Expr const& expr 46 , BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& attr)) 47 { 48 // Report invalid expression error as early as possible. 49 // If you got an error_invalid_expression error message here, 50 // then the expression (expr) is not a valid spirit karma expression. 51 BOOST_SPIRIT_ASSERT_MATCH(karma::domain, Expr); 52 53 typedef fusion::vector< 54 BOOST_PP_ENUM(N, BOOST_SPIRIT_KARMA_ATTRIBUTE_REFERENCE, A) 55 > vector_type; 56 57 vector_type attr (BOOST_PP_ENUM_PARAMS(N, attr)); 58 return compile<karma::domain>(expr).generate(sink, unused, unused, attr); 59 } 60 61 template <typename OutputIterator, typename Expr 62 , BOOST_PP_ENUM_PARAMS(N, typename A)> 63 inline bool generate(OutputIterator & sink_,Expr const & expr,BOOST_PP_ENUM_BINARY_PARAMS (N,A,const & attr))64 generate( 65 OutputIterator& sink_ 66 , Expr const& expr 67 , BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& attr)) 68 { 69 typedef traits::properties_of< 70 typename result_of::compile<karma::domain, Expr>::type 71 > properties; 72 73 // wrap user supplied iterator into our own output iterator 74 detail::output_iterator<OutputIterator 75 , mpl::int_<properties::value> > sink(sink_); 76 return karma::generate(sink, expr, BOOST_PP_ENUM_PARAMS(N, attr)); 77 } 78 79 template <typename OutputIterator, typename Expr 80 , BOOST_PP_ENUM_PARAMS(N, typename A)> 81 inline bool generate(OutputIterator const & sink_,Expr const & expr,BOOST_PP_ENUM_BINARY_PARAMS (N,A,const & attr))82 generate( 83 OutputIterator const& sink_ 84 , Expr const& expr 85 , BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& attr)) 86 { 87 OutputIterator sink = sink_; 88 return karma::generate(sink, expr, BOOST_PP_ENUM_PARAMS(N, attr)); 89 } 90 91 /////////////////////////////////////////////////////////////////////////// 92 template <typename OutputIterator, typename Properties, typename Expr 93 , typename Delimiter, BOOST_PP_ENUM_PARAMS(N, typename A)> 94 inline bool generate_delimited(detail::output_iterator<OutputIterator,Properties> & sink,Expr const & expr,Delimiter const & delimiter,BOOST_SCOPED_ENUM (delimit_flag)pre_delimit,BOOST_PP_ENUM_BINARY_PARAMS (N,A,const & attr))95 generate_delimited( 96 detail::output_iterator<OutputIterator, Properties>& sink 97 , Expr const& expr 98 , Delimiter const& delimiter 99 , BOOST_SCOPED_ENUM(delimit_flag) pre_delimit 100 , BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& attr)) 101 { 102 // Report invalid expression error as early as possible. 103 // If you got an error_invalid_expression error message here, 104 // then either the expression (expr) or skipper is not a valid 105 // spirit karma expression. 106 BOOST_SPIRIT_ASSERT_MATCH(karma::domain, Expr); 107 BOOST_SPIRIT_ASSERT_MATCH(karma::domain, Delimiter); 108 109 typename result_of::compile<karma::domain, Delimiter>::type const 110 delimiter_ = compile<karma::domain>(delimiter); 111 112 if (pre_delimit == delimit_flag::predelimit && 113 !karma::delimit_out(sink, delimiter_)) 114 { 115 return false; 116 } 117 118 typedef fusion::vector< 119 BOOST_PP_ENUM(N, BOOST_SPIRIT_KARMA_ATTRIBUTE_REFERENCE, A) 120 > vector_type; 121 122 vector_type attr (BOOST_PP_ENUM_PARAMS(N, attr)); 123 return compile<karma::domain>(expr). 124 generate(sink, unused, delimiter_, attr); 125 } 126 127 template <typename OutputIterator, typename Expr, typename Delimiter 128 , BOOST_PP_ENUM_PARAMS(N, typename A)> 129 inline bool generate_delimited(OutputIterator & sink_,Expr const & expr,Delimiter const & delimiter,BOOST_SCOPED_ENUM (delimit_flag)pre_delimit,BOOST_PP_ENUM_BINARY_PARAMS (N,A,const & attr))130 generate_delimited( 131 OutputIterator& sink_ 132 , Expr const& expr 133 , Delimiter const& delimiter 134 , BOOST_SCOPED_ENUM(delimit_flag) pre_delimit 135 , BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& attr)) 136 { 137 typedef traits::properties_of< 138 typename result_of::compile<karma::domain, Expr>::type 139 > properties; 140 typedef traits::properties_of< 141 typename result_of::compile<karma::domain, Delimiter>::type 142 > delimiter_properties; 143 144 // wrap user supplied iterator into our own output iterator 145 detail::output_iterator<OutputIterator 146 , mpl::int_<properties::value | delimiter_properties::value> 147 > sink(sink_); 148 return karma::generate_delimited(sink, expr, delimiter, pre_delimit 149 , BOOST_PP_ENUM_PARAMS(N, attr)); 150 } 151 152 template <typename OutputIterator, typename Expr, typename Delimiter 153 , BOOST_PP_ENUM_PARAMS(N, typename A)> 154 inline bool generate_delimited(OutputIterator const & sink_,Expr const & expr,Delimiter const & delimiter,BOOST_SCOPED_ENUM (delimit_flag)pre_delimit,BOOST_PP_ENUM_BINARY_PARAMS (N,A,const & attr))155 generate_delimited( 156 OutputIterator const& sink_ 157 , Expr const& expr 158 , Delimiter const& delimiter 159 , BOOST_SCOPED_ENUM(delimit_flag) pre_delimit 160 , BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& attr)) 161 { 162 OutputIterator sink = sink_; 163 return karma::generate_delimited(sink, expr, delimiter, pre_delimit 164 , BOOST_PP_ENUM_PARAMS(N, attr)); 165 } 166 167 /////////////////////////////////////////////////////////////////////////// 168 template <typename OutputIterator, typename Expr, typename Delimiter 169 , BOOST_PP_ENUM_PARAMS(N, typename A)> 170 inline bool generate_delimited(OutputIterator & sink_,Expr const & expr,Delimiter const & delimiter,BOOST_PP_ENUM_BINARY_PARAMS (N,A,const & attr))171 generate_delimited( 172 OutputIterator& sink_ 173 , Expr const& expr 174 , Delimiter const& delimiter 175 , BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& attr)) 176 { 177 typedef traits::properties_of< 178 typename result_of::compile<karma::domain, Expr>::type 179 > properties; 180 typedef traits::properties_of< 181 typename result_of::compile<karma::domain, Delimiter>::type 182 > delimiter_properties; 183 184 // wrap user supplied iterator into our own output iterator 185 detail::output_iterator<OutputIterator 186 , mpl::int_<properties::value | delimiter_properties::value> 187 > sink(sink_); 188 return karma::generate_delimited(sink, expr, delimiter 189 , delimit_flag::dont_predelimit, BOOST_PP_ENUM_PARAMS(N, attr)); 190 } 191 192 template <typename OutputIterator, typename Expr, typename Delimiter 193 , BOOST_PP_ENUM_PARAMS(N, typename A)> 194 inline bool generate_delimited(OutputIterator const & sink_,Expr const & expr,Delimiter const & delimiter,BOOST_PP_ENUM_BINARY_PARAMS (N,A,const & attr))195 generate_delimited( 196 OutputIterator const& sink_ 197 , Expr const& expr 198 , Delimiter const& delimiter 199 , BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& attr)) 200 { 201 OutputIterator sink = sink_; 202 return karma::generate_delimited(sink, expr, delimiter 203 , delimit_flag::dont_predelimit, BOOST_PP_ENUM_PARAMS(N, attr)); 204 } 205 206 }}} 207 208 #undef BOOST_SPIRIT_KARMA_ATTRIBUTE_REFERENCE 209 #undef N 210 211 #endif // defined(BOOST_PP_IS_ITERATING) 212 213