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 <iterator> 14 #include <string> 15 #include <boost/spirit/home/karma/generate.hpp> 16 #include <boost/spirit/home/support/iterators/ostream_iterator.hpp> 17 #include <boost/mpl/bool.hpp> 18 19 /////////////////////////////////////////////////////////////////////////////// 20 namespace boost { namespace spirit { namespace karma { namespace detail 21 { 22 /////////////////////////////////////////////////////////////////////////// 23 template <typename Expr 24 , typename CopyExpr = mpl::false_, typename CopyAttr = mpl::false_ 25 , typename Delimiter = unused_type, typename Attribute = unused_type> 26 struct format_manip 27 { 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, ()); 33 format_manipboost::spirit::karma::detail::format_manip34 format_manip(Expr const& xpr, Delimiter const& d, Attribute const& a) 35 : expr(xpr), delim(d), pre(delimit_flag::dont_predelimit), attr(a) {} 36 format_manipboost::spirit::karma::detail::format_manip37 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) {} 40 41 Expr const& expr; 42 Delimiter const& delim; 43 BOOST_SCOPED_ENUM(delimit_flag) const pre; 44 Attribute const& attr; 45 46 private: 47 // silence MSVC warning C4512: assignment operator could not be generated 48 format_manip& operator= (format_manip const&); 49 }; 50 51 template <typename Expr, typename Delimiter, typename Attribute> 52 struct format_manip<Expr, mpl::false_, mpl::true_, Delimiter, Attribute> 53 { format_manipboost::spirit::karma::detail::format_manip54 format_manip(Expr const& xpr, Delimiter const& d, Attribute const& a) 55 : expr(xpr), delim(d), pre(delimit_flag::dont_predelimit), attr(a) {} 56 format_manipboost::spirit::karma::detail::format_manip57 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) {} 60 61 Expr const& expr; 62 Delimiter const& delim; 63 BOOST_SCOPED_ENUM(delimit_flag) const pre; 64 Attribute attr; 65 66 private: 67 // silence MSVC warning C4512: assignment operator could not be generated 68 format_manip& operator= (format_manip const&); 69 }; 70 71 template <typename Expr, typename Delimiter, typename Attribute> 72 struct format_manip<Expr, mpl::true_, mpl::false_, Delimiter, Attribute> 73 { format_manipboost::spirit::karma::detail::format_manip74 format_manip(Expr const& xpr, Delimiter const& d, Attribute const& a) 75 : expr(xpr), delim(d), pre(delimit_flag::dont_predelimit), attr(a) {} 76 format_manipboost::spirit::karma::detail::format_manip77 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) {} 80 81 Expr expr; 82 Delimiter const& delim; 83 BOOST_SCOPED_ENUM(delimit_flag) const pre; 84 Attribute const& attr; 85 86 private: 87 // silence MSVC warning C4512: assignment operator could not be generated 88 format_manip& operator= (format_manip const&); 89 }; 90 91 /////////////////////////////////////////////////////////////////////////// 92 template <typename Expr, typename Enable = void> 93 struct format 94 { 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); 101 }; 102 103 template <typename Expr> 104 struct format<Expr 105 , typename enable_if<traits::matches<karma::domain, Expr> >::type> 106 { 107 typedef format_manip<Expr> type; 108 callboost::spirit::karma::detail::format109 static type call(Expr const& expr) 110 { 111 return type(expr, unused, unused); 112 } 113 }; 114 115 /////////////////////////////////////////////////////////////////////////// 116 template <typename Expr, typename Delimiter, typename Enable = void> 117 struct format_delimited 118 { 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); 125 }; 126 127 template <typename Expr, typename Delimiter> 128 struct format_delimited<Expr, Delimiter 129 , typename enable_if<traits::matches<karma::domain, Expr> >::type> 130 { 131 typedef format_manip<Expr, mpl::false_, mpl::false_, Delimiter> type; 132 callboost::spirit::karma::detail::format_delimited133 static type call( 134 Expr const& expr 135 , Delimiter const& delimiter 136 , BOOST_SCOPED_ENUM(delimit_flag) pre_delimit) 137 { 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); 143 } 144 }; 145 146 /////////////////////////////////////////////////////////////////////////// 147 template<typename Char, typename Traits, typename Expr 148 , typename CopyExpr, typename CopyAttr> 149 inline std::basic_ostream<Char, Traits> & operator <<(std::basic_ostream<Char,Traits> & os,format_manip<Expr,CopyExpr,CopyAttr> const & fm)150 operator<< (std::basic_ostream<Char, Traits> &os 151 , format_manip<Expr, CopyExpr, CopyAttr> const& fm) 152 { 153 karma::ostream_iterator<Char, Char, Traits> sink(os); 154 if (!karma::generate (sink, fm.expr)) 155 { 156 os.setstate(std::ios_base::failbit); 157 } 158 return os; 159 } 160 161 /////////////////////////////////////////////////////////////////////////// 162 template<typename Char, typename Traits, typename Expr 163 , typename CopyExpr, typename CopyAttr, typename Attribute> 164 inline std::basic_ostream<Char, Traits> & operator <<(std::basic_ostream<Char,Traits> & os,format_manip<Expr,CopyExpr,CopyAttr,unused_type,Attribute> const & fm)165 operator<< (std::basic_ostream<Char, Traits> &os 166 , format_manip<Expr, CopyExpr, CopyAttr, unused_type, Attribute> const& fm) 167 { 168 karma::ostream_iterator<Char, Char, Traits> sink(os); 169 if (!karma::generate(sink, fm.expr, fm.attr)) 170 { 171 os.setstate(std::ios_base::failbit); 172 } 173 return os; 174 } 175 176 template<typename Char, typename Traits, typename Expr 177 , typename CopyExpr, typename CopyAttr, typename Delimiter> 178 inline std::basic_ostream<Char, Traits> & operator <<(std::basic_ostream<Char,Traits> & os,format_manip<Expr,CopyExpr,CopyAttr,Delimiter> const & fm)179 operator<< (std::basic_ostream<Char, Traits> &os 180 , format_manip<Expr, CopyExpr, CopyAttr, Delimiter> const& fm) 181 { 182 karma::ostream_iterator<Char, Char, Traits> sink(os); 183 if (!karma::generate_delimited(sink, fm.expr, fm.delim, fm.pre)) 184 { 185 os.setstate(std::ios_base::failbit); 186 } 187 return os; 188 } 189 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> & operator <<(std::basic_ostream<Char,Traits> & os,format_manip<Expr,CopyExpr,CopyAttr,Delimiter,Attribute> const & fm)195 operator<< (std::basic_ostream<Char, Traits> &os 196 , format_manip<Expr, CopyExpr, CopyAttr, Delimiter, Attribute> const& fm) 197 { 198 karma::ostream_iterator<Char, Char, Traits> sink(os); 199 if (!karma::generate_delimited(sink, fm.expr, fm.delim, fm.pre, fm.attr)) 200 { 201 os.setstate(std::ios_base::failbit); 202 } 203 return os; 204 } 205 }}}} 206 207 #endif 208