stlab.adobe.com Adobe Systems Incorporated

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 /*************************************************************************************************/

Copyright © 2006-2007 Adobe Systems Incorporated.

Use of this website signifies your agreement to the Terms of Use and Online Privacy Policy.

Search powered by Google