File indexing completed on 2025-01-19 09:47:36
0001
0002
0003
0004
0005
0006 #if !defined(BOOST_SPIRIT_KARMA_COLUMNS_DEC_03_2009_0736AM)
0007 #define BOOST_SPIRIT_KARMA_COLUMNS_DEC_03_2009_0736AM
0008
0009 #if defined(_MSC_VER)
0010 #pragma once
0011 #endif
0012
0013 #include <boost/spirit/home/karma/meta_compiler.hpp>
0014 #include <boost/spirit/home/karma/generator.hpp>
0015 #include <boost/spirit/home/karma/domain.hpp>
0016 #include <boost/spirit/home/karma/delimit_out.hpp>
0017 #include <boost/spirit/home/karma/detail/default_width.hpp>
0018 #include <boost/spirit/home/karma/auxiliary/eol.hpp>
0019 #include <boost/spirit/home/karma/auxiliary/lazy.hpp>
0020 #include <boost/spirit/home/support/unused.hpp>
0021 #include <boost/spirit/home/support/common_terminals.hpp>
0022 #include <boost/spirit/home/support/has_semantic_action.hpp>
0023 #include <boost/spirit/home/support/handles_container.hpp>
0024 #include <boost/spirit/home/karma/detail/attributes.hpp>
0025 #include <boost/spirit/home/support/info.hpp>
0026 #include <boost/fusion/include/at.hpp>
0027 #include <boost/fusion/include/vector.hpp>
0028 #include <boost/integer_traits.hpp>
0029
0030 namespace boost { namespace spirit
0031 {
0032
0033
0034
0035 template <>
0036 struct use_directive<karma::domain, tag::columns>
0037 : mpl::true_ {};
0038
0039
0040 template <typename T>
0041 struct use_directive<karma::domain
0042 , terminal_ex<tag::columns, fusion::vector1<T> > >
0043 : mpl::true_ {};
0044
0045
0046 template <>
0047 struct use_lazy_directive<karma::domain, tag::columns, 1>
0048 : mpl::true_ {};
0049
0050
0051
0052 template <typename T1, typename T2>
0053 struct use_directive<karma::domain
0054 , terminal_ex<tag::columns, fusion::vector2<T1, T2> > >
0055 : boost::spirit::traits::matches<karma::domain, T2> {};
0056
0057
0058 template <>
0059 struct use_lazy_directive<karma::domain, tag::columns, 2>
0060 : mpl::true_ {};
0061
0062 }}
0063
0064 namespace boost { namespace spirit { namespace karma
0065 {
0066 #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
0067 using spirit::columns;
0068 #endif
0069 using spirit::columns_type;
0070
0071 namespace detail
0072 {
0073 #ifdef _MSC_VER
0074 # pragma warning(push)
0075 # pragma warning(disable: 4512)
0076 #endif
0077 template <typename Delimiter, typename ColumnDelimiter>
0078 struct columns_delimiter
0079 {
0080 columns_delimiter(Delimiter const& delim
0081 , ColumnDelimiter const& cdelim, unsigned int const numcols)
0082 : delimiter(delim), column_delimiter(cdelim)
0083 , numcolumns(numcols), count(0) {}
0084
0085 template <typename OutputIterator, typename Context
0086 , typename Delimiter_, typename Attribute>
0087 bool generate(OutputIterator& sink, Context&, Delimiter_ const&
0088 , Attribute const&) const
0089 {
0090
0091 if (!karma::delimit_out(sink, delimiter))
0092 return false;
0093
0094
0095
0096 if ((++count % numcolumns) == 0)
0097 return karma::delimit_out(sink, column_delimiter);
0098 return true;
0099 }
0100
0101
0102
0103 template <typename OutputIterator>
0104 bool delimit_out(OutputIterator& sink) const
0105 {
0106 if (count % numcolumns)
0107 return karma::delimit_out(sink, column_delimiter);
0108 return true;
0109 }
0110
0111 Delimiter const& delimiter;
0112 ColumnDelimiter const& column_delimiter;
0113 unsigned int const numcolumns;
0114 mutable unsigned int count;
0115 };
0116 #ifdef _MSC_VER
0117 # pragma warning(pop)
0118 #endif
0119 }
0120
0121
0122
0123
0124 template <typename Subject, typename NumColumns, typename ColumnsDelimiter>
0125 struct columns_generator
0126 : unary_generator<columns_generator<Subject, NumColumns, ColumnsDelimiter> >
0127 {
0128 typedef Subject subject_type;
0129 typedef ColumnsDelimiter delimiter_type;
0130
0131 typedef mpl::int_<
0132 subject_type::properties::value | delimiter_type::properties::value
0133 > properties;
0134
0135 template <typename Context, typename Iterator>
0136 struct attribute
0137 : traits::attribute_of<subject_type, Context, Iterator>
0138 {};
0139
0140 columns_generator(Subject const& subject, NumColumns const& cols
0141 , ColumnsDelimiter const& cdelimiter)
0142 : subject(subject), numcolumns(cols), column_delimiter(cdelimiter)
0143 {
0144
0145 BOOST_ASSERT(numcolumns > 0);
0146 }
0147
0148 template <typename OutputIterator, typename Context
0149 , typename Delimiter, typename Attribute>
0150 bool generate(OutputIterator& sink, Context& ctx
0151 , Delimiter const& delimiter, Attribute const& attr) const
0152 {
0153
0154
0155
0156 typedef detail::columns_delimiter<
0157 Delimiter, ColumnsDelimiter
0158 > columns_delimiter_type;
0159
0160 columns_delimiter_type d(delimiter, column_delimiter, numcolumns);
0161 return subject.generate(sink, ctx, d, attr) && d.delimit_out(sink);
0162 }
0163
0164 template <typename Context>
0165 info what(Context& context) const
0166 {
0167 return info("columns", subject.what(context));
0168 }
0169
0170 Subject subject;
0171 NumColumns numcolumns;
0172 ColumnsDelimiter column_delimiter;
0173 };
0174
0175
0176
0177
0178
0179
0180 template <typename Subject, typename Modifiers>
0181 struct make_directive<tag::columns, Subject, Modifiers>
0182 {
0183 typedef typename
0184 result_of::compile<karma::domain, eol_type, Modifiers>::type
0185 columns_delimiter_type;
0186 typedef columns_generator<
0187 Subject, detail::default_columns, columns_delimiter_type>
0188 result_type;
0189
0190 result_type operator()(unused_type, Subject const& subject
0191 , unused_type) const
0192 {
0193 #if defined(BOOST_SPIRIT_NO_PREDEFINED_TERMINALS)
0194 eol_type const eol = eol_type();
0195 #endif
0196 return result_type(subject, detail::default_columns()
0197 , compile<karma::domain>(eol));
0198 }
0199 };
0200
0201
0202 template <typename T, typename Subject, typename Modifiers>
0203 struct make_directive<
0204 terminal_ex<tag::columns, fusion::vector1<T> >
0205 , Subject, Modifiers
0206 , typename enable_if_c<integer_traits<T>::is_integral>::type>
0207 {
0208 typedef typename
0209 result_of::compile<karma::domain, eol_type, Modifiers>::type
0210 columns_delimiter_type;
0211 typedef columns_generator<
0212 Subject, T, columns_delimiter_type
0213 > result_type;
0214
0215 template <typename Terminal>
0216 result_type operator()(Terminal const& term, Subject const& subject
0217 , unused_type) const
0218 {
0219 #if defined(BOOST_SPIRIT_NO_PREDEFINED_TERMINALS)
0220 eol_type const eol = eol_type();
0221 #endif
0222 return result_type(subject, fusion::at_c<0>(term.args)
0223 , compile<karma::domain>(eol));
0224 }
0225 };
0226
0227
0228 template <typename T, typename Subject, typename Modifiers>
0229 struct make_directive<
0230 terminal_ex<tag::columns, fusion::vector1<T> >
0231 , Subject, Modifiers
0232 , typename enable_if<
0233 mpl::and_<
0234 spirit::traits::matches<karma::domain, T>,
0235 mpl::not_<mpl::bool_<integer_traits<T>::is_integral> >
0236 >
0237 >::type>
0238 {
0239 typedef typename
0240 result_of::compile<karma::domain, T, Modifiers>::type
0241 columns_delimiter_type;
0242 typedef columns_generator<
0243 Subject, detail::default_columns, columns_delimiter_type
0244 > result_type;
0245
0246 template <typename Terminal>
0247 result_type operator()(Terminal const& term, Subject const& subject
0248 , unused_type) const
0249 {
0250 return result_type(subject, detail::default_columns()
0251 , compile<karma::domain>(fusion::at_c<0>(term.args)));
0252 }
0253 };
0254
0255
0256
0257 template <typename T1, typename T2, typename Subject, typename Modifiers>
0258 struct make_directive<
0259 terminal_ex<tag::columns, fusion::vector2<T1, T2> >
0260 , Subject, Modifiers>
0261 {
0262 typedef typename
0263 result_of::compile<karma::domain, T2, Modifiers>::type
0264 columns_delimiter_type;
0265 typedef columns_generator<
0266 Subject, T1, columns_delimiter_type
0267 > result_type;
0268
0269 template <typename Terminal>
0270 result_type operator()(Terminal const& term, Subject const& subject
0271 , unused_type) const
0272 {
0273 return result_type (subject, fusion::at_c<0>(term.args)
0274 , compile<karma::domain>(fusion::at_c<1>(term.args)));
0275 }
0276 };
0277
0278 }}}
0279
0280 namespace boost { namespace spirit { namespace traits
0281 {
0282
0283 template <typename Subject, typename T1, typename T2>
0284 struct has_semantic_action<karma::columns_generator<Subject, T1, T2> >
0285 : unary_has_semantic_action<Subject> {};
0286
0287
0288 template <typename Subject, typename T1, typename T2, typename Attribute
0289 , typename Context, typename Iterator>
0290 struct handles_container<
0291 karma::columns_generator<Subject, T1, T2>, Attribute
0292 , Context, Iterator>
0293 : unary_handles_container<Subject, Attribute, Context, Iterator> {};
0294 }}}
0295
0296 #endif