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_SPIRIT_KARMA_FORMAT_MANIP_MAY_03_2007_1424PM)
7#define BOOST_SPIRIT_KARMA_FORMAT_MANIP_MAY_03_2007_1424PM
8
9#if defined(_MSC_VER)
10#pragma once
11#endif
12
13#include <iosfwd>
14#include <iterator>
15#include <string>
16#include <boost/spirit/home/karma/generate.hpp>
17#include <boost/spirit/home/support/iterators/ostream_iterator.hpp>
18#include <boost/core/scoped_enum.hpp>
19#include <boost/mpl/bool.hpp>
20
21///////////////////////////////////////////////////////////////////////////////
22namespace boost { namespace spirit { namespace karma { namespace detail
23{
24 ///////////////////////////////////////////////////////////////////////////
25#ifdef _MSC_VER
26# pragma warning(push)
27# pragma warning(disable: 4512) // assignment operator could not be generated.
28#endif
29 template <typename Expr
30 , typename CopyExpr = mpl::false_, typename CopyAttr = mpl::false_
31 , typename Delimiter = unused_type, typename Attribute = unused_type>
32 struct format_manip
33 {
34 // This assertion makes sure we don't hit the only code path which is
35 // not implemented (because it isn't needed), where both, the
36 // expression and the attribute need to be held as a copy.
37 BOOST_SPIRIT_ASSERT_MSG(!CopyExpr::value || !CopyAttr::value
38 , error_invalid_should_not_happen, ());
39
40 format_manip(Expr const& xpr, Delimiter const& d, Attribute const& a)
41 : expr(xpr), delim(d), pre(delimit_flag::dont_predelimit), attr(a) {}
42
43 format_manip(Expr const& xpr, Delimiter const& d
44 , BOOST_SCOPED_ENUM(delimit_flag) pre_delimit, Attribute const& a)
45 : expr(xpr), delim(d), pre(pre_delimit), attr(a) {}
46
47 Expr const& expr;
48 Delimiter const& delim;
49 BOOST_SCOPED_ENUM(delimit_flag) const pre;
50 Attribute const& attr;
51 };
52
53 template <typename Expr, typename Delimiter, typename Attribute>
54 struct format_manip<Expr, mpl::false_, mpl::true_, Delimiter, Attribute>
55 {
56 format_manip(Expr const& xpr, Delimiter const& d, Attribute const& a)
57 : expr(xpr), delim(d), pre(delimit_flag::dont_predelimit), attr(a) {}
58
59 format_manip(Expr const& xpr, Delimiter const& d
60 , BOOST_SCOPED_ENUM(delimit_flag) pre_delimit, Attribute const& a)
61 : expr(xpr), delim(d), pre(pre_delimit), attr(a) {}
62
63 Expr const& expr;
64 Delimiter const& delim;
65 BOOST_SCOPED_ENUM(delimit_flag) const pre;
66 Attribute attr;
67 };
68
69 template <typename Expr, typename Delimiter, typename Attribute>
70 struct format_manip<Expr, mpl::true_, mpl::false_, Delimiter, Attribute>
71 {
72 format_manip(Expr const& xpr, Delimiter const& d, Attribute const& a)
73 : expr(xpr), delim(d), pre(delimit_flag::dont_predelimit), attr(a) {}
74
75 format_manip(Expr const& xpr, Delimiter const& d
76 , BOOST_SCOPED_ENUM(delimit_flag) pre_delimit, Attribute const& a)
77 : expr(xpr), delim(d), pre(pre_delimit), attr(a) {}
78
79 Expr expr;
80 Delimiter const& delim;
81 BOOST_SCOPED_ENUM(delimit_flag) const pre;
82 Attribute const& attr;
83 };
84#ifdef _MSC_VER
85# pragma warning(pop)
86#endif
87
88 ///////////////////////////////////////////////////////////////////////////
89 template <typename Expr, typename Enable = void>
90 struct format
91 {
92 // Report invalid expression error as early as possible.
93 // If you got an error_invalid_expression error message here,
94 // then the expression (Expr) is not a valid spirit karma expression.
95 // Did you intend to use the auto_ facilities while forgetting to
96 // #include <boost/spirit/include/karma_format_auto.hpp>?
97 BOOST_SPIRIT_ASSERT_MATCH(karma::domain, Expr);
98 };
99
100 template <typename Expr>
101 struct format<Expr
102 , typename enable_if<traits::matches<karma::domain, Expr> >::type>
103 {
104 typedef format_manip<Expr> type;
105
106 static type call(Expr const& expr)
107 {
108 return type(expr, unused, unused);
109 }
110 };
111
112 ///////////////////////////////////////////////////////////////////////////
113 template <typename Expr, typename Delimiter, typename Enable = void>
114 struct format_delimited
115 {
116 // Report invalid expression error as early as possible.
117 // If you got an error_invalid_expression error message here,
118 // then the expression (Expr) is not a valid spirit karma expression.
119 // Did you intend to use the auto_ facilities while forgetting to
120 // #include <boost/spirit/include/karma_format_auto.hpp>?
121 BOOST_SPIRIT_ASSERT_MATCH(karma::domain, Expr);
122 };
123
124 template <typename Expr, typename Delimiter>
125 struct format_delimited<Expr, Delimiter
126 , typename enable_if<traits::matches<karma::domain, Expr> >::type>
127 {
128 typedef format_manip<Expr, mpl::false_, mpl::false_, Delimiter> type;
129
130 static type call(
131 Expr const& expr
132 , Delimiter const& delimiter
133 , BOOST_SCOPED_ENUM(delimit_flag) pre_delimit)
134 {
135 // Report invalid expression error as early as possible.
136 // If you got an error_invalid_expression error message here,
137 // then the delimiter is not a valid spirit karma expression.
138 BOOST_SPIRIT_ASSERT_MATCH(karma::domain, Delimiter);
139 return type(expr, delimiter, pre_delimit, unused);
140 }
141 };
142
143 ///////////////////////////////////////////////////////////////////////////
144 template<typename Char, typename Traits, typename Expr
145 , typename CopyExpr, typename CopyAttr>
146 inline std::basic_ostream<Char, Traits> &
147 operator<< (std::basic_ostream<Char, Traits> &os
148 , format_manip<Expr, CopyExpr, CopyAttr> const& fm)
149 {
150 karma::ostream_iterator<Char, Char, Traits> sink(os);
151 if (!karma::generate (sink, fm.expr))
152 {
153 os.setstate(std::basic_ostream<Char, Traits>::failbit);
154 }
155 return os;
156 }
157
158 ///////////////////////////////////////////////////////////////////////////
159 template<typename Char, typename Traits, typename Expr
160 , typename CopyExpr, typename CopyAttr, typename Attribute>
161 inline std::basic_ostream<Char, Traits> &
162 operator<< (std::basic_ostream<Char, Traits> &os
163 , format_manip<Expr, CopyExpr, CopyAttr, unused_type, Attribute> const& fm)
164 {
165 karma::ostream_iterator<Char, Char, Traits> sink(os);
166 if (!karma::generate(sink, fm.expr, fm.attr))
167 {
168 os.setstate(std::basic_ostream<Char, Traits>::failbit);
169 }
170 return os;
171 }
172
173 template<typename Char, typename Traits, typename Expr
174 , typename CopyExpr, typename CopyAttr, typename Delimiter>
175 inline std::basic_ostream<Char, Traits> &
176 operator<< (std::basic_ostream<Char, Traits> &os
177 , format_manip<Expr, CopyExpr, CopyAttr, Delimiter> const& fm)
178 {
179 karma::ostream_iterator<Char, Char, Traits> sink(os);
180 if (!karma::generate_delimited(sink, fm.expr, fm.delim, fm.pre))
181 {
182 os.setstate(std::basic_ostream<Char, Traits>::failbit);
183 }
184 return os;
185 }
186
187 ///////////////////////////////////////////////////////////////////////////
188 template<typename Char, typename Traits, typename Expr
189 , typename CopyExpr, typename CopyAttr, typename Delimiter
190 , typename Attribute>
191 inline std::basic_ostream<Char, Traits> &
192 operator<< (std::basic_ostream<Char, Traits> &os
193 , format_manip<Expr, CopyExpr, CopyAttr, Delimiter, Attribute> const& fm)
194 {
195 karma::ostream_iterator<Char, Char, Traits> sink(os);
196 if (!karma::generate_delimited(sink, fm.expr, fm.delim, fm.pre, fm.attr))
197 {
198 os.setstate(std::basic_ostream<Char, Traits>::failbit);
199 }
200 return os;
201 }
202}}}}
203
204#endif
205

source code of boost/libs/spirit/include/boost/spirit/home/karma/stream/detail/format_manip.hpp