diff options
Diffstat (limited to 'libcutl/cutl/compiler/code-stream.hxx')
-rw-r--r-- | libcutl/cutl/compiler/code-stream.hxx | 154 |
1 files changed, 154 insertions, 0 deletions
diff --git a/libcutl/cutl/compiler/code-stream.hxx b/libcutl/cutl/compiler/code-stream.hxx new file mode 100644 index 0000000..bfd33d0 --- /dev/null +++ b/libcutl/cutl/compiler/code-stream.hxx @@ -0,0 +1,154 @@ +// file : cutl/compiler/code-stream.hxx +// copyright : Copyright (c) 2009-2013 Code Synthesis Tools CC +// license : MIT; see accompanying LICENSE file + +#ifndef CUTL_COMPILER_CODE_STREAM_HXX +#define CUTL_COMPILER_CODE_STREAM_HXX + +#include <memory> // std::auto_ptr +#include <ostream> + +#include <cutl/exception.hxx> + +namespace cutl +{ + namespace compiler + { + // + // + template <typename C> + class code_stream + { + public: + code_stream () {} + + virtual + ~code_stream (); + + public: + virtual void + put (C) = 0; + + // Unbuffer flushes internal formatting buffers (if any). + // Note that unbuffer is not exactly flushing since it can + // result in formatting errors and in general can not be + // called at arbitrary points. Natural use case would be + // to call unbuffer at the end of the stream when no more + // data is expected. + // + virtual void + unbuffer () = 0; + + private: + code_stream (code_stream const&); + + code_stream& + operator= (code_stream const&); + }; + + // + // + template <typename C> + class from_streambuf_adapter: public code_stream<C> + { + public: + typedef typename std::basic_streambuf<C>::traits_type traits_type; + typedef typename std::basic_streambuf<C>::int_type int_type; + + class eof: exception {}; + class sync: exception {}; + + public: + from_streambuf_adapter (std::basic_streambuf<C>& stream) + : stream_ (stream) + { + } + + private: + from_streambuf_adapter (from_streambuf_adapter const&); + + from_streambuf_adapter& + operator= (from_streambuf_adapter const&); + + public: + virtual void + put (C c); + + virtual void + unbuffer (); + + private: + std::basic_streambuf<C>& stream_; + }; + + // + // + template <typename C> + class to_streambuf_adapter: public std::basic_streambuf<C> + { + public: + typedef typename std::basic_streambuf<C>::traits_type traits_type; + typedef typename std::basic_streambuf<C>::int_type int_type; + + public: + to_streambuf_adapter (code_stream<C>& stream) + : stream_ (stream) + { + } + + private: + to_streambuf_adapter (to_streambuf_adapter const&); + + to_streambuf_adapter& + operator= (to_streambuf_adapter const&); + + public: + virtual int_type + overflow (int_type i); + + // Does nothing since calling unbuffer here would be dangerous. + // See the note in code_stream. + // + virtual int + sync (); + + private: + code_stream<C>& stream_; + }; + + // + // + template <template <typename> class S, typename C> + class ostream_filter + { + public: + typedef S<C> stream_type; + + ostream_filter (std::basic_ostream<C>& os); + ~ostream_filter (); + + stream_type& + stream () + { + return stream_; + } + + private: + ostream_filter (ostream_filter const&); + + ostream_filter& + operator= (ostream_filter const&); + + private: + std::basic_ostream<C>& os_; + std::basic_streambuf<C>* prev_; + from_streambuf_adapter<C> from_adapter_; + stream_type stream_; + to_streambuf_adapter<C> to_adapter_; + }; + } +} + +#include <cutl/compiler/code-stream.txx> + +#endif // CUTL_COMPILER_CODE_STREAM_HXX |