1  // Position types -*- C++ -*-
       2  
       3  // Copyright (C) 1997-2023 Free Software Foundation, Inc.
       4  //
       5  // This file is part of the GNU ISO C++ Library.  This library is free
       6  // software; you can redistribute it and/or modify it under the
       7  // terms of the GNU General Public License as published by the
       8  // Free Software Foundation; either version 3, or (at your option)
       9  // any later version.
      10  
      11  // This library is distributed in the hope that it will be useful,
      12  // but WITHOUT ANY WARRANTY; without even the implied warranty of
      13  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14  // GNU General Public License for more details.
      15  
      16  // Under Section 7 of GPL version 3, you are granted additional
      17  // permissions described in the GCC Runtime Library Exception, version
      18  // 3.1, as published by the Free Software Foundation.
      19  
      20  // You should have received a copy of the GNU General Public License and
      21  // a copy of the GCC Runtime Library Exception along with this program;
      22  // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
      23  // <http://www.gnu.org/licenses/>.
      24  
      25  /** @file bits/postypes.h
      26   *  This is an internal header file, included by other library headers.
      27   *  Do not attempt to use it directly. @headername{iosfwd}
      28   */
      29  
      30  //
      31  // ISO C++ 14882: 27.4.1 - Types
      32  // ISO C++ 14882: 27.4.3 - Template class fpos
      33  //
      34  
      35  #ifndef _GLIBCXX_POSTYPES_H
      36  #define _GLIBCXX_POSTYPES_H 1
      37  
      38  #pragma GCC system_header
      39  
      40  #include <cwchar> // For mbstate_t
      41  
      42  namespace std _GLIBCXX_VISIBILITY(default)
      43  {
      44  _GLIBCXX_BEGIN_NAMESPACE_VERSION
      45  
      46    // The types streamoff, streampos and wstreampos and the class
      47    // template fpos<> are described in clauses 21.1.2, 21.1.3, 27.1.2,
      48    // 27.2, 27.4.1, 27.4.3 and D.6. Despite all this verbiage, the
      49    // behaviour of these types is mostly implementation defined or
      50    // unspecified. The behaviour in this implementation is as noted
      51    // below.
      52  
      53    /**
      54     *  @brief  Type used by fpos, char_traits<char>, and char_traits<wchar_t>.
      55     *
      56     *  In clauses 21.1.3.1 and 27.4.1 streamoff is described as an
      57     *  implementation defined type.
      58     *  Note: In versions of GCC up to and including GCC 3.3, streamoff
      59     *  was typedef long.
      60    */  
      61  #ifdef __INT64_TYPE__
      62    typedef __INT64_TYPE__          streamoff;
      63  #else
      64    typedef long long     streamoff;
      65  #endif
      66  
      67    /// Integral type for I/O operation counts and buffer sizes.
      68    typedef ptrdiff_t	streamsize; // Signed integral type
      69  
      70    /**
      71     *  @brief  Class representing stream positions.
      72     *
      73     *  The standard places no requirements upon the template parameter StateT.
      74     *  In this implementation StateT must be DefaultConstructible,
      75     *  CopyConstructible and Assignable.  The standard only requires that fpos
      76     *  should contain a member of type StateT. In this implementation it also
      77     *  contains an offset stored as a signed integer.
      78     *
      79     *  @param  StateT  Type passed to and returned from state().
      80     */
      81    template<typename _StateT>
      82      class fpos
      83      {
      84      private:
      85        streamoff	                _M_off;
      86        _StateT			_M_state;
      87  
      88      public:
      89        // The standard doesn't require that fpos objects can be default
      90        // constructed. This implementation provides a default
      91        // constructor that initializes the offset to 0 and default
      92        // constructs the state.
      93        fpos()
      94        : _M_off(0), _M_state() { }
      95  
      96        // The standard requires that fpos objects can be constructed
      97        // from streamoff objects using the constructor syntax, and
      98        // fails to give any meaningful semantics. In this
      99        // implementation implicit conversion is also allowed, and this
     100        // constructor stores the streamoff as the offset and default
     101        // constructs the state.
     102        /// Construct position from offset.
     103        fpos(streamoff __off)
     104        : _M_off(__off), _M_state() { }
     105  
     106  #if __cplusplus >= 201103L
     107        fpos(const fpos&) = default;
     108        fpos& operator=(const fpos&) = default;
     109        ~fpos() = default;
     110  #endif
     111  
     112        /// Convert to streamoff.
     113        operator streamoff() const { return _M_off; }
     114  
     115        /// Remember the value of @a st.
     116        void
     117        state(_StateT __st)
     118        { _M_state = __st; }
     119  
     120        /// Return the last set value of @a st.
     121        _StateT
     122        state() const
     123        { return _M_state; }
     124  
     125        // The standard requires that this operator must be defined, but
     126        // gives no semantics. In this implementation it just adds its
     127        // argument to the stored offset and returns *this.
     128        /// Add offset to this position.
     129        fpos&
     130        operator+=(streamoff __off)
     131        {
     132  	_M_off += __off;
     133  	return *this;
     134        }
     135  
     136        // The standard requires that this operator must be defined, but
     137        // gives no semantics. In this implementation it just subtracts
     138        // its argument from the stored offset and returns *this.
     139        /// Subtract offset from this position.
     140        fpos&
     141        operator-=(streamoff __off)
     142        {
     143  	_M_off -= __off;
     144  	return *this;
     145        }
     146  
     147        // The standard requires that this operator must be defined, but
     148        // defines its semantics only in terms of operator-. In this
     149        // implementation it constructs a copy of *this, adds the
     150        // argument to that copy using operator+= and then returns the
     151        // copy.
     152        /// Add position and offset.
     153        fpos
     154        operator+(streamoff __off) const
     155        {
     156  	fpos __pos(*this);
     157  	__pos += __off;
     158  	return __pos;
     159        }
     160  
     161        // The standard requires that this operator must be defined, but
     162        // defines its semantics only in terms of operator+. In this
     163        // implementation it constructs a copy of *this, subtracts the
     164        // argument from that copy using operator-= and then returns the
     165        // copy.
     166        /// Subtract offset from position.
     167        fpos
     168        operator-(streamoff __off) const
     169        {
     170  	fpos __pos(*this);
     171  	__pos -= __off;
     172  	return __pos;
     173        }
     174  
     175        // The standard requires that this operator must be defined, but
     176        // defines its semantics only in terms of operator+. In this
     177        // implementation it returns the difference between the offset
     178        // stored in *this and in the argument.
     179        /// Subtract position to return offset.
     180        streamoff
     181        operator-(const fpos& __other) const
     182        { return _M_off - __other._M_off; }
     183      };
     184  
     185    // The standard only requires that operator== must be an
     186    // equivalence relation. In this implementation two fpos<StateT>
     187    // objects belong to the same equivalence class if the contained
     188    // offsets compare equal.
     189    /// Test if equivalent to another position.
     190    template<typename _StateT>
     191      inline bool
     192      operator==(const fpos<_StateT>& __lhs, const fpos<_StateT>& __rhs)
     193      { return streamoff(__lhs) == streamoff(__rhs); }
     194  
     195    template<typename _StateT>
     196      inline bool
     197      operator!=(const fpos<_StateT>& __lhs, const fpos<_StateT>& __rhs)
     198      { return streamoff(__lhs) != streamoff(__rhs); }
     199  
     200    // Clauses 21.1.3.1 and 21.1.3.2 describe streampos and wstreampos
     201    // as implementation defined types, but clause 27.2 requires that
     202    // they must both be typedefs for fpos<mbstate_t>
     203    /// File position for char streams.
     204    typedef fpos<mbstate_t> streampos;
     205    /// File position for wchar_t streams.
     206    typedef fpos<mbstate_t> wstreampos;
     207  
     208  #ifdef _GLIBCXX_USE_CHAR8_T
     209    /// File position for char8_t streams.
     210    typedef fpos<mbstate_t> u8streampos;
     211  #endif
     212  
     213  #if __cplusplus >= 201103L
     214    /// File position for char16_t streams.
     215    typedef fpos<mbstate_t> u16streampos;
     216    /// File position for char32_t streams.
     217    typedef fpos<mbstate_t> u32streampos;
     218  #endif
     219  
     220  _GLIBCXX_END_NAMESPACE_VERSION
     221  } // namespace
     222  
     223  #endif