$search
00001 00008 /***************************************************************************** 00009 ** Ifdefs 00010 *****************************************************************************/ 00011 00012 #ifndef ECL_FORMATTERS_STRINGS_HPP_ 00013 #define ECL_FORMATTERS_STRINGS_HPP_ 00014 00015 /***************************************************************************** 00016 ** Includes 00017 *****************************************************************************/ 00018 00019 #include <string> 00020 #include <ecl/exceptions/standard_exception.hpp> 00021 #include "common.hpp" 00022 00023 /***************************************************************************** 00024 ** Namespaces 00025 *****************************************************************************/ 00026 00027 namespace ecl { 00028 00029 /***************************************************************************** 00030 ** Format Interface [String types] 00031 *****************************************************************************/ 00032 00040 template <> 00041 class Format<std::string> { 00042 public: 00043 /****************************************** 00044 ** C&D's 00045 *******************************************/ 00051 Format(int w = -1, Alignment a = NoAlign) : width_(w),alignment_(a) {} 00052 virtual ~Format() {} 00053 00054 /****************************************** 00055 ** Set 00056 *******************************************/ 00061 Format<std::string>& width(int w) { width_ = w; return *this; } 00067 Format<std::string>& align(Alignment a) { alignment_ = a; return *this; } 00068 00069 /****************************************** 00070 * Set Format Combinations 00071 ******************************************/ 00078 Format<std::string>& operator ()(int w, Alignment a); 00079 00080 /****************************************** 00081 ** Format a value 00082 *******************************************/ 00088 Format<std::string>& operator() (const std::string &input_string); 00089 00090 /****************************************** 00091 ** Common format usages 00092 *******************************************/ 00099 Format<std::string>& operator() (const std::string &input_string, int w); 00108 Format<std::string>& operator() (const std::string &input_string, int w, Alignment a); 00109 00110 /****************************************** 00111 ** Insert the formatter into a stream 00112 *******************************************/ 00125 template <typename OutputStream> friend OutputStream& operator << (OutputStream& ostream, Format<std::string>& formatter) ecl_assert_throw_decl(StandardException); 00126 00127 private: 00128 /****************************************** 00129 ** Parameters 00130 *******************************************/ 00131 int width_; 00132 Alignment alignment_; 00133 bool ready_to_format; 00134 std::string s; 00135 00136 /****************************************** 00137 ** Padding 00138 *******************************************/ 00144 template <typename OutputStream> void pad(int n, OutputStream &ostream) const; 00150 template <typename OutputStream> void prePad(int n, OutputStream &ostream) const; 00156 template <typename OutputStream> void postPad(int n, OutputStream &ostream) const; 00157 00158 /****************************************** 00159 ** Formatter Functions 00160 *******************************************/ 00165 template <typename OutputStream> void format(OutputStream &ostream) const; 00166 }; 00167 00168 /***************************************************************************** 00169 ** Implementation [Format<string>][Templates] 00170 *****************************************************************************/ 00171 00172 template <typename OutputStream> 00173 void Format<std::string>::format(OutputStream &ostream) const 00174 { 00175 int size = s.size(); 00176 00177 prePad(width_ - (size),ostream); // previously had (size+2) here...why? 00178 ostream << s; 00179 postPad(width_ - (size),ostream); 00180 } 00181 00182 template <typename OutputStream> 00183 void Format<std::string>::prePad(int n, OutputStream &ostream) const 00184 { 00185 if ( n <= 0 ) { return; } 00186 switch ( alignment_ ) 00187 { 00188 case ( NoAlign ) : { break; } 00189 case ( LeftAlign ) : { break; } 00190 case ( RightAlign ) : { pad(n,ostream); break; } 00191 case ( CentreAlign ) : { pad(n/2+ n%2,ostream); break; } // Add the remainder 00192 default : break; 00193 } 00194 } 00195 template <typename OutputStream> 00196 void Format<std::string>::postPad(int n, OutputStream &ostream) const 00197 { 00198 if ( n <= 0 ) { return; } 00199 switch ( alignment_ ) 00200 { 00201 case ( NoAlign ) : { break; } 00202 case ( LeftAlign ) : { pad(n,ostream); break; } 00203 case ( RightAlign ) : { break; } 00204 case ( CentreAlign ) : { pad(n/2,ostream); break; } // Do not add the remainder 00205 default : break; 00206 } 00207 } 00208 template <typename OutputStream> 00209 void Format<std::string>::pad(int n, OutputStream &ostream) const 00210 { 00211 for (int i = n; i > 0; --i ) 00212 { 00213 ostream << ' '; 00214 } 00215 } 00216 00217 /***************************************************************************** 00218 * Implementation [streaming] 00219 *****************************************************************************/ 00220 00221 template <typename OutputStream> 00222 OutputStream& operator << (OutputStream &ostream, Format<std::string>& formatter ) ecl_assert_throw_decl(StandardException) 00223 { 00224 bool ready = formatter.ready_to_format; 00225 00226 ecl_assert_throw(ready, StandardException(LOC,UsageError,"The formatter cannot print any data - " 00227 "either there is no data available, or you have tried to use the " 00228 "formatter more than once in a single streaming operation. " 00229 "C++ produces unspecified results when functors are used multiply " 00230 "in the same stream sequence, so this is not permitted here.") ); 00231 00232 if ( ready ) { 00233 formatter.format(ostream); 00234 formatter.ready_to_format = false; 00235 } 00236 00237 return ostream; 00238 } 00239 00240 }; // namespace ecl 00241 00242 #endif /*ECL_FORMATTERS_STRINGS_HPP_*/