sbuild  1.7.1
format-detail.h
1 /* Copyright © 2005-2013 Roger Leigh <rleigh@debian.org>
2  *
3  * schroot is free software: you can redistribute it and/or modify it
4  * under the terms of the GNU General Public License as published by
5  * the Free Software Foundation, either version 3 of the License, or
6  * (at your option) any later version.
7  *
8  * schroot is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11  * General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program. If not, see
15  * <http://www.gnu.org/licenses/>.
16  *
17  *********************************************************************/
18 
19 #ifndef SBUILD_FORMAT_DETAIL_H
20 #define SBUILD_FORMAT_DETAIL_H
21 
22 #include <sbuild/types.h>
23 #include <sbuild/util.h>
24 
25 #include <cwchar>
26 #include <iomanip>
27 #include <locale>
28 #include <ostream>
29 #include <sstream>
30 #include <string>
31 
32 namespace sbuild
33 {
34 
39  {
40  public:
47  format_detail (const std::string& title,
48  std::locale locale);
49 
50  virtual ~format_detail ();
51 
60  add (const std::string& name,
61  const std::string& value);
62 
71  add (const std::string& name,
72  bool value);
73 
82  add (const std::string& name,
83  const string_list& value);
84 
92  template<typename T>
94  add (const std::string& name,
95  T const& value)
96  {
97  std::ostringstream varstring;
98  varstring.imbue(this->locale);
99  varstring << value;
100  return add(name, varstring.str());
101  }
102 
103  private:
110  std::string
111  get_title () const;
112 
120  template <class charT, class traits>
121  friend
122  std::basic_ostream<charT,traits>&
123  operator << (std::basic_ostream<charT,traits>& stream,
124  const format_detail& rhs)
125  {
126  std::locale loc = stream.getloc();
127  int max_width = 0;
128 
129  for (const auto& item : rhs.items)
130  {
131  std::wstring wide = widen_string(item.first, loc);
132  int width = wcswidth(wide.c_str(), wide.length());
133 
134  if (max_width < width)
135  max_width = width;
136  }
137 
138  if (max_width < 20)
139  max_width = 20;
140  // To ensure 2 spaces of separation between name and value
141  max_width += 2;
142 
143  stream << " " << rhs.get_title() << '\n';
144 
145  for (const auto& item : rhs.items)
146  {
147  std::wostringstream ws;
148  ws.imbue(loc);
149 
150  std::wstring wide = widen_string(item.first, loc);
151  ws << L" " << std::setw(max_width) << std::left << wide;
152 
153  stream << narrow_string(ws.str(), loc) << item.second << '\n';
154  }
155 
156  return stream;
157  }
158 
159  private:
161  typedef std::pair<std::string,std::string> value_type;
163  typedef std::vector<value_type> list_type;
164 
166  std::string title;
168  std::locale locale;
171  };
172 
173 }
174 
175 #endif /* SBUILD_FORMAT_DETAIL_H */
176 
177 /*
178  * Local Variables:
179  * mode:C++
180  * End:
181  */