summaryrefslogtreecommitdiff
path: root/utils/writer.h
diff options
context:
space:
mode:
Diffstat (limited to 'utils/writer.h')
-rw-r--r--utils/writer.h155
1 files changed, 155 insertions, 0 deletions
diff --git a/utils/writer.h b/utils/writer.h
new file mode 100644
index 00000000..d21b74d6
--- /dev/null
+++ b/utils/writer.h
@@ -0,0 +1,155 @@
+#ifndef WRITER_H
+#define WRITER_H
+
+#include <iostream>
+
+struct Writer
+{
+ template <class Ch, class Tr,class value_type>
+ std::basic_ostream<Ch,Tr>&
+ operator()(std::basic_ostream<Ch,Tr>& o,const value_type &l) const {
+ return o << l;
+ }
+};
+
+struct LineWriter
+{
+ template <class Ch, class Tr,class Label>
+ std::basic_ostream<Ch,Tr>&
+ operator()(std::basic_ostream<Ch,Tr>& o,const Label &l) const {
+ return o << l << std::endl;
+ }
+};
+
+template <class O, class T,class W> inline
+std::ios_base::iostate write_range_iostate(O& o,T begin, T end,W writer,bool multiline=false,bool parens=true,char open_paren='(',char close_paren=')',char space=' ')
+{
+ static const char *const MULTILINE_SEP="\n";
+ if (parens) {
+ o << open_paren;
+ if (multiline)
+ o << MULTILINE_SEP;
+ }
+ if (multiline) {
+ for (;begin!=end;++begin) {
+ o << space;
+ writer(o,*begin);
+ o << MULTILINE_SEP;
+ }
+ } else {
+ for (T i=begin;i!=end;++i) {
+ if (i!=begin) o<<space;
+ writer(o,*i);
+ }
+ }
+ if (parens) {
+ o << close_paren;
+ if (multiline)
+ o << MULTILINE_SEP;
+ }
+ return std::ios_base::goodbit;
+}
+
+
+template <class Ib,class Ie,class W=Writer>
+struct range_formatter {
+ Ib i;
+ Ie e;
+ W w;
+ bool multiline;
+ bool parens;
+ range_formatter(Ib i,Ie e,W w=W(),bool multiline=false,bool parens=true) :
+ i(i),e(e),w(w),multiline(multiline),parens(parens) {}
+
+ template <class Ch, class Tr>
+ std::basic_ostream<Ch,Tr> &
+ operator()(std::basic_ostream<Ch,Tr> &o) const {
+ write_range_iostate(o,i,e,w,multiline,parens);
+ return o;
+ }
+
+ template <class Ch, class Tr>
+ friend inline
+ std::basic_ostream<Ch,Tr> &
+ operator<<(std::basic_ostream<Ch,Tr> &o,range_formatter<Ib,Ie,W> const& w) {
+ return w(o);
+ }
+};
+
+template <class Ib,class Ie,class W>
+range_formatter<Ib,Ie,W>
+wrange(Ib i,Ie e,W const& w,bool multiline=false,bool parens=true)
+{
+ return range_formatter<Ib,Ie,W>(i,e,w,multiline,parens);
+}
+
+template <class Ib,class Ie>
+range_formatter<Ib,Ie>
+prange(Ib i,Ie e,bool multiline=false,bool parens=true)
+{
+ return range_formatter<Ib,Ie,Writer>(i,e,Writer(),multiline,parens);
+}
+
+
+template <class Ch, class Tr, class T,class W> inline
+std::basic_ostream<Ch,Tr> & write_range(std::basic_ostream<Ch,Tr>& o,T begin, T end,W writer,bool multiline=false,bool parens=true,char open_paren='(',char close_paren=')')
+{
+ write_range_iostate(o,begin,end,writer,multiline,parens,open_paren,close_paren);
+ return o;
+}
+
+template <class O, class T>
+inline std::ios_base::iostate print_range(O& o,T begin,T end,bool multiline=false,bool parens=true,char open_paren='(',char close_paren=')') {
+ return write_range_iostate(o,begin,end,Writer(),multiline,parens,open_paren,close_paren);
+}
+
+template <class O, class C>
+inline std::ios_base::iostate print_range_i(O& o,C const&c,unsigned from,unsigned to,bool multiline=false,bool parens=true,char open_paren='(',char close_paren=')') {
+ return write_range_iostate(o,c.begin()+from,c.begin()+to,Writer(),multiline,parens,open_paren,close_paren);
+}
+
+
+template <class O>
+struct bound_printer
+{
+ O *po;
+ template <class T>
+ void operator()(T const& t) const
+ {
+ *po << t;
+ }
+};
+
+template <class O>
+bound_printer<O>
+make_bound_printer(O &o)
+{
+ bound_printer<O> ret;
+ ret.po=&o;
+ return ret;
+}
+
+template <class W>
+struct bound_writer
+{
+ W const& w;
+ bound_writer(W const& w) : w(w) {}
+ bound_writer(bound_writer const& o) :w(o.w) {}
+ template <class O,class V>
+ void operator()(O &o,V const& v) const
+ {
+ v.print(o,w);
+ }
+};
+
+
+template <class W>
+bound_writer<W>
+make_bound_writer(W const& w)
+{
+ return bound_writer<W>(w);
+}
+
+
+
+#endif