// Backward-compat support -*- C++ -*-

// Copyright (C) 2001-2026 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.

// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
// <http://www.gnu.org/licenses/>.

/*
 * Copyright (c) 1998
 * Silicon Graphics Computer Systems, Inc.
 *
 * Permission to use, copy, modify, distribute and sell this software
 * and its documentation for any purpose is hereby granted without fee,
 * provided that the above copyright notice appear in all copies and
 * that both that copyright notice and this permission notice appear
 * in supporting documentation.  Silicon Graphics makes no
 * representations about the suitability of this software for any
 * purpose.  It is provided "as is" without express or implied warranty.
 */

// WARNING: The classes defined in this header are DEPRECATED.  This
// header is defined in section D.7.1 of the C++ standard, and it
// MAY BE REMOVED in a future standard revision.  One should use the
// header <sstream> instead.

/** @file strstream
 *  This is a Standard C++ Library header.
 */

#ifndef _BACKWARD_STRSTREAM
#define _BACKWARD_STRSTREAM

#include <backward/backward_warning.h>
#include <iosfwd>
#include <ios>
#include <istream>
#include <ostream>

namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

#if __glibcxx_spanstream
# define _GLIBCXX_STRSTREAM_DEPR(A, B) _GLIBCXX_DEPRECATED_SUGGEST(A "' or '" B)
#else
# define _GLIBCXX_STRSTREAM_DEPR(A, B) _GLIBCXX_DEPRECATED_SUGGEST(A)
#endif

  // Class strstreambuf, a streambuf class that manages an array of char.
  // Note that this class is not a template.
  class strstreambuf : public basic_streambuf<char, char_traits<char> >
  {
  public:
    // Types.
    typedef char_traits<char>              _Traits;
    typedef basic_streambuf<char, _Traits> _Base;

  public:
    // Constructor, destructor
#if __cplusplus >= 201103L
    strstreambuf() : strstreambuf(0) { }
    explicit strstreambuf(streamsize __initial_capacity);
#else
    explicit strstreambuf(streamsize __initial_capacity = 0);
#endif
    strstreambuf(void* (*__alloc)(size_t), void (*__free)(void*));

    strstreambuf(char* __get, streamsize __n, char* __put = 0) throw ();
    strstreambuf(signed char* __get, streamsize __n, signed char* __put = 0) throw ();
    strstreambuf(unsigned char* __get, streamsize __n, unsigned char* __put=0) throw ();

    strstreambuf(const char* __get, streamsize __n) throw ();
    strstreambuf(const signed char* __get, streamsize __n) throw ();
    strstreambuf(const unsigned char* __get, streamsize __n) throw ();

    virtual ~strstreambuf();

#if __cplusplus >= 201103L
    strstreambuf(strstreambuf&& __rhs) noexcept
    : _Base(__rhs), _M_alloc_fun(__rhs._M_alloc_fun),
      _M_free_fun(__rhs._M_free_fun), _M_dynamic(__rhs._M_dynamic),
      _M_frozen(__rhs._M_frozen), _M_constant(__rhs._M_constant)
    {
      __rhs.setg(nullptr, nullptr, nullptr);
      __rhs.setp(nullptr, nullptr);
    }

    strstreambuf&
    operator=(strstreambuf&& __rhs) noexcept
    {
      if (_M_dynamic && !_M_frozen)
	_M_free(eback());
      _Base::operator=(static_cast<const _Base&>(__rhs));
      _M_alloc_fun = __rhs._M_alloc_fun;
      _M_free_fun = __rhs._M_free_fun;
      _M_dynamic = __rhs._M_dynamic;
      _M_frozen = __rhs._M_frozen;
      _M_constant = __rhs._M_constant;
      __rhs.setg(nullptr, nullptr, nullptr);
      __rhs.setp(nullptr, nullptr);
      return *this;
    }
#endif

  public:
    void freeze(bool = true) throw ();
    char* str() throw ();
    _GLIBCXX_PURE int pcount() const throw ();

  protected:
    virtual int_type overflow(int_type __c  = _Traits::eof());
    virtual int_type pbackfail(int_type __c = _Traits::eof());
    virtual int_type underflow();
    virtual _Base* setbuf(char* __buf, streamsize __n);
    virtual pos_type seekoff(off_type __off, ios_base::seekdir __dir,
			     ios_base::openmode __mode
			     = ios_base::in | ios_base::out);
    virtual pos_type seekpos(pos_type __pos, ios_base::openmode __mode
			     = ios_base::in | ios_base::out);

  private:
#if __cplusplus < 201103L
    strstreambuf&
    operator=(const strstreambuf&);

    strstreambuf(const strstreambuf&);
#endif

    // Dynamic allocation, possibly using _M_alloc_fun and _M_free_fun.
    char* _M_alloc(size_t);
    void  _M_free(char*);

    // Helper function used in constructors.
    void _M_setup(char* __get, char* __put, streamsize __n) throw ();

    // Data members.
    void* (*_M_alloc_fun)(size_t);
    void  (*_M_free_fun)(void*);

    bool _M_dynamic  : 1;
    bool _M_frozen   : 1;
    bool _M_constant : 1;
  } _GLIBCXX_STRSTREAM_DEPR("std::stringbuf", "std::spanbuf");

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"

  // Class istrstream, an istream that manages a strstreambuf.
  class istrstream : public basic_istream<char>
  {
  public:
    explicit istrstream(char*);
    explicit istrstream(const char*);
    istrstream(char* , streamsize);
    istrstream(const char*, streamsize);
    virtual ~istrstream();

#if __cplusplus >= 201103L
    istrstream(istrstream&& __rhs)
    : istream(std::move(__rhs)), _M_buf(std::move(__rhs._M_buf))
    { set_rdbuf(&_M_buf); }

    istrstream& operator=(istrstream&&) = default;
#endif

    _GLIBCXX_CONST strstreambuf* rdbuf() const throw ();
    char* str() throw ();

  private:
    strstreambuf _M_buf;
  } _GLIBCXX_STRSTREAM_DEPR("std::istringstream", "std::ispanstream");

  // Class ostrstream
  class ostrstream : public basic_ostream<char>
  {
  public:
    ostrstream();
    ostrstream(char*, int, ios_base::openmode = ios_base::out);
    virtual ~ostrstream();

#if __cplusplus >= 201103L
    ostrstream(ostrstream&& __rhs)
    : ostream(std::move(__rhs)), _M_buf(std::move(__rhs._M_buf))
    { set_rdbuf(&_M_buf); }

    ostrstream& operator=(ostrstream&&) = default;
#endif

    _GLIBCXX_CONST strstreambuf* rdbuf() const throw ();
    void freeze(bool = true) throw();
    char* str() throw ();
    _GLIBCXX_PURE int pcount() const throw ();

  private:
    strstreambuf _M_buf;
  } _GLIBCXX_STRSTREAM_DEPR("std::ostringstream", "std::ospanstream");

  // Class strstream
  class strstream : public basic_iostream<char>
  {
  public:
    typedef char                        char_type;
    typedef char_traits<char>::int_type int_type;
    typedef char_traits<char>::pos_type pos_type;
    typedef char_traits<char>::off_type off_type;

    strstream();
    strstream(char*, int, ios_base::openmode = ios_base::in | ios_base::out);
    virtual ~strstream();

#if __cplusplus >= 201103L
    strstream(strstream&& __rhs)
    : iostream(std::move(__rhs)), _M_buf(std::move(__rhs._M_buf))
    { set_rdbuf(&_M_buf); }

    strstream& operator=(strstream&&) = default;
#endif

    _GLIBCXX_CONST strstreambuf* rdbuf() const throw ();
    void freeze(bool = true) throw ();
    _GLIBCXX_PURE int pcount() const throw ();
    char* str() throw ();

  private:
    strstreambuf _M_buf;
  } _GLIBCXX_STRSTREAM_DEPR("std::stringstream", "std::spanstream");

#undef _GLIBCXX_STRSTREAM_DEPR
#pragma GCC diagnostic pop

_GLIBCXX_END_NAMESPACE_VERSION
} // namespace

#endif
