ostream_insert.h revision 169691
1216642Sdavidxu// Helpers for ostream inserters -*- C++ -*-
2216642Sdavidxu
3216642Sdavidxu// Copyright (C) 2007 Free Software Foundation, Inc.
4216642Sdavidxu//
5216642Sdavidxu// This file is part of the GNU ISO C++ Library.  This library is free
6216642Sdavidxu// software; you can redistribute it and/or modify it under the
7216642Sdavidxu// terms of the GNU General Public License as published by the
8216642Sdavidxu// Free Software Foundation; either version 2, or (at your option)
9216642Sdavidxu// any later version.
10216642Sdavidxu
11216642Sdavidxu// This library is distributed in the hope that it will be useful,
12216642Sdavidxu// but WITHOUT ANY WARRANTY; without even the implied warranty of
13216642Sdavidxu// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14216642Sdavidxu// GNU General Public License for more details.
15216642Sdavidxu
16216642Sdavidxu// You should have received a copy of the GNU General Public License along
17216642Sdavidxu// with this library; see the file COPYING.  If not, write to the Free
18216642Sdavidxu// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
19216642Sdavidxu// USA.
20216642Sdavidxu
21216642Sdavidxu// As a special exception, you may use this file as part of a free software
22216642Sdavidxu// library without restriction.  Specifically, if other files instantiate
23216642Sdavidxu// templates or use macros or inline functions from this file, or you compile
24216642Sdavidxu// this file and link it with other files to produce an executable, this
25216642Sdavidxu// file does not by itself cause the resulting executable to be covered by
26216642Sdavidxu// the GNU General Public License.  This exception does not however
27297706Skib// invalidate any other reasons why the executable file might be covered by
28297706Skib// the GNU General Public License.
29297706Skib
30216642Sdavidxu/** @file ostream_insert.h
31216642Sdavidxu *  This is an internal header file, included by other library headers.
32216642Sdavidxu *  You should not attempt to use it directly.
33216642Sdavidxu */
34216642Sdavidxu
35216642Sdavidxu#ifndef _OSTREAM_INSERT_H
36216642Sdavidxu#define _OSTREAM_INSERT_H 1
37216642Sdavidxu
38216642Sdavidxu#pragma GCC system_header
39216642Sdavidxu
40216642Sdavidxu#include <iosfwd>
41216642Sdavidxu
42216642Sdavidxu_GLIBCXX_BEGIN_NAMESPACE(std)
43234947Sdavidxu
44216642Sdavidxu  template<typename _CharT, typename _Traits>
45216642Sdavidxu    inline void
46216642Sdavidxu    __ostream_write(basic_ostream<_CharT, _Traits>& __out,
47216642Sdavidxu		    const _CharT* __s, streamsize __n)
48216642Sdavidxu    {
49216642Sdavidxu      typedef basic_ostream<_CharT, _Traits>       __ostream_type;
50216642Sdavidxu      typedef typename __ostream_type::ios_base    __ios_base;
51216642Sdavidxu
52216642Sdavidxu      const streamsize __put = __out.rdbuf()->sputn(__s, __n);
53216642Sdavidxu      if (__put != __n)
54216642Sdavidxu	__out.setstate(__ios_base::badbit);
55216642Sdavidxu    }
56216642Sdavidxu
57216642Sdavidxu  template<typename _CharT, typename _Traits>
58216642Sdavidxu    inline void
59216642Sdavidxu    __ostream_fill(basic_ostream<_CharT, _Traits>& __out, streamsize __n)
60216642Sdavidxu    {
61216642Sdavidxu      typedef basic_ostream<_CharT, _Traits>       __ostream_type;
62216642Sdavidxu      typedef typename __ostream_type::ios_base    __ios_base;
63216642Sdavidxu
64216642Sdavidxu      const _CharT __c = __out.fill();
65216642Sdavidxu      for (; __n > 0; --__n)
66216642Sdavidxu	{
67216642Sdavidxu	  const typename _Traits::int_type __put = __out.rdbuf()->sputc(__c);
68216642Sdavidxu	  if (_Traits::eq_int_type(__put, _Traits::eof()))
69216642Sdavidxu	    {
70216642Sdavidxu	      __out.setstate(__ios_base::badbit);
71216642Sdavidxu	      break;
72216642Sdavidxu	    }
73216642Sdavidxu	}
74216642Sdavidxu    }
75216642Sdavidxu
76216642Sdavidxu  template<typename _CharT, typename _Traits>
77216642Sdavidxu    basic_ostream<_CharT, _Traits>&
78216642Sdavidxu    __ostream_insert(basic_ostream<_CharT, _Traits>& __out,
79216642Sdavidxu		     const _CharT* __s, streamsize __n)
80216642Sdavidxu    {
81216642Sdavidxu      typedef basic_ostream<_CharT, _Traits>       __ostream_type;
82216642Sdavidxu      typedef typename __ostream_type::ios_base    __ios_base;
83216642Sdavidxu
84216642Sdavidxu      typename __ostream_type::sentry __cerb(__out);
85216642Sdavidxu      if (__cerb)
86216642Sdavidxu	{
87216642Sdavidxu	  try
88216642Sdavidxu	    {
89216642Sdavidxu	      const streamsize __w = __out.width();
90216642Sdavidxu	      if (__w > __n)
91216642Sdavidxu		{
92216642Sdavidxu		  const bool __left = ((__out.flags()
93216642Sdavidxu					& __ios_base::adjustfield)
94216642Sdavidxu				       == __ios_base::left);
95216642Sdavidxu		  if (!__left)
96216642Sdavidxu		    __ostream_fill(__out, __w - __n);
97216642Sdavidxu		  if (__out.good())
98235218Sdavidxu		    __ostream_write(__out, __s, __n);
99235218Sdavidxu		  if (__left && __out.good())
100216642Sdavidxu		    __ostream_fill(__out, __w - __n);
101216642Sdavidxu		}
102216642Sdavidxu	      else
103216642Sdavidxu		__ostream_write(__out, __s, __n);
104216642Sdavidxu	      __out.width(0);
105216642Sdavidxu	    }
106216642Sdavidxu	  catch(...)
107216642Sdavidxu	    { __out._M_setstate(__ios_base::badbit); }
108216642Sdavidxu	}
109235218Sdavidxu      return __out;
110235218Sdavidxu    }
111235218Sdavidxu
112235218Sdavidxu_GLIBCXX_END_NAMESPACE
113235218Sdavidxu
114235218Sdavidxu#endif /* _OSTREAM_INSERT_H */
115216642Sdavidxu