00001 #ifndef TAG_STDPP_H
00002 #define TAG_STDPP_H
00003
00004 #include <iostream>
00005 #include <utility>
00006
00007 namespace tag {
00008
00011
00038 #ifndef DOXYGEN_IGNORE_INTERNAL
00039
00040 template <class T> struct NotFirst {
00041 inline NotFirst(T & d) : data(d) {};
00042 T & data;
00043 };
00044
00045 template <class T, class Char, class Traits>
00046 inline NotFirst<std::basic_ostream<Char,Traits> > operator,(std::basic_ostream<Char,Traits> & stream, const T & data ){
00047 stream << data;
00048 return NotFirst<std::basic_ostream<Char,Traits> >(stream);
00049 }
00050
00051 template <class T, class Char, class Traits>
00052 inline NotFirst<std::basic_ostream<Char,Traits> > operator,(NotFirst<std::basic_ostream<Char,Traits> > nf, const T & data ){
00053 nf.data << nf.data.fill() << data;
00054 return nf;
00055 }
00056
00057 template <class Char, class Traits>
00058 inline std::basic_ostream<Char,Traits> & operator,(NotFirst<std::basic_ostream<Char,Traits> > nf, std::basic_ostream<Char,Traits> & (*modifier)(std::basic_ostream<Char,Traits> &)){
00059 nf.data << modifier;
00060 return nf.data;
00061 }
00062
00063 namespace Internal
00064 {
00065
00066 struct add_fill_s{};
00067 struct like_print_s{};
00068 struct no_space_s{};
00069
00070 template<class S> struct add_fill_bound
00071 {
00072 add_fill_bound(S& os)
00073 :o(os),first(1) {}
00074
00075
00076 template<class C> add_fill_bound& operator<<(const C& c)
00077 {
00078 if(first == true)
00079 first=false;
00080 else
00081 o << o.fill();
00082
00083 o << c;
00084 return *this;
00085 }
00086
00087 add_fill_bound& operator<<(const no_space_s&)
00088 {
00089 first=true;
00090 return *this;
00091 }
00092
00093 add_fill_bound& operator<<(S& (*fptr)(S&) )
00094 {
00095 o << fptr;
00096
00097 if(fptr == static_cast<S&(*)(S&)>(std::endl))
00098 first=true;
00099
00100 return *this;
00101 }
00102
00103 private:
00104 S& o;
00105 bool first;
00106 };
00107
00108
00109 template<class S> struct like_print_bound:public add_fill_bound<S>
00110 {
00111 like_print_bound(S&os)
00112 :add_fill_bound<S>(os)
00113 {
00114 }
00115
00116 ~like_print_bound()
00117 {
00118 add_fill_bound<S>::operator<<(std::endl);
00119 }
00120 };
00121
00122 }
00123
00124 #endif
00125
00139 static struct Internal::add_fill_s add_fill;
00140
00154 static struct Internal::like_print_s print;
00155
00168 static struct Internal::no_space_s no_space;
00169
00170 #ifndef DOXYGEN_IGNORE_INTERNAL
00171
00172 template<class Char, class Traits> Internal::add_fill_bound<std::basic_ostream<Char,Traits> > operator<<(std::basic_ostream<Char,Traits>& o, const Internal::add_fill_s&)
00173 {
00174 return Internal::add_fill_bound<std::basic_ostream<Char,Traits> >(o);
00175 }
00176
00177 template<class Char, class Traits> Internal::like_print_bound<std::basic_ostream<Char,Traits> > operator<<(std::basic_ostream<Char,Traits>& o, const Internal::like_print_s&)
00178 {
00179 return Internal::like_print_bound<std::basic_ostream<Char,Traits> >(o);
00180 }
00181
00182 #endif
00183
00184 #ifndef DOXYGEN_IGNORE_INTERNAL
00185 namespace Internal
00186 {
00187 template<class A, class B> struct refpair
00188 {
00189 A& a;
00190 B& b;
00191 refpair(A& aa, B& bb)
00192 :a(aa),b(bb)
00193 {}
00194
00195 void operator=(const std::pair<A,B>& p)
00196 {
00197 a=p.first;
00198 b=p.second;
00199 }
00200 };
00201 }
00202
00203 #endif
00204
00216 template<class A, class B> Internal::refpair<A,B> rpair(A&aa, B&bb)
00217 {
00218 return Internal::refpair<A,B>(aa, bb);
00219 }
00220
00221
00222
00223 }
00224
00225 #endif // __PRINT_H_