diff options
author | Jörg Frings-Fürst <jff@merkur> | 2014-05-18 16:08:14 +0200 |
---|---|---|
committer | Jörg Frings-Fürst <jff@merkur> | 2014-05-18 16:08:14 +0200 |
commit | a15cf65c44d5c224169c32ef5495b68c758134b7 (patch) | |
tree | 3419f58fc8e1b315ba8171910ee044c5d467c162 /libbackend-elements/backend-elements/indentation/clip.hxx |
Imported Upstream version 3.3.0.2upstream/3.3.0.2
Diffstat (limited to 'libbackend-elements/backend-elements/indentation/clip.hxx')
-rw-r--r-- | libbackend-elements/backend-elements/indentation/clip.hxx | 173 |
1 files changed, 173 insertions, 0 deletions
diff --git a/libbackend-elements/backend-elements/indentation/clip.hxx b/libbackend-elements/backend-elements/indentation/clip.hxx new file mode 100644 index 0000000..068ed0d --- /dev/null +++ b/libbackend-elements/backend-elements/indentation/clip.hxx @@ -0,0 +1,173 @@ +// file : backend-elements/indentation/clip.hxx +// author : Boris Kolpackov <boris@kolpackov.net> +// copyright : Copyright (c) 2005-2010 Boris Kolpackov +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef BACKEND_ELEMENTS_INDENTATION_CLIP_HXX +#define BACKEND_ELEMENTS_INDENTATION_CLIP_HXX + +#include <backend-elements/types.hxx> + +#include <backend-elements/indentation/buffer.hxx> + +#include <ostream> + +namespace BackendElements +{ + namespace Indentation + { + template <typename C> + class ToStreambufAdapter: public std::basic_streambuf<C>, + public NonCopyable + { + public: + typedef + typename std::basic_streambuf<C>::traits_type + Traits; + + typedef + typename std::basic_streambuf<C>::char_type + AsChar; + + typedef + typename std::basic_streambuf<C>::int_type + AsInt; + + public: + ToStreambufAdapter (Buffer<C>& buffer) + : buffer_ (buffer) + { + } + + virtual AsInt + overflow (AsInt ch) + { + return buffer_.put (Traits::to_char_type (ch)); + } + + virtual Int + sync () + { + return 0; + } + + private: + Buffer<C>& buffer_; + }; + + + template <typename C> + class FromStreambufAdapter: public Buffer<C> + { + public: + typedef + typename Buffer<C>::Traits + Traits; + + typedef + typename Buffer<C>::AsChar + AsChar; + + typedef + typename Buffer<C>::AsInt + AsInt; + + typedef + typename Buffer<C>::Write + Write; + + public: + FromStreambufAdapter (std::basic_streambuf<C>& b) + : buffer_ (b) + { + } + + virtual AsInt + put (AsChar ch) + { + return buffer_.sputc (ch); + } + + virtual Void + unbuffer () + { + try + { + if (buffer_.pubsync () == 0) return; + } + catch (std::ios_base::failure const&) + { + } + + throw Write (); + } + + private: + std::basic_streambuf<C>& buffer_; + }; + + + template <template <typename> class Buffer, typename C = Char> + class Clip: public NonCopyable + { + public: + Clip (std::basic_ostream<C>& os) + : os_ (os), + prev_ (os_.rdbuf ()), + from_adapter_ (*prev_), + buffer_ (from_adapter_), + to_adapter_ (buffer_) + { + os_.rdbuf (&to_adapter_); + } + + /* + template <typename Arg0> + Clip (std::basic_ostream<C>& os, Arg0 a0) + : os_ (os), + prev_ (os_.rdbuf ()), + from_adapter_ (*prev_), + buffer_ (from_adapter_, a0), + to_adapter_ (buffer_) + { + os_.rdbuf (&to_adapter_); + } + */ + + ~Clip () + { + try + { + buffer_.unbuffer (); + } + catch (...) + { + os_.rdbuf (prev_); + throw; + } + + os_.rdbuf (prev_); + } + + Buffer<C>& + buffer () + { + return buffer_; + } + + private: + std::basic_ostream<C>& os_; + std::basic_streambuf<C>* prev_; + + FromStreambufAdapter<C> from_adapter_; + + Buffer<C> buffer_; + + ToStreambufAdapter<C> to_adapter_; + }; + } +} + +#include <backend-elements/indentation/clip.txx> + +#endif // BACKEND_ELEMENTS_INDENTATION_CLIP_HXX |