dlvhex
2.5.0
|
00001 /* dlvhex -- Answer-Set Programming with external interfaces. 00002 * Copyright (C) 2005-2007 Roman Schindlauer 00003 * Copyright (C) 2006-2015 Thomas Krennwallner 00004 * Copyright (C) 2009-2016 Peter Schüller 00005 * Copyright (C) 2011-2016 Christoph Redl 00006 * Copyright (C) 2015-2016 Tobias Kaminski 00007 * Copyright (C) 2015-2016 Antonius Weinzierl 00008 * 00009 * This file is part of dlvhex. 00010 * 00011 * dlvhex is free software; you can redistribute it and/or modify it 00012 * under the terms of the GNU Lesser General Public License as 00013 * published by the Free Software Foundation; either version 2.1 of 00014 * the License, or (at your option) any later version. 00015 * 00016 * dlvhex is distributed in the hope that it will be useful, but 00017 * WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00019 * Lesser General Public License for more details. 00020 * 00021 * You should have received a copy of the GNU Lesser General Public 00022 * License along with dlvhex; if not, write to the Free Software 00023 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 00024 * 02110-1301 USA. 00025 */ 00026 00034 #ifndef PRINTHELPERS_HPP_INCLUDED__11122011 00035 #define PRINTHELPERS_HPP_INCLUDED__11122011 00036 00037 #include <boost/range/iterator_range.hpp> 00038 #include <boost/function.hpp> 00039 #include <boost/bind.hpp> 00040 #include <boost/optional.hpp> 00041 00042 #include <iostream> 00043 #include <sstream> 00044 #include <set> 00045 #include <vector> 00046 00054 template<typename T> 00055 class ostream_printable 00056 { 00061 friend std::ostream& operator<<(std::ostream& o, const T& t) 00062 { return t.print(o); } 00063 // to be defined in derived class: 00064 //std::ostream& print(std::ostream& o) const; 00065 }; 00066 00067 // if some class has a method "std::ostream& print(std::ostream&) const" 00068 // and you have an object o of this type 00069 // then you can do "std::cerr << ... << print_method(o) << ... " to print it 00070 00071 // if some other method is used to print T foo 00072 // e.g. std::ostream& BAR::printFOO(std::ostream& o, const FOO& p) const 00073 // then you can do 00074 // std::cerr << ... << print_function(boost::bind(&BAR::printFOO, &bar, _1, foo)) << ... 00075 // e.g. std::ostream& printFOO(std::ostream& o, const FOO& p) const 00076 // then you can do 00077 // std::cerr << ... << print_function(boost::bind(&printFoo, _1, foo)) << ... 00078 00079 // std::cerr << ... << printopt(boost::optional<T>) << ... 00080 // gives "unset" or prints T's contents 00081 00082 // std::cerr << ... << printptr(T* or boost::shared_ptr<T>) << ... 00083 // gives "null" or prints T* as a void* 00084 00085 // std::cerr << ... << printrange(Range r) << ... prints generic ranges enclosed in "<>" 00086 // std::cerr << ... << printvector(std::vector<T>) << ... prints generic vectors enclosed in "[]" 00087 // std::cerr << ... << printset(std::set<T>) << ... prints generic sets enclosed in "{}" 00088 00090 struct print_container 00091 { 00093 virtual ~print_container() {} 00097 virtual std::ostream& print(std::ostream& o) const = 0; 00098 }; 00099 00104 inline std::ostream& operator<<(std::ostream& o, print_container* c) 00105 { 00106 assert(c); 00107 std::ostream& ret = c->print(o); 00108 delete c; 00109 return ret; 00110 } 00111 00112 00114 template<typename T> 00115 struct print_stream_container: 00116 public print_container 00117 { 00119 T t; 00122 print_stream_container(const T& t): t(t) {} 00124 virtual ~print_stream_container() {} 00125 virtual std::ostream& print(std::ostream& o) const 00126 { return o << t; } 00127 }; 00128 00130 struct print_method_container: 00131 public print_container 00132 { 00133 typedef boost::function<std::ostream& (std::ostream&)> 00134 PrintFn; 00136 PrintFn fn; 00139 print_method_container(const PrintFn& fn): fn(fn) {} 00141 virtual ~print_method_container() {} 00142 virtual std::ostream& print(std::ostream& o) const 00143 { return fn(o); } 00144 }; 00145 00149 template<typename T> 00150 inline print_container* print_method(const T& t) 00151 { 00152 return new print_method_container( 00153 boost::bind(&T::print, &t, _1)); 00154 } 00155 00156 00164 inline print_container* print_function( 00165 const print_method_container::PrintFn& fn) 00166 { 00167 return new print_method_container(fn); 00168 } 00169 00170 00174 template<typename T> 00175 inline print_container* printopt(const boost::optional<T>& t) 00176 { 00177 if( !!t ) 00178 return new print_stream_container<const T&>(t.get()); 00179 else 00180 return new print_stream_container<const char*>("unset"); 00181 } 00182 00183 00187 template<typename T> 00188 inline print_container* printptr(const boost::shared_ptr<T>& t) 00189 { 00190 if( !!t ) 00191 return new print_stream_container<const void*>( 00192 reinterpret_cast<const void*>(t.get())); 00193 else 00194 return new print_stream_container<const char*>("null"); 00195 } 00196 00197 00201 template<typename T> 00202 inline print_container* printptr(const boost::shared_ptr<const T>& t) 00203 { 00204 if( t != 0 ) 00205 return new print_stream_container<const void*>( 00206 reinterpret_cast<const void*>(t.get())); 00207 else 00208 return new print_stream_container<const char*>("null"); 00209 } 00210 00211 00215 template<typename T> 00216 inline print_container* printptr(const T* const t) 00217 { 00218 if( t != 0 ) 00219 return new print_stream_container<const void*>( 00220 reinterpret_cast<const void* const>(t)); 00221 else 00222 return new print_stream_container<const char*>("null"); 00223 } 00224 00225 00236 template<typename Range> 00237 inline print_container* printrange(Range r, 00238 const char* open="<", const char* sep=",", const char* close=">") 00239 { 00240 std::ostringstream o; 00241 o << open; 00242 typename Range::const_iterator it = boost::begin(r); 00243 typename Range::const_iterator itend = boost::end(r); 00244 if( it != itend ) { 00245 o << *it; 00246 it++; 00247 } 00248 for(; it != itend; ++it) 00249 o << sep << *it; 00250 o << close; 00251 return new print_stream_container<std::string>(o.str()); 00252 } 00253 00254 00265 template<typename T> 00266 inline print_container* printset(const std::set<T>& t, 00267 const char* open="{", const char* sep=",", const char* close="}") 00268 { 00269 return printrange(t, open, sep, close); 00270 } 00271 00272 00283 template<typename T> 00284 inline print_container* printvector(const std::vector<T>& t, 00285 const char* open="[", const char* sep=",", const char* close="]") 00286 { 00287 return printrange(t, open, sep, close); 00288 } 00289 #endif // PRINTHELPERS_HPP_INCLUDED__11122011 00290 00291 // vim:expandtab:ts=4:sw=4: 00292 // mode: C++ 00293 // End: