1169691Skan// Helpers for ostream inserters -*- C++ -*-
2169691Skan
3169691Skan// Copyright (C) 2007 Free Software Foundation, Inc.
4169691Skan//
5169691Skan// This file is part of the GNU ISO C++ Library.  This library is free
6169691Skan// software; you can redistribute it and/or modify it under the
7169691Skan// terms of the GNU General Public License as published by the
8169691Skan// Free Software Foundation; either version 2, or (at your option)
9169691Skan// any later version.
10169691Skan
11169691Skan// This library is distributed in the hope that it will be useful,
12169691Skan// but WITHOUT ANY WARRANTY; without even the implied warranty of
13169691Skan// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14169691Skan// GNU General Public License for more details.
15169691Skan
16169691Skan// You should have received a copy of the GNU General Public License along
17169691Skan// with this library; see the file COPYING.  If not, write to the Free
18169691Skan// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
19169691Skan// USA.
20169691Skan
21169691Skan// As a special exception, you may use this file as part of a free software
22169691Skan// library without restriction.  Specifically, if other files instantiate
23169691Skan// templates or use macros or inline functions from this file, or you compile
24169691Skan// this file and link it with other files to produce an executable, this
25169691Skan// file does not by itself cause the resulting executable to be covered by
26169691Skan// the GNU General Public License.  This exception does not however
27169691Skan// invalidate any other reasons why the executable file might be covered by
28169691Skan// the GNU General Public License.
29169691Skan
30169691Skan/** @file ostream_insert.h
31169691Skan *  This is an internal header file, included by other library headers.
32169691Skan *  You should not attempt to use it directly.
33169691Skan */
34169691Skan
35169691Skan#ifndef _OSTREAM_INSERT_H
36169691Skan#define _OSTREAM_INSERT_H 1
37169691Skan
38169691Skan#pragma GCC system_header
39169691Skan
40169691Skan#include <iosfwd>
41169691Skan
42169691Skan_GLIBCXX_BEGIN_NAMESPACE(std)
43169691Skan
44169691Skan  template<typename _CharT, typename _Traits>
45169691Skan    inline void
46169691Skan    __ostream_write(basic_ostream<_CharT, _Traits>& __out,
47169691Skan		    const _CharT* __s, streamsize __n)
48169691Skan    {
49169691Skan      typedef basic_ostream<_CharT, _Traits>       __ostream_type;
50169691Skan      typedef typename __ostream_type::ios_base    __ios_base;
51169691Skan
52169691Skan      const streamsize __put = __out.rdbuf()->sputn(__s, __n);
53169691Skan      if (__put != __n)
54169691Skan	__out.setstate(__ios_base::badbit);
55169691Skan    }
56169691Skan
57169691Skan  template<typename _CharT, typename _Traits>
58169691Skan    inline void
59169691Skan    __ostream_fill(basic_ostream<_CharT, _Traits>& __out, streamsize __n)
60169691Skan    {
61169691Skan      typedef basic_ostream<_CharT, _Traits>       __ostream_type;
62169691Skan      typedef typename __ostream_type::ios_base    __ios_base;
63169691Skan
64169691Skan      const _CharT __c = __out.fill();
65169691Skan      for (; __n > 0; --__n)
66169691Skan	{
67169691Skan	  const typename _Traits::int_type __put = __out.rdbuf()->sputc(__c);
68169691Skan	  if (_Traits::eq_int_type(__put, _Traits::eof()))
69169691Skan	    {
70169691Skan	      __out.setstate(__ios_base::badbit);
71169691Skan	      break;
72169691Skan	    }
73169691Skan	}
74169691Skan    }
75169691Skan
76169691Skan  template<typename _CharT, typename _Traits>
77169691Skan    basic_ostream<_CharT, _Traits>&
78169691Skan    __ostream_insert(basic_ostream<_CharT, _Traits>& __out,
79169691Skan		     const _CharT* __s, streamsize __n)
80169691Skan    {
81169691Skan      typedef basic_ostream<_CharT, _Traits>       __ostream_type;
82169691Skan      typedef typename __ostream_type::ios_base    __ios_base;
83169691Skan
84169691Skan      typename __ostream_type::sentry __cerb(__out);
85169691Skan      if (__cerb)
86169691Skan	{
87169691Skan	  try
88169691Skan	    {
89169691Skan	      const streamsize __w = __out.width();
90169691Skan	      if (__w > __n)
91169691Skan		{
92169691Skan		  const bool __left = ((__out.flags()
93169691Skan					& __ios_base::adjustfield)
94169691Skan				       == __ios_base::left);
95169691Skan		  if (!__left)
96169691Skan		    __ostream_fill(__out, __w - __n);
97169691Skan		  if (__out.good())
98169691Skan		    __ostream_write(__out, __s, __n);
99169691Skan		  if (__left && __out.good())
100169691Skan		    __ostream_fill(__out, __w - __n);
101169691Skan		}
102169691Skan	      else
103169691Skan		__ostream_write(__out, __s, __n);
104169691Skan	      __out.width(0);
105169691Skan	    }
106169691Skan	  catch(...)
107169691Skan	    { __out._M_setstate(__ios_base::badbit); }
108169691Skan	}
109169691Skan      return __out;
110169691Skan    }
111169691Skan
112171827Skan  // Inhibit implicit instantiations for required instantiations,
113171827Skan  // which are defined via explicit instantiations elsewhere.
114171827Skan  // NB:  This syntax is a GNU extension.
115171827Skan#if _GLIBCXX_EXTERN_TEMPLATE
116171827Skan  extern template ostream& __ostream_insert(ostream&, const char*, streamsize);
117171827Skan
118171827Skan#ifdef _GLIBCXX_USE_WCHAR_T
119171827Skan  extern template wostream& __ostream_insert(wostream&, const wchar_t*,
120171827Skan					     streamsize);
121171827Skan#endif
122171827Skan#endif
123171827Skan
124169691Skan_GLIBCXX_END_NAMESPACE
125169691Skan
126169691Skan#endif /* _OSTREAM_INSERT_H */
127