manip.hpp
Go to the documentation of this file.
00001 /* 00002 Copyright 2005-2007 Adobe Systems Incorporated 00003 Distributed under the MIT License (see accompanying file LICENSE_1_0_0.txt 00004 or a copy at http://stlab.adobe.com/licenses.html) 00005 */ 00006 00007 /*************************************************************************************************/ 00008 00009 #ifdef ADOBE_STD_SERIALIZATION 00010 00011 /*************************************************************************************************/ 00012 00013 #ifndef ADOBE_MANIP_HPP 00014 #define ADOBE_MANIP_HPP 00015 00016 /*************************************************************************************************/ 00017 00018 #include <adobe/config.hpp> 00019 00020 #include <iostream> 00021 00022 /*************************************************************************************************/ 00023 00024 namespace adobe { 00025 00026 00027 /*************************************************************************************************/ 00028 00034 class manipulator_base 00035 { 00036 public: 00037 manipulator_base() : 00038 error_m(std::ios_base::goodbit) 00039 { } 00040 00041 protected: 00042 00043 template <typename StreamType> 00044 std::ios_base::iostate handle_error(StreamType& strm) const 00045 { 00046 std::ios_base::iostate err(error_m); 00047 00048 try { throw; } 00049 00050 catch (std::bad_alloc&) 00051 { 00052 set_bad(); 00053 00054 std::ios_base::iostate exception_mask(strm.exceptions()); 00055 00056 if (exception_mask & std::ios_base::failbit && !(exception_mask & std::ios_base::badbit)) 00057 strm.setstate(err); 00058 else if (exception_mask & std::ios_base::badbit) 00059 { 00060 try { strm.setstate(err); } 00061 catch (std::ios_base::failure&) { } 00062 throw; 00063 } 00064 } 00065 catch (...) 00066 { 00067 set_fail(); 00068 00069 std::ios_base::iostate exception_mask(strm.exceptions()); 00070 00071 if ((exception_mask & std::ios_base::badbit) && (err & std::ios_base::badbit)) 00072 strm.setstate(err); 00073 else if (exception_mask & std::ios_base::failbit) 00074 { 00075 try { strm.setstate(err); } 00076 catch (std::ios_base::failure&) { } 00077 throw; 00078 } 00079 } 00080 00081 return err; 00082 } 00083 00084 void set_fail() const { error_m |= std::ios_base::failbit; } 00085 void set_bad() const { error_m |= std::ios_base::badbit; } 00086 00087 mutable std::ios_base::iostate error_m; 00088 }; 00089 00090 /*************************************************************************************************/ 00091 00092 template <typename ArgumentType, class charT, class traits> 00093 class basic_omanipulator : public manipulator_base 00094 { 00095 public: 00096 typedef ArgumentType argument_type; 00097 typedef std::basic_ostream<charT, traits> stream_type; 00098 typedef stream_type& (*manip_func)(stream_type&, const ArgumentType&); 00099 00100 basic_omanipulator(manip_func pf, const argument_type& arg) : 00101 pf_m(pf), arg_m(arg) 00102 { } 00103 00104 void do_manip(stream_type& strm) const 00105 { 00106 if (error_m != std::ios_base::goodbit) 00107 strm.setstate(error_m); 00108 else 00109 { 00110 std::ios_base::iostate err(error_m); 00111 try 00112 { 00113 (*pf_m)(strm, arg_m); 00114 } 00115 catch (...) 00116 { 00117 err = handle_error(strm); 00118 } 00119 00120 if (err) strm.setstate(err); 00121 } 00122 } 00123 00124 private: 00125 manip_func pf_m; 00126 00127 protected: 00128 argument_type arg_m; 00129 }; 00130 00131 /*************************************************************************************************/ 00132 00133 template <typename ArgumentType1, typename ArgumentType2, class charT, class traits> 00134 class basic_omanipulator2 : public manipulator_base 00135 { 00136 public: 00137 typedef ArgumentType1 argument_type_1; 00138 typedef ArgumentType2 argument_type_2; 00139 typedef std::basic_ostream<charT, traits> stream_type; 00140 typedef stream_type& (*manip_func)(stream_type&, const ArgumentType1&, const ArgumentType2&); 00141 00142 basic_omanipulator2(manip_func pf, const ArgumentType1& arg1, const ArgumentType2& arg2) : 00143 pf_m(pf), arg1_m(arg1) , arg2_m(arg2) 00144 { } 00145 00146 void do_manip(stream_type& strm) const 00147 { 00148 if (error_m != std::ios_base::goodbit) 00149 strm.setstate(error_m); 00150 else 00151 { 00152 std::ios_base::iostate err(error_m); 00153 try 00154 { 00155 (*pf_m)(strm, arg1_m, arg2_m); 00156 } 00157 catch (...) 00158 { 00159 err = handle_error(strm); 00160 } 00161 00162 if (err) strm.setstate(err); 00163 } 00164 } 00165 00166 private: 00167 manip_func pf_m; 00168 00169 protected: 00170 argument_type_1 arg1_m; 00171 argument_type_2 arg2_m; 00172 }; 00173 00174 /*************************************************************************************************/ 00175 00176 template <class ArgumentType, class charT, class traits> 00177 std::basic_ostream<charT, traits>& operator << (std::basic_ostream<charT, traits>& os, 00178 const adobe::basic_omanipulator<ArgumentType, charT, traits>& manip) 00179 { 00180 if (os.good()) 00181 manip.do_manip(os); 00182 00183 return os; 00184 } 00185 00186 /*************************************************************************************************/ 00187 00188 template <class ArgumentType1, class ArgumentType2, class charT, class traits> 00189 std::basic_ostream<charT, traits>& operator << (std::basic_ostream<charT, traits>& os, 00190 const adobe::basic_omanipulator2<ArgumentType1, ArgumentType2, charT, traits>& manip) 00191 { 00192 if (os.good()) 00193 manip.do_manip(os); 00194 00195 return os; 00196 } 00197 00198 /*************************************************************************************************/ 00199 00200 template <class charT, class traits> 00201 class basic_bounded_width : public basic_omanipulator<unsigned int, charT, traits> 00202 { 00203 typedef basic_omanipulator<unsigned int, charT, traits> inherited_t; 00204 00205 public: 00206 typedef typename inherited_t::stream_type stream_type; 00207 typedef typename inherited_t::argument_type argument_type; 00208 00209 basic_bounded_width(argument_type min, argument_type max) : 00210 basic_omanipulator<argument_type, charT, traits>(basic_bounded_width::fct, min), 00211 min_m(min), max_m(max) 00212 { } 00213 00214 inherited_t& operator() (argument_type i) 00215 { 00216 inherited_t::arg_m = std::min(max_m, std::max(i, min_m)); 00217 return *this; 00218 } 00219 00220 private: 00221 static stream_type& fct(stream_type& strm, const argument_type& i) 00222 { 00223 strm.width(i); 00224 return strm; 00225 } 00226 00227 argument_type min_m; 00228 argument_type max_m; 00229 }; 00230 00231 typedef basic_bounded_width<char, std::char_traits<char> > bounded_width; 00232 typedef basic_bounded_width<wchar_t, std::char_traits<wchar_t> > wbounded_width; 00233 00235 00236 /*************************************************************************************************/ 00237 00238 } // namespace adobe 00239 00240 /*************************************************************************************************/ 00241 00242 #endif 00243 00244 /*************************************************************************************************/ 00245 00246 #endif 00247 00248 /*************************************************************************************************/ |