1 // Copyright (c) 2001-2011 Hartmut Kaiser
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)
6 #if !defined(BOOST_SPIRIT_KARMA_FORMAT_MANIP_MAY_03_2007_1424PM)
7 #define BOOST_SPIRIT_KARMA_FORMAT_MANIP_MAY_03_2007_1424PM
15 #include <boost/spirit/home/karma/generate.hpp>
16 #include <boost/spirit/home/support/iterators/ostream_iterator.hpp>
17 #include <boost/mpl/bool.hpp>
19 ///////////////////////////////////////////////////////////////////////////////
20 namespace boost { namespace spirit { namespace karma { namespace detail
22 ///////////////////////////////////////////////////////////////////////////
23 template <typename Expr
24 , typename CopyExpr = mpl::false_, typename CopyAttr = mpl::false_
25 , typename Delimiter = unused_type, typename Attribute = unused_type>
28 // This assertion makes sure we don't hit the only code path which is
29 // not implemented (because it isn't needed), where both, the
30 // expression and the attribute need to be held as a copy.
31 BOOST_SPIRIT_ASSERT_MSG(!CopyExpr::value || !CopyAttr::value
32 , error_invalid_should_not_happen, ());
34 format_manip(Expr const& xpr, Delimiter const& d, Attribute const& a)
35 : expr(xpr), delim(d), pre(delimit_flag::dont_predelimit), attr(a) {}
37 format_manip(Expr const& xpr, Delimiter const& d
38 , BOOST_SCOPED_ENUM(delimit_flag) pre_delimit, Attribute const& a)
39 : expr(xpr), delim(d), pre(pre_delimit), attr(a) {}
42 Delimiter const& delim;
43 BOOST_SCOPED_ENUM(delimit_flag) const pre;
44 Attribute const& attr;
47 // silence MSVC warning C4512: assignment operator could not be generated
48 format_manip& operator= (format_manip const&);
51 template <typename Expr, typename Delimiter, typename Attribute>
52 struct format_manip<Expr, mpl::false_, mpl::true_, Delimiter, Attribute>
54 format_manip(Expr const& xpr, Delimiter const& d, Attribute const& a)
55 : expr(xpr), delim(d), pre(delimit_flag::dont_predelimit), attr(a) {}
57 format_manip(Expr const& xpr, Delimiter const& d
58 , BOOST_SCOPED_ENUM(delimit_flag) pre_delimit, Attribute const& a)
59 : expr(xpr), delim(d), pre(pre_delimit), attr(a) {}
62 Delimiter const& delim;
63 BOOST_SCOPED_ENUM(delimit_flag) const pre;
67 // silence MSVC warning C4512: assignment operator could not be generated
68 format_manip& operator= (format_manip const&);
71 template <typename Expr, typename Delimiter, typename Attribute>
72 struct format_manip<Expr, mpl::true_, mpl::false_, Delimiter, Attribute>
74 format_manip(Expr const& xpr, Delimiter const& d, Attribute const& a)
75 : expr(xpr), delim(d), pre(delimit_flag::dont_predelimit), attr(a) {}
77 format_manip(Expr const& xpr, Delimiter const& d
78 , BOOST_SCOPED_ENUM(delimit_flag) pre_delimit, Attribute const& a)
79 : expr(xpr), delim(d), pre(pre_delimit), attr(a) {}
82 Delimiter const& delim;
83 BOOST_SCOPED_ENUM(delimit_flag) const pre;
84 Attribute const& attr;
87 // silence MSVC warning C4512: assignment operator could not be generated
88 format_manip& operator= (format_manip const&);
91 ///////////////////////////////////////////////////////////////////////////
92 template <typename Expr, typename Enable = void>
95 // Report invalid expression error as early as possible.
96 // If you got an error_invalid_expression error message here,
97 // then the expression (Expr) is not a valid spirit karma expression.
98 // Did you intend to use the auto_ facilities while forgetting to
99 // #include <boost/spirit/include/karma_format_auto.hpp>?
100 BOOST_SPIRIT_ASSERT_MATCH(karma::domain, Expr);
103 template <typename Expr>
105 , typename enable_if<traits::matches<karma::domain, Expr> >::type>
107 typedef format_manip<Expr> type;
109 static type call(Expr const& expr)
111 return type(expr, unused, unused);
115 ///////////////////////////////////////////////////////////////////////////
116 template <typename Expr, typename Delimiter, typename Enable = void>
117 struct format_delimited
119 // Report invalid expression error as early as possible.
120 // If you got an error_invalid_expression error message here,
121 // then the expression (Expr) is not a valid spirit karma expression.
122 // Did you intend to use the auto_ facilities while forgetting to
123 // #include <boost/spirit/include/karma_format_auto.hpp>?
124 BOOST_SPIRIT_ASSERT_MATCH(karma::domain, Expr);
127 template <typename Expr, typename Delimiter>
128 struct format_delimited<Expr, Delimiter
129 , typename enable_if<traits::matches<karma::domain, Expr> >::type>
131 typedef format_manip<Expr, mpl::false_, mpl::false_, Delimiter> type;
135 , Delimiter const& delimiter
136 , BOOST_SCOPED_ENUM(delimit_flag) pre_delimit)
138 // Report invalid expression error as early as possible.
139 // If you got an error_invalid_expression error message here,
140 // then the delimiter is not a valid spirit karma expression.
141 BOOST_SPIRIT_ASSERT_MATCH(karma::domain, Delimiter);
142 return type(expr, delimiter, pre_delimit, unused);
146 ///////////////////////////////////////////////////////////////////////////
147 template<typename Char, typename Traits, typename Expr
148 , typename CopyExpr, typename CopyAttr>
149 inline std::basic_ostream<Char, Traits> &
150 operator<< (std::basic_ostream<Char, Traits> &os
151 , format_manip<Expr, CopyExpr, CopyAttr> const& fm)
153 karma::ostream_iterator<Char, Char, Traits> sink(os);
154 if (!karma::generate (sink, fm.expr))
156 os.setstate(std::ios_base::failbit);
161 ///////////////////////////////////////////////////////////////////////////
162 template<typename Char, typename Traits, typename Expr
163 , typename CopyExpr, typename CopyAttr, typename Attribute>
164 inline std::basic_ostream<Char, Traits> &
165 operator<< (std::basic_ostream<Char, Traits> &os
166 , format_manip<Expr, CopyExpr, CopyAttr, unused_type, Attribute> const& fm)
168 karma::ostream_iterator<Char, Char, Traits> sink(os);
169 if (!karma::generate(sink, fm.expr, fm.attr))
171 os.setstate(std::ios_base::failbit);
176 template<typename Char, typename Traits, typename Expr
177 , typename CopyExpr, typename CopyAttr, typename Delimiter>
178 inline std::basic_ostream<Char, Traits> &
179 operator<< (std::basic_ostream<Char, Traits> &os
180 , format_manip<Expr, CopyExpr, CopyAttr, Delimiter> const& fm)
182 karma::ostream_iterator<Char, Char, Traits> sink(os);
183 if (!karma::generate_delimited(sink, fm.expr, fm.delim, fm.pre))
185 os.setstate(std::ios_base::failbit);
190 ///////////////////////////////////////////////////////////////////////////
191 template<typename Char, typename Traits, typename Expr
192 , typename CopyExpr, typename CopyAttr, typename Delimiter
193 , typename Attribute>
194 inline std::basic_ostream<Char, Traits> &
195 operator<< (std::basic_ostream<Char, Traits> &os
196 , format_manip<Expr, CopyExpr, CopyAttr, Delimiter, Attribute> const& fm)
198 karma::ostream_iterator<Char, Char, Traits> sink(os);
199 if (!karma::generate_delimited(sink, fm.expr, fm.delim, fm.pre, fm.attr))
201 os.setstate(std::ios_base::failbit);