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 // silence MSVC warning C4512: assignment operator could not be generated 47 BOOST_DELETED_FUNCTION(format_manip& operator= (format_manip const&)) 48 }; 49 50 template <typename Expr, typename Delimiter, typename Attribute> 51 struct format_manip<Expr, mpl::false_, mpl::true_, Delimiter, Attribute> 52 { format_manipboost::spirit::karma::detail::format_manip53 format_manip(Expr const& xpr, Delimiter const& d, Attribute const& a) 54 : expr(xpr), delim(d), pre(delimit_flag::dont_predelimit), attr(a) {} 55 format_manipboost::spirit::karma::detail::format_manip56 format_manip(Expr const& xpr, Delimiter const& d 57 , BOOST_SCOPED_ENUM(delimit_flag) pre_delimit, Attribute const& a) 58 : expr(xpr), delim(d), pre(pre_delimit), attr(a) {} 59 60 Expr const& expr; 61 Delimiter const& delim; 62 BOOST_SCOPED_ENUM(delimit_flag) const pre; 63 Attribute attr; 64 65 // silence MSVC warning C4512: assignment operator could not be generated 66 BOOST_DELETED_FUNCTION(format_manip& operator= (format_manip const&)) 67 }; 68 69 template <typename Expr, typename Delimiter, typename Attribute> 70 struct format_manip<Expr, mpl::true_, mpl::false_, Delimiter, Attribute> 71 { format_manipboost::spirit::karma::detail::format_manip72 format_manip(Expr const& xpr, Delimiter const& d, Attribute const& a) 73 : expr(xpr), delim(d), pre(delimit_flag::dont_predelimit), attr(a) {} 74 format_manipboost::spirit::karma::detail::format_manip75 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 // silence MSVC warning C4512: assignment operator could not be generated 85 BOOST_DELETED_FUNCTION(format_manip& operator= (format_manip const&)) 86 }; 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 callboost::spirit::karma::detail::format106 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 callboost::spirit::karma::detail::format_delimited130 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> & operator <<(std::basic_ostream<Char,Traits> & os,format_manip<Expr,CopyExpr,CopyAttr> const & fm)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::ios_base::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> & operator <<(std::basic_ostream<Char,Traits> & os,format_manip<Expr,CopyExpr,CopyAttr,unused_type,Attribute> const & fm)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::ios_base::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> & operator <<(std::basic_ostream<Char,Traits> & os,format_manip<Expr,CopyExpr,CopyAttr,Delimiter> const & fm)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::ios_base::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> & operator <<(std::basic_ostream<Char,Traits> & os,format_manip<Expr,CopyExpr,CopyAttr,Delimiter,Attribute> const & fm)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::ios_base::failbit); 199 } 200 return os; 201 } 202 }}}} 203 204 #endif 205