1 /* 2 This file is part of MADNESS. 3 4 Copyright (C) 2007,2010 Oak Ridge National Laboratory 5 6 This program is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 2 of the License, or 9 (at your option) any later version. 10 11 This program is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with this program; if not, write to the Free Software 18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 20 For more information please contact: 21 22 Robert J. Harrison 23 Oak Ridge National Laboratory 24 One Bethel Valley Road 25 P.O. Box 2008, MS-6367 26 27 email: harrisonrj@ornl.gov 28 tel: 865-241-3937 29 fax: 865-572-0680 30 */ 31 32 #ifndef MADNESS_WORLD_PRINT_H__INCLUDED 33 #define MADNESS_WORLD_PRINT_H__INCLUDED 34 35 /** 36 \file print.h 37 \brief Defines simple templates for printing to \c std::cout "a la Python". 38 \ingroup libraries 39 */ 40 41 #include <type_traits> 42 #include <iostream> 43 #include <complex> 44 #include <list> 45 #include <vector> 46 #include <madness/world/worldmutex.h> 47 48 #ifdef BRAINDEAD 49 // Cray XT nonsense 50 #define ENDL "\n" 51 52 #else 53 54 #define ENDL std::endl 55 56 #endif 57 58 59 namespace madness { 60 61 /// \addtogroup libraries 62 /// @{ 63 64 /// Easy printing of complex numbers. 65 66 /// \tparam T The "real" type of the complex number. 67 /// \param[in,out] s The output stream. 68 /// \param[in] c The complex number. 69 /// \return The output stream (for chaining). 70 template <typename T> 71 std::ostream& operator<<(std::ostream& s, const std::complex<T>& c) { 72 s << c.real() << "+" << c.imag() << "j"; 73 return s; 74 } 75 76 /// Easy printing of pairs. 77 78 /// \tparam T Type 1 of the pair. 79 /// \tparam U Type 2 of the pair. 80 /// \param[in,out] s The output stream. 81 /// \param[in] p The pair. 82 /// \return The output stream (for chaining). 83 template <typename T, typename U> 84 std::ostream& operator<<(std::ostream& s, const std::pair<T,U>& p) { 85 s << "(" << p.first << "," << p.second << ")"; 86 return s; 87 } 88 89 /// Easy printing of lists. 90 91 /// \tparam T Type stored in the list. 92 /// \param[in,out] s The output stream. 93 /// \param[in] c The list. 94 /// \return The output stream (for chaining). 95 template <typename T> 96 std::ostream& operator<<(std::ostream& s, const std::list<T>& c) { 97 s << "["; 98 typename std::list<T>::const_iterator it = c.begin(); 99 while (it != c.end()) { 100 s << *it; 101 ++it; 102 if (it != c.end()) s << ", "; 103 }; 104 s << "]"; 105 return s; 106 } 107 108 /// Easy printing of vectors. 109 110 /// \tparam T Type stored in the vector. 111 /// \param[in,out] s The output stream. 112 /// \param[in] c The vector. 113 /// \return The output stream (for chaining). 114 template <typename T> 115 std::ostream& operator<<(std::ostream& s, const std::vector<T>& c) { 116 s << "["; 117 typename std::vector<T>::const_iterator it = c.begin(); 118 while (it != c.end()) { 119 s << *it; 120 ++it; 121 if (it != c.end()) s << ", "; 122 }; 123 s << "]"; 124 return s; 125 } 126 127 /// Easy printing of fixed dimension arrays. 128 129 /// STL I/O already does char (thus the \c enable_if business). 130 /// \tparam T Type of data in the array. 131 /// \tparam N Size of the array. 132 /// \param[in,out] s The output stream. 133 /// \param[in] v The array. 134 /// \return The output stream (for chaining). 135 template <typename T, std::size_t N> 136 typename std::enable_if<!std::is_same<T,char>::value, std::ostream&>::type 137 operator<<(std::ostream& s, const T(&v)[N]) { 138 s << "["; 139 for (std::size_t i=0; i<N; ++i) { 140 s << v[i]; 141 if (i != (N-1)) s << ","; 142 } 143 s << "]"; 144 return s; 145 } 146 147 /// Print a string justified on the left to start at the given column with optional underlining. 148 void print_justified(const char* s, int column=0, bool underline=true); 149 150 /// Print a string centered at the given column with optional underlining. 151 void print_centered(const char* s, int column=40, bool underline=true); 152 153 154 // the "print" function and functions to help handle the variadic templates 155 156 /// Helper function for \c print. Base case. 157 158 /// This gets called recursively when there are no items left to print. 159 /// \param[in,out] out Output stream. 160 /// \return The output stream (for chaining). print_helper(std::ostream & out)161 inline std::ostream& print_helper(std::ostream& out) { 162 return out; 163 } 164 165 /// \brief Helper function for \c print. Prints the first item (\c t) and 166 /// recursively passes on the other items. 167 168 /// \tparam T Type of the item to print in this call. 169 /// \tparam Ts Argument pack type for the remaining items. 170 /// \param[in,out] out Output stream. 171 /// \param[in] t The item to print in this call. 172 /// \param[in] ts The remaining items in the argument pack (they get 173 /// recursively passed on). 174 /// \return The output stream (for chaining). 175 template <typename T, typename... Ts> print_helper(std::ostream & out,const T & t,const Ts &...ts)176 inline std::ostream& print_helper(std::ostream& out, 177 const T& t, const Ts&... ts) { 178 out << ' ' << t; 179 return print_helper(out, ts...); 180 } 181 182 /// \brief Print items to \c std::cout (items separated by spaces) and 183 /// terminate with a new line 184 185 /// The first item is printed here so that it isn't preceded by a space. 186 /// \tparam T Type of the first item to be printed. 187 /// \tparam Ts Argument pack type for the items to be printed. 188 /// \param[in] t The first item to be printed. 189 /// \param[in] ts The remaining items to be printed in the argument pack. 190 template<typename T, typename... Ts> print(const T & t,const Ts &...ts)191 void print(const T& t, const Ts&... ts) { 192 ScopedMutex<Mutex> safe(detail::printmutex); 193 std::cout << t; 194 print_helper(std::cout, ts...) << ENDL; 195 } 196 197 /// \brief Print items to \c std::cerr (items separated by spaces) and 198 /// terminate with a new line 199 200 /// The first item is printed here so that it isn't preceded by a space. 201 /// \tparam T Type of the first item to be printed. 202 /// \tparam Ts Argument pack type for the items to be printed. 203 /// \param[in] t The first item to be printed. 204 /// \param[in] ts The remaining items to be printed in the argument pack. 205 template<typename T, typename... Ts> print_error(const T & t,const Ts &...ts)206 void print_error(const T& t, const Ts&... ts) { 207 ScopedMutex<Mutex> safe(detail::printmutex); 208 std::cerr << t; 209 print_helper(std::cerr, ts...) << ENDL; 210 } 211 212 /// @} 213 214 } 215 #endif // MADNESS_WORLD_PRINT_H__INCLUDED 216