blob: 8dfc4093bdbd3ed840eb408bde73fa0072a61edd (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
// file : CCF/CodeGenerationKit/IndentationImplanter.hpp
// author : Boris Kolpackov <boris@dre.vanderbilt.edu>
// cvs-id : $Id$
#ifndef CCF_CODE_GENERATION_KIT_INDENTATION_IMPLANTER
#define CCF_CODE_GENERATION_KIT_INDENTATION_IMPLANTER
#include <ostream>
#include "CCF/CodeGenerationKit/IndentationBuffer.hpp"
namespace Indentation
{
class ToStreamBufAdapter : public std::streambuf
{
public:
ToStreamBufAdapter (Buffer& buffer)
: buffer_ (buffer)
{
}
virtual int_type
overflow (int_type c)
{
return buffer_.put (Buffer::traits_type::to_char_type (c));
}
virtual int
sync ()
{
return 0;
}
private:
Buffer& buffer_;
};
class FromStreamBufAdapter : public Buffer
{
public:
FromStreamBufAdapter (std::streambuf& buffer)
: buffer_ (buffer)
{
}
virtual int_type
put (char_type c) throw (Exception, ExH::System::Exception)
{
return buffer_.sputc (traits_type::to_int_type (c));
}
virtual void
unbuffer () throw (ExH::System::Exception)
{
try
{
if (buffer_.pubsync () == 0) return;
}
catch (std::ios_base::failure const&)
{
}
throw Exception ("underlying std::streambuf::sync failed");
}
private:
std::streambuf& buffer_;
};
template <typename Buffer>
class Implanter
{
public:
Implanter (std::ostream& os)
: os_ (os),
prev_ (os_.rdbuf ()),
from_adapter_ (*prev_),
buffer_ (from_adapter_),
to_adapter_ (buffer_)
{
os_.rdbuf (&to_adapter_);
}
template <typename Arg0>
Implanter (std::ostream& os, Arg0 a0)
: os_ (os),
prev_ (os_.rdbuf ()),
from_adapter_ (*prev_),
buffer_ (from_adapter_, a0),
to_adapter_ (buffer_)
{
os_.rdbuf (&to_adapter_);
}
~Implanter ()
{
try
{
buffer_.unbuffer ();
}
catch (...)
{
// there is nothing I can do...
}
os_.rdbuf (prev_);
}
private:
std::ostream& os_;
std::streambuf* prev_;
FromStreamBufAdapter from_adapter_;
Buffer buffer_;
ToStreamBufAdapter to_adapter_;
};
}
#endif // CCF_CODE_GENERATION_KIT_INDENTATION_IMPLANTER
|