Normalize SourceMgr messages.
[oota-llvm.git] / include / llvm / Support / Streams.h
index 138a07014975aba4b0e88ed761c017e6216f164b..445ab98c476d7711a325eb10851944a80d2f59d1 100644 (file)
@@ -2,52 +2,89 @@
 //
 //                     The LLVM Compiler Infrastructure
 //
-// This file was developed by Bill Wendling and is distributed under the
-// University of Illinois Open Source License. See LICENSE.TXT for details.
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
 //
-// This file implements a wrapper for the std::cout and std::cerr I/O streams.
-// It prevents the need to include <iostream> to each file just to get I/O.
+// This file implements a wrapper for the STL I/O streams.  It prevents the need
+// to include <iostream> in a file just to get I/O.
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_SUPPORT_STREAMS_H
 #define LLVM_SUPPORT_STREAMS_H
 
-#include <ostream>              // Doesn't have static d'tors!!
+#include <iosfwd>
 
 namespace llvm {
 
-  /// llvm_ostream - Acts like an ostream. It's a wrapper for the std::cerr and
-  /// std::cout ostreams. However, it doesn't require #including <iostream> in
-  /// every file, which increases static c'tors & d'tors in the object code.
-  /// 
-  class llvm_ostream {
-    std::ostream* Stream;
+  /// FlushStream - Function called by BaseStream to flush an ostream.
+  void FlushStream(std::ostream &S);
+
+  /// BaseStream - Acts like the STL streams. It's a wrapper for the std::cerr,
+  /// std::cout, std::cin, etc. streams. However, it doesn't require #including
+  /// @verbatim <iostream> @endverbatm in every file (doing so increases static
+  /// c'tors & d'tors in the object code).
+  ///
+  template <typename StreamTy>
+  class BaseStream {
+    StreamTy *Stream;
   public:
-    llvm_ostream() : Stream(0) {}
-    llvm_ostream(std::ostream &OStream) : Stream(&OStream) {}
+    BaseStream() : Stream(0) {}
+    BaseStream(StreamTy &S) : Stream(&S) {}
+    BaseStream(StreamTy *S) : Stream(S) {}
 
-    std::ostream* stream() const { return Stream; }
+    StreamTy *stream() const { return Stream; }
 
-    inline llvm_ostream &operator << (std::ostream& (*Func)(std::ostream&)) {
-      *Stream << Func;
+    inline BaseStream &operator << (std::ios_base &(*Func)(std::ios_base&)) {
+      if (Stream) *Stream << Func;
       return *this;
     }
-      
+
+    inline BaseStream &operator << (StreamTy &(*Func)(StreamTy&)) {
+      if (Stream) *Stream << Func;
+      return *this;
+    }
+
+    void flush() {
+      if (Stream)
+        FlushStream(*Stream);
+    }
+
     template <typename Ty>
-    llvm_ostream &operator << (const Ty &Thing) {
+    BaseStream &operator << (const Ty &Thing) {
       if (Stream) *Stream << Thing;
       return *this;
     }
 
-    bool operator == (const std::ostream &OS) { return &OS == Stream; }
+    template <typename Ty>
+    BaseStream &operator >> (Ty &Thing) {
+      if (Stream) *Stream >> Thing;
+      return *this;
+    }
+
+    template <typename Ty>
+    BaseStream &write(const Ty &A, unsigned N) {
+      if (Stream) Stream->write(A, N);
+      return *this;
+    }
+
+    operator StreamTy* () { return Stream; }
+
+    bool operator == (const StreamTy &S) { return &S == Stream; }
+    bool operator != (const StreamTy &S) { return !(*this == S); }
+    bool operator == (const BaseStream &S) { return S.Stream == Stream; }
+    bool operator != (const BaseStream &S) { return !(*this == S); }
   };
 
-  extern llvm_ostream llvm_null;
-  extern llvm_ostream llvm_cout;
-  extern llvm_ostream llvm_cerr;
+  typedef BaseStream<std::ostream> OStream;
+  typedef BaseStream<std::istream> IStream;
+  typedef BaseStream<std::stringstream> StringStream;
+
+  extern OStream cout;
+  extern OStream cerr;
+  extern IStream cin;
 
 } // End llvm namespace