2010-05-11 19:42:16 +00:00
|
|
|
// -*- C++ -*-
|
2021-11-17 16:25:01 -05:00
|
|
|
//===----------------------------------------------------------------------===//
|
2010-05-11 19:42:16 +00:00
|
|
|
//
|
2019-01-19 10:56:40 +00:00
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
2010-05-11 19:42:16 +00:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#ifndef _LIBCPP_FSTREAM
|
|
|
|
#define _LIBCPP_FSTREAM
|
|
|
|
|
|
|
|
/*
|
|
|
|
fstream synopsis
|
|
|
|
|
|
|
|
template <class charT, class traits = char_traits<charT> >
|
|
|
|
class basic_filebuf
|
|
|
|
: public basic_streambuf<charT, traits>
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
typedef charT char_type;
|
|
|
|
typedef traits traits_type;
|
|
|
|
typedef typename traits_type::int_type int_type;
|
|
|
|
typedef typename traits_type::pos_type pos_type;
|
|
|
|
typedef typename traits_type::off_type off_type;
|
|
|
|
|
|
|
|
// 27.9.1.2 Constructors/destructor:
|
|
|
|
basic_filebuf();
|
|
|
|
basic_filebuf(basic_filebuf&& rhs);
|
|
|
|
virtual ~basic_filebuf();
|
|
|
|
|
|
|
|
// 27.9.1.3 Assign/swap:
|
|
|
|
basic_filebuf& operator=(basic_filebuf&& rhs);
|
|
|
|
void swap(basic_filebuf& rhs);
|
|
|
|
|
|
|
|
// 27.9.1.4 Members:
|
|
|
|
bool is_open() const;
|
|
|
|
basic_filebuf* open(const char* s, ios_base::openmode mode);
|
|
|
|
basic_filebuf* open(const string& s, ios_base::openmode mode);
|
Implement <filesystem>
This patch implements the <filesystem> header and uses that
to provide <experimental/filesystem>.
Unlike other standard headers, the symbols needed for <filesystem>
have not yet been placed in libc++.so. Instead they live in the
new libc++fs.a library. Users of filesystem are required to link this
library. (Also note that libc++experimental no longer contains the
definition of <experimental/filesystem>, which now requires linking libc++fs).
The reason for keeping <filesystem> out of the dylib for now is that
it's still somewhat experimental, and the possibility of requiring an
ABI breaking change is very real. In the future the symbols will likely
be moved into the dylib, or the dylib will be made to link libc++fs automagically).
Note that moving the symbols out of libc++experimental may break user builds
until they update to -lc++fs. This should be OK, because the experimental
library provides no stability guarantees. However, I plan on looking into
ways we can force libc++experimental to automagically link libc++fs.
In order to use a single implementation and set of tests for <filesystem>, it
has been placed in a special `__fs` namespace. This namespace is inline in
C++17 onward, but not before that. As such implementation is available
in C++11 onward, but no filesystem namespace is present "directly", and
as such name conflicts shouldn't occur in C++11 or C++14.
llvm-svn: 338093
2018-07-27 03:07:09 +00:00
|
|
|
basic_filebuf* open(const filesystem::path& p, ios_base::openmode mode); // C++17
|
2010-05-11 19:42:16 +00:00
|
|
|
basic_filebuf* close();
|
|
|
|
|
|
|
|
protected:
|
|
|
|
// 27.9.1.5 Overridden virtual functions:
|
|
|
|
virtual streamsize showmanyc();
|
|
|
|
virtual int_type underflow();
|
|
|
|
virtual int_type uflow();
|
|
|
|
virtual int_type pbackfail(int_type c = traits_type::eof());
|
|
|
|
virtual int_type overflow (int_type c = traits_type::eof());
|
|
|
|
virtual basic_streambuf<char_type, traits_type>* setbuf(char_type* s, streamsize n);
|
|
|
|
virtual pos_type seekoff(off_type off, ios_base::seekdir way,
|
|
|
|
ios_base::openmode which = ios_base::in | ios_base::out);
|
|
|
|
virtual pos_type seekpos(pos_type sp,
|
|
|
|
ios_base::openmode which = ios_base::in | ios_base::out);
|
|
|
|
virtual int sync();
|
|
|
|
virtual void imbue(const locale& loc);
|
|
|
|
};
|
|
|
|
|
|
|
|
template <class charT, class traits>
|
|
|
|
void
|
|
|
|
swap(basic_filebuf<charT, traits>& x, basic_filebuf<charT, traits>& y);
|
|
|
|
|
|
|
|
typedef basic_filebuf<char> filebuf;
|
|
|
|
typedef basic_filebuf<wchar_t> wfilebuf;
|
|
|
|
|
|
|
|
template <class charT, class traits = char_traits<charT> >
|
|
|
|
class basic_ifstream
|
|
|
|
: public basic_istream<charT,traits>
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
typedef charT char_type;
|
|
|
|
typedef traits traits_type;
|
|
|
|
typedef typename traits_type::int_type int_type;
|
|
|
|
typedef typename traits_type::pos_type pos_type;
|
|
|
|
typedef typename traits_type::off_type off_type;
|
2024-01-07 18:01:03 +02:00
|
|
|
using native_handle_type = typename basic_filebuf<charT, traits>::native_handle_type; // Since C++26
|
2010-05-11 19:42:16 +00:00
|
|
|
|
|
|
|
basic_ifstream();
|
|
|
|
explicit basic_ifstream(const char* s, ios_base::openmode mode = ios_base::in);
|
|
|
|
explicit basic_ifstream(const string& s, ios_base::openmode mode = ios_base::in);
|
2024-04-06 20:33:41 +08:00
|
|
|
template<class T>
|
|
|
|
explicit basic_ifstream(const T& s, ios_base::openmode mode = ios_base::in); // Since C++17
|
2010-05-11 19:42:16 +00:00
|
|
|
basic_ifstream(basic_ifstream&& rhs);
|
|
|
|
|
|
|
|
basic_ifstream& operator=(basic_ifstream&& rhs);
|
|
|
|
void swap(basic_ifstream& rhs);
|
|
|
|
|
|
|
|
basic_filebuf<char_type, traits_type>* rdbuf() const;
|
2024-01-07 18:01:03 +02:00
|
|
|
native_handle_type native_handle() const noexcept; // Since C++26
|
2010-05-11 19:42:16 +00:00
|
|
|
bool is_open() const;
|
|
|
|
void open(const char* s, ios_base::openmode mode = ios_base::in);
|
|
|
|
void open(const string& s, ios_base::openmode mode = ios_base::in);
|
Implement <filesystem>
This patch implements the <filesystem> header and uses that
to provide <experimental/filesystem>.
Unlike other standard headers, the symbols needed for <filesystem>
have not yet been placed in libc++.so. Instead they live in the
new libc++fs.a library. Users of filesystem are required to link this
library. (Also note that libc++experimental no longer contains the
definition of <experimental/filesystem>, which now requires linking libc++fs).
The reason for keeping <filesystem> out of the dylib for now is that
it's still somewhat experimental, and the possibility of requiring an
ABI breaking change is very real. In the future the symbols will likely
be moved into the dylib, or the dylib will be made to link libc++fs automagically).
Note that moving the symbols out of libc++experimental may break user builds
until they update to -lc++fs. This should be OK, because the experimental
library provides no stability guarantees. However, I plan on looking into
ways we can force libc++experimental to automagically link libc++fs.
In order to use a single implementation and set of tests for <filesystem>, it
has been placed in a special `__fs` namespace. This namespace is inline in
C++17 onward, but not before that. As such implementation is available
in C++11 onward, but no filesystem namespace is present "directly", and
as such name conflicts shouldn't occur in C++11 or C++14.
llvm-svn: 338093
2018-07-27 03:07:09 +00:00
|
|
|
void open(const filesystem::path& s, ios_base::openmode mode = ios_base::in); // C++17
|
|
|
|
|
2010-05-11 19:42:16 +00:00
|
|
|
void close();
|
|
|
|
};
|
|
|
|
|
|
|
|
template <class charT, class traits>
|
|
|
|
void
|
|
|
|
swap(basic_ifstream<charT, traits>& x, basic_ifstream<charT, traits>& y);
|
|
|
|
|
|
|
|
typedef basic_ifstream<char> ifstream;
|
|
|
|
typedef basic_ifstream<wchar_t> wifstream;
|
|
|
|
|
|
|
|
template <class charT, class traits = char_traits<charT> >
|
|
|
|
class basic_ofstream
|
|
|
|
: public basic_ostream<charT,traits>
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
typedef charT char_type;
|
|
|
|
typedef traits traits_type;
|
|
|
|
typedef typename traits_type::int_type int_type;
|
|
|
|
typedef typename traits_type::pos_type pos_type;
|
|
|
|
typedef typename traits_type::off_type off_type;
|
2024-01-07 18:01:03 +02:00
|
|
|
using native_handle_type = typename basic_filebuf<charT, traits>::native_handle_type; // Since C++26
|
2010-05-11 19:42:16 +00:00
|
|
|
|
|
|
|
basic_ofstream();
|
|
|
|
explicit basic_ofstream(const char* s, ios_base::openmode mode = ios_base::out);
|
|
|
|
explicit basic_ofstream(const string& s, ios_base::openmode mode = ios_base::out);
|
2024-04-06 20:33:41 +08:00
|
|
|
template<class T>
|
|
|
|
explicit basic_ofstream(const T& s, ios_base::openmode mode = ios_base::out); // Since C++17
|
2010-05-11 19:42:16 +00:00
|
|
|
basic_ofstream(basic_ofstream&& rhs);
|
|
|
|
|
|
|
|
basic_ofstream& operator=(basic_ofstream&& rhs);
|
|
|
|
void swap(basic_ofstream& rhs);
|
|
|
|
|
|
|
|
basic_filebuf<char_type, traits_type>* rdbuf() const;
|
2024-01-07 18:01:03 +02:00
|
|
|
native_handle_type native_handle() const noexcept; // Since C++26
|
|
|
|
|
2010-05-11 19:42:16 +00:00
|
|
|
bool is_open() const;
|
|
|
|
void open(const char* s, ios_base::openmode mode = ios_base::out);
|
|
|
|
void open(const string& s, ios_base::openmode mode = ios_base::out);
|
Implement <filesystem>
This patch implements the <filesystem> header and uses that
to provide <experimental/filesystem>.
Unlike other standard headers, the symbols needed for <filesystem>
have not yet been placed in libc++.so. Instead they live in the
new libc++fs.a library. Users of filesystem are required to link this
library. (Also note that libc++experimental no longer contains the
definition of <experimental/filesystem>, which now requires linking libc++fs).
The reason for keeping <filesystem> out of the dylib for now is that
it's still somewhat experimental, and the possibility of requiring an
ABI breaking change is very real. In the future the symbols will likely
be moved into the dylib, or the dylib will be made to link libc++fs automagically).
Note that moving the symbols out of libc++experimental may break user builds
until they update to -lc++fs. This should be OK, because the experimental
library provides no stability guarantees. However, I plan on looking into
ways we can force libc++experimental to automagically link libc++fs.
In order to use a single implementation and set of tests for <filesystem>, it
has been placed in a special `__fs` namespace. This namespace is inline in
C++17 onward, but not before that. As such implementation is available
in C++11 onward, but no filesystem namespace is present "directly", and
as such name conflicts shouldn't occur in C++11 or C++14.
llvm-svn: 338093
2018-07-27 03:07:09 +00:00
|
|
|
void open(const filesystem::path& p,
|
|
|
|
ios_base::openmode mode = ios_base::out); // C++17
|
|
|
|
|
2010-05-11 19:42:16 +00:00
|
|
|
void close();
|
|
|
|
};
|
|
|
|
|
2010-08-22 00:02:43 +00:00
|
|
|
template <class charT, class traits>
|
2010-05-11 19:42:16 +00:00
|
|
|
void
|
|
|
|
swap(basic_ofstream<charT, traits>& x, basic_ofstream<charT, traits>& y);
|
|
|
|
|
|
|
|
typedef basic_ofstream<char> ofstream;
|
|
|
|
typedef basic_ofstream<wchar_t> wofstream;
|
|
|
|
|
|
|
|
template <class charT, class traits=char_traits<charT> >
|
|
|
|
class basic_fstream
|
|
|
|
: public basic_iostream<charT,traits>
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
typedef charT char_type;
|
|
|
|
typedef traits traits_type;
|
|
|
|
typedef typename traits_type::int_type int_type;
|
|
|
|
typedef typename traits_type::pos_type pos_type;
|
|
|
|
typedef typename traits_type::off_type off_type;
|
2024-01-07 18:01:03 +02:00
|
|
|
using native_handle_type = typename basic_filebuf<charT, traits>::native_handle_type; // Since C++26
|
2010-05-11 19:42:16 +00:00
|
|
|
|
|
|
|
basic_fstream();
|
|
|
|
explicit basic_fstream(const char* s, ios_base::openmode mode = ios_base::in|ios_base::out);
|
|
|
|
explicit basic_fstream(const string& s, ios_base::openmode mode = ios_base::in|ios_base::out);
|
2024-04-06 20:33:41 +08:00
|
|
|
template<class T>
|
|
|
|
explicit basic_fstream(const T& s, ios_base::openmode mode = ios_base::in | ios_base::out); // Since C++17
|
2010-05-11 19:42:16 +00:00
|
|
|
basic_fstream(basic_fstream&& rhs);
|
|
|
|
|
|
|
|
basic_fstream& operator=(basic_fstream&& rhs);
|
|
|
|
void swap(basic_fstream& rhs);
|
|
|
|
|
|
|
|
basic_filebuf<char_type, traits_type>* rdbuf() const;
|
2024-01-07 18:01:03 +02:00
|
|
|
native_handle_type native_handle() const noexcept; // Since C++26
|
2010-05-11 19:42:16 +00:00
|
|
|
bool is_open() const;
|
|
|
|
void open(const char* s, ios_base::openmode mode = ios_base::in|ios_base::out);
|
|
|
|
void open(const string& s, ios_base::openmode mode = ios_base::in|ios_base::out);
|
Implement <filesystem>
This patch implements the <filesystem> header and uses that
to provide <experimental/filesystem>.
Unlike other standard headers, the symbols needed for <filesystem>
have not yet been placed in libc++.so. Instead they live in the
new libc++fs.a library. Users of filesystem are required to link this
library. (Also note that libc++experimental no longer contains the
definition of <experimental/filesystem>, which now requires linking libc++fs).
The reason for keeping <filesystem> out of the dylib for now is that
it's still somewhat experimental, and the possibility of requiring an
ABI breaking change is very real. In the future the symbols will likely
be moved into the dylib, or the dylib will be made to link libc++fs automagically).
Note that moving the symbols out of libc++experimental may break user builds
until they update to -lc++fs. This should be OK, because the experimental
library provides no stability guarantees. However, I plan on looking into
ways we can force libc++experimental to automagically link libc++fs.
In order to use a single implementation and set of tests for <filesystem>, it
has been placed in a special `__fs` namespace. This namespace is inline in
C++17 onward, but not before that. As such implementation is available
in C++11 onward, but no filesystem namespace is present "directly", and
as such name conflicts shouldn't occur in C++11 or C++14.
llvm-svn: 338093
2018-07-27 03:07:09 +00:00
|
|
|
void open(const filesystem::path& s,
|
|
|
|
ios_base::openmode mode = ios_base::in|ios_base::out); // C++17
|
|
|
|
|
2010-05-11 19:42:16 +00:00
|
|
|
void close();
|
|
|
|
};
|
|
|
|
|
|
|
|
template <class charT, class traits>
|
|
|
|
void swap(basic_fstream<charT, traits>& x, basic_fstream<charT, traits>& y);
|
|
|
|
|
|
|
|
typedef basic_fstream<char> fstream;
|
|
|
|
typedef basic_fstream<wchar_t> wfstream;
|
|
|
|
|
|
|
|
} // std
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
2022-02-15 18:18:08 +01:00
|
|
|
#include <__algorithm/max.h>
|
2024-02-29 10:12:22 -05:00
|
|
|
#include <__assert>
|
2021-05-19 11:57:04 -04:00
|
|
|
#include <__config>
|
2024-09-16 15:06:20 -04:00
|
|
|
#include <__filesystem/path.h>
|
2023-04-20 21:03:40 +02:00
|
|
|
#include <__fwd/fstream.h>
|
2010-05-11 19:42:16 +00:00
|
|
|
#include <__locale>
|
2024-08-06 19:47:56 +02:00
|
|
|
#include <__memory/addressof.h>
|
2024-04-06 20:33:41 +08:00
|
|
|
#include <__type_traits/enable_if.h>
|
|
|
|
#include <__type_traits/is_same.h>
|
2022-03-05 19:17:07 +01:00
|
|
|
#include <__utility/move.h>
|
|
|
|
#include <__utility/swap.h>
|
2022-02-14 18:26:02 +01:00
|
|
|
#include <__utility/unreachable.h>
|
2010-05-11 19:42:16 +00:00
|
|
|
#include <cstdio>
|
2021-05-12 23:04:03 -04:00
|
|
|
#include <istream>
|
|
|
|
#include <ostream>
|
2022-09-05 00:01:15 +02:00
|
|
|
#include <typeinfo>
|
2021-12-22 18:14:14 +01:00
|
|
|
#include <version>
|
2021-01-18 12:18:18 -05:00
|
|
|
|
2011-10-17 20:05:10 +00:00
|
|
|
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
2022-02-01 20:16:40 -05:00
|
|
|
# pragma GCC system_header
|
2011-10-17 20:05:10 +00:00
|
|
|
#endif
|
2010-05-11 19:42:16 +00:00
|
|
|
|
2017-05-31 22:07:49 +00:00
|
|
|
_LIBCPP_PUSH_MACROS
|
|
|
|
#include <__undef_macros>
|
|
|
|
|
2024-10-12 09:49:52 +02:00
|
|
|
#if !defined(_LIBCPP_MSVCRT) && !defined(_NEWLIB_VERSION)
|
|
|
|
# define _LIBCPP_HAS_OFF_T_FUNCTIONS 1
|
|
|
|
#else
|
|
|
|
# define _LIBCPP_HAS_OFF_T_FUNCTIONS 0
|
2021-04-12 14:19:51 -04:00
|
|
|
#endif
|
2017-05-31 22:07:49 +00:00
|
|
|
|
2024-11-06 10:39:19 +01:00
|
|
|
#if _LIBCPP_HAS_FILESYSTEM && _LIBCPP_HAS_LOCALIZATION
|
2022-11-18 15:01:33 -05:00
|
|
|
|
2010-05-11 19:42:16 +00:00
|
|
|
_LIBCPP_BEGIN_NAMESPACE_STD
|
|
|
|
|
2024-01-07 18:01:03 +02:00
|
|
|
# if _LIBCPP_STD_VER >= 26 && defined(_LIBCPP_WIN32API)
|
|
|
|
_LIBCPP_EXPORTED_FROM_ABI void* __filebuf_windows_native_handle(FILE* __file) noexcept;
|
|
|
|
# endif
|
|
|
|
|
2010-05-11 19:42:16 +00:00
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
class _LIBCPP_TEMPLATE_VIS basic_filebuf : public basic_streambuf<_CharT, _Traits> {
|
|
|
|
public:
|
|
|
|
typedef _CharT char_type;
|
|
|
|
typedef _Traits traits_type;
|
|
|
|
typedef typename traits_type::int_type int_type;
|
|
|
|
typedef typename traits_type::pos_type pos_type;
|
|
|
|
typedef typename traits_type::off_type off_type;
|
|
|
|
typedef typename traits_type::state_type state_type;
|
2024-01-07 18:01:03 +02:00
|
|
|
# if _LIBCPP_STD_VER >= 26
|
|
|
|
# if defined(_LIBCPP_WIN32API)
|
|
|
|
using native_handle_type = void*; // HANDLE
|
|
|
|
# elif __has_include(<unistd.h>)
|
|
|
|
using native_handle_type = int; // POSIX file descriptor
|
|
|
|
# else
|
|
|
|
# error "Provide a native file handle!"
|
|
|
|
# endif
|
|
|
|
# endif
|
2023-12-18 14:01:33 -05:00
|
|
|
|
2010-05-11 19:42:16 +00:00
|
|
|
// 27.9.1.2 Constructors/destructor:
|
|
|
|
basic_filebuf();
|
|
|
|
basic_filebuf(basic_filebuf&& __rhs);
|
2022-08-24 02:14:29 +02:00
|
|
|
~basic_filebuf() override;
|
2023-12-18 14:01:33 -05:00
|
|
|
|
2010-05-11 19:42:16 +00:00
|
|
|
// 27.9.1.3 Assign/swap:
|
|
|
|
_LIBCPP_HIDE_FROM_ABI basic_filebuf& operator=(basic_filebuf&& __rhs);
|
|
|
|
void swap(basic_filebuf& __rhs);
|
2023-12-18 14:01:33 -05:00
|
|
|
|
2010-05-11 19:42:16 +00:00
|
|
|
// 27.9.1.4 Members:
|
|
|
|
_LIBCPP_HIDE_FROM_ABI bool is_open() const;
|
|
|
|
basic_filebuf* open(const char* __s, ios_base::openmode __mode);
|
2024-10-12 09:49:52 +02:00
|
|
|
# if _LIBCPP_HAS_OPEN_WITH_WCHAR
|
2018-01-23 02:07:27 +00:00
|
|
|
basic_filebuf* open(const wchar_t* __s, ios_base::openmode __mode);
|
|
|
|
# endif
|
2010-05-11 19:42:16 +00:00
|
|
|
_LIBCPP_HIDE_FROM_ABI basic_filebuf* open(const string& __s, ios_base::openmode __mode);
|
2023-12-18 14:01:33 -05:00
|
|
|
|
2023-05-31 11:20:24 -07:00
|
|
|
# if _LIBCPP_STD_VER >= 17
|
2023-06-05 08:20:39 -07:00
|
|
|
_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_HIDE_FROM_ABI basic_filebuf*
|
2023-11-28 18:41:59 -05:00
|
|
|
open(const filesystem::path& __p, ios_base::openmode __mode) {
|
Implement <filesystem>
This patch implements the <filesystem> header and uses that
to provide <experimental/filesystem>.
Unlike other standard headers, the symbols needed for <filesystem>
have not yet been placed in libc++.so. Instead they live in the
new libc++fs.a library. Users of filesystem are required to link this
library. (Also note that libc++experimental no longer contains the
definition of <experimental/filesystem>, which now requires linking libc++fs).
The reason for keeping <filesystem> out of the dylib for now is that
it's still somewhat experimental, and the possibility of requiring an
ABI breaking change is very real. In the future the symbols will likely
be moved into the dylib, or the dylib will be made to link libc++fs automagically).
Note that moving the symbols out of libc++experimental may break user builds
until they update to -lc++fs. This should be OK, because the experimental
library provides no stability guarantees. However, I plan on looking into
ways we can force libc++experimental to automagically link libc++fs.
In order to use a single implementation and set of tests for <filesystem>, it
has been placed in a special `__fs` namespace. This namespace is inline in
C++17 onward, but not before that. As such implementation is available
in C++11 onward, but no filesystem namespace is present "directly", and
as such name conflicts shouldn't occur in C++11 or C++14.
llvm-svn: 338093
2018-07-27 03:07:09 +00:00
|
|
|
return open(__p.c_str(), __mode);
|
|
|
|
}
|
|
|
|
# endif
|
2018-07-22 02:00:53 +00:00
|
|
|
_LIBCPP_HIDE_FROM_ABI basic_filebuf* __open(int __fd, ios_base::openmode __mode);
|
2010-05-11 19:42:16 +00:00
|
|
|
basic_filebuf* close();
|
2024-01-07 18:01:03 +02:00
|
|
|
# if _LIBCPP_STD_VER >= 26
|
|
|
|
_LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() const noexcept {
|
|
|
|
_LIBCPP_ASSERT_UNCATEGORIZED(this->is_open(), "File must be opened");
|
|
|
|
# if defined(_LIBCPP_WIN32API)
|
|
|
|
return std::__filebuf_windows_native_handle(__file_);
|
|
|
|
# elif __has_include(<unistd.h>)
|
|
|
|
return fileno(__file_);
|
|
|
|
# else
|
|
|
|
# error "Provide a way to determine the file native handle!"
|
|
|
|
# endif
|
|
|
|
}
|
|
|
|
# endif // _LIBCPP_STD_VER >= 26
|
2010-05-11 19:42:16 +00:00
|
|
|
|
2018-07-22 02:00:53 +00:00
|
|
|
_LIBCPP_HIDE_FROM_ABI inline static const char* __make_mdstring(ios_base::openmode __mode) _NOEXCEPT;
|
2024-10-12 09:49:52 +02:00
|
|
|
# if _LIBCPP_HAS_OPEN_WITH_WCHAR
|
2024-03-03 13:23:41 +01:00
|
|
|
_LIBCPP_HIDE_FROM_ABI inline static const wchar_t* __make_mdwstring(ios_base::openmode __mode) _NOEXCEPT;
|
|
|
|
# endif
|
2018-07-22 02:00:53 +00:00
|
|
|
|
|
|
|
protected:
|
2010-05-11 19:42:16 +00:00
|
|
|
// 27.9.1.5 Overridden virtual functions:
|
2022-08-24 02:14:29 +02:00
|
|
|
int_type underflow() override;
|
|
|
|
int_type pbackfail(int_type __c = traits_type::eof()) override;
|
|
|
|
int_type overflow(int_type __c = traits_type::eof()) override;
|
|
|
|
basic_streambuf<char_type, traits_type>* setbuf(char_type* __s, streamsize __n) override;
|
|
|
|
pos_type
|
|
|
|
seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __wch = ios_base::in | ios_base::out) override;
|
|
|
|
pos_type seekpos(pos_type __sp, ios_base::openmode __wch = ios_base::in | ios_base::out) override;
|
|
|
|
int sync() override;
|
|
|
|
void imbue(const locale& __loc) override;
|
2010-05-11 19:42:16 +00:00
|
|
|
|
|
|
|
private:
|
2018-07-22 02:00:53 +00:00
|
|
|
char* __extbuf_;
|
|
|
|
const char* __extbufnext_;
|
|
|
|
const char* __extbufend_;
|
|
|
|
char __extbuf_min_[8];
|
|
|
|
size_t __ebs_;
|
|
|
|
char_type* __intbuf_;
|
|
|
|
size_t __ibs_;
|
|
|
|
FILE* __file_;
|
|
|
|
const codecvt<char_type, char, state_type>* __cv_;
|
|
|
|
state_type __st_;
|
|
|
|
state_type __st_last_;
|
|
|
|
ios_base::openmode __om_;
|
2024-03-14 17:55:05 +01:00
|
|
|
// There have been no file operations yet, which allows setting unbuffered
|
|
|
|
// I/O mode.
|
|
|
|
static const ios_base::openmode __no_io_operations = ios_base::trunc;
|
|
|
|
// Unbuffered I/O mode has been requested.
|
|
|
|
static const ios_base::openmode __use_unbuffered_io = ios_base::ate;
|
|
|
|
// Used to track the currently used mode and track whether the output should
|
|
|
|
// be unbuffered.
|
|
|
|
// [filebuf.virtuals]/12
|
|
|
|
// If setbuf(0, 0) is called on a stream before any I/O has occurred on
|
|
|
|
// that stream, the stream becomes unbuffered. Otherwise the results are
|
|
|
|
// implementation-defined.
|
|
|
|
// This allows calling setbuf(0, 0)
|
|
|
|
// - before opening a file,
|
|
|
|
// - after opening a file, before
|
|
|
|
// - a read
|
|
|
|
// - a write
|
|
|
|
// - a seek.
|
|
|
|
// Note that opening a file with ios_base::ate does a seek operation.
|
|
|
|
// Normally underflow, overflow, and sync change this flag to ios_base::in,
|
|
|
|
// ios_base_out, or 0.
|
|
|
|
//
|
|
|
|
// The ios_base::trunc and ios_base::ate flags are not used in __cm_. They
|
|
|
|
// are used to track the state of the unbuffered request. For readability
|
|
|
|
// they have the aliases __no_io_operations and __use_unbuffered_io
|
|
|
|
// respectively.
|
|
|
|
//
|
|
|
|
// The __no_io_operations and __use_unbuffered_io flags are used in the
|
|
|
|
// following way:
|
|
|
|
// - __no_io_operations is set upon construction to indicate the unbuffered
|
|
|
|
// state can be set.
|
|
|
|
// - When requesting unbuffered output:
|
|
|
|
// - If the file is open it sets the mode.
|
|
|
|
// - Else places a request by adding the __use_unbuffered_io flag.
|
|
|
|
// - When a file is opened it checks whether both __no_io_operations and
|
|
|
|
// __use_unbuffered_io are set. If so switches to unbuffered mode.
|
|
|
|
// - All file I/O operations change the mode effectively clearing the
|
|
|
|
// __no_io_operations and __use_unbuffered_io flags.
|
2018-07-22 02:00:53 +00:00
|
|
|
ios_base::openmode __cm_;
|
|
|
|
bool __owns_eb_;
|
|
|
|
bool __owns_ib_;
|
|
|
|
bool __always_noconv_;
|
|
|
|
|
|
|
|
bool __read_mode();
|
|
|
|
void __write_mode();
|
2023-12-19 19:32:17 +01:00
|
|
|
|
|
|
|
_LIBCPP_EXPORTED_FROM_ABI friend FILE* __get_ostream_file(ostream&);
|
2024-03-03 13:23:41 +01:00
|
|
|
|
|
|
|
// There are multiple (__)open function, they use different C-API open
|
|
|
|
// function. After that call these functions behave the same. This function
|
|
|
|
// does that part and determines the final return value.
|
|
|
|
_LIBCPP_HIDE_FROM_ABI basic_filebuf* __do_open(FILE* __file, ios_base::openmode __mode) {
|
|
|
|
__file_ = __file;
|
|
|
|
if (!__file_)
|
|
|
|
return nullptr;
|
|
|
|
|
|
|
|
__om_ = __mode;
|
2024-03-14 17:55:05 +01:00
|
|
|
if (__cm_ == (__no_io_operations | __use_unbuffered_io)) {
|
|
|
|
std::setbuf(__file_, nullptr);
|
|
|
|
__cm_ = 0;
|
|
|
|
}
|
|
|
|
|
2024-03-03 13:23:41 +01:00
|
|
|
if (__mode & ios_base::ate) {
|
2024-03-14 17:55:05 +01:00
|
|
|
__cm_ = 0;
|
2024-03-03 13:23:41 +01:00
|
|
|
if (fseek(__file_, 0, SEEK_END)) {
|
|
|
|
fclose(__file_);
|
|
|
|
__file_ = nullptr;
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return this;
|
|
|
|
}
|
2024-03-14 17:55:05 +01:00
|
|
|
|
|
|
|
// If the file is already open, switch to unbuffered mode. Otherwise, record
|
|
|
|
// the request to use unbuffered mode so that we use that mode when we
|
|
|
|
// eventually open the file.
|
|
|
|
_LIBCPP_HIDE_FROM_ABI void __request_unbuffered_mode(char_type* __s, streamsize __n) {
|
|
|
|
if (__cm_ == __no_io_operations && __s == nullptr && __n == 0) {
|
|
|
|
if (__file_) {
|
|
|
|
std::setbuf(__file_, nullptr);
|
|
|
|
__cm_ = 0;
|
|
|
|
} else {
|
|
|
|
__cm_ = __no_io_operations | __use_unbuffered_io;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2010-05-11 19:42:16 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
basic_filebuf<_CharT, _Traits>::basic_filebuf()
|
2020-11-24 12:53:53 -05:00
|
|
|
: __extbuf_(nullptr),
|
|
|
|
__extbufnext_(nullptr),
|
|
|
|
__extbufend_(nullptr),
|
2010-05-11 19:42:16 +00:00
|
|
|
__ebs_(0),
|
2020-11-24 12:53:53 -05:00
|
|
|
__intbuf_(nullptr),
|
2010-05-11 19:42:16 +00:00
|
|
|
__ibs_(0),
|
2020-11-24 12:53:53 -05:00
|
|
|
__file_(nullptr),
|
2012-08-24 16:52:47 +00:00
|
|
|
__cv_(nullptr),
|
2010-05-11 19:42:16 +00:00
|
|
|
__st_(),
|
2012-08-24 21:20:56 +00:00
|
|
|
__st_last_(),
|
2010-05-11 19:42:16 +00:00
|
|
|
__om_(0),
|
2024-03-14 17:55:05 +01:00
|
|
|
__cm_(__no_io_operations),
|
2010-05-11 19:42:16 +00:00
|
|
|
__owns_eb_(false),
|
|
|
|
__owns_ib_(false),
|
2012-08-24 16:52:47 +00:00
|
|
|
__always_noconv_(false) {
|
[libc++] Add custom clang-tidy checks
Reviewed By: #libc, ldionne
Spies: jwakely, beanz, smeenai, cfe-commits, tschuett, avogelsgesang, Mordante, sstefan1, libcxx-commits, ldionne, mgorny, arichardson, miyuki
Differential Revision: https://reviews.llvm.org/D131963
2022-08-13 22:33:12 +02:00
|
|
|
if (std::has_facet<codecvt<char_type, char, state_type> >(this->getloc())) {
|
|
|
|
__cv_ = &std::use_facet<codecvt<char_type, char, state_type> >(this->getloc());
|
2012-08-24 16:52:47 +00:00
|
|
|
__always_noconv_ = __cv_->always_noconv();
|
|
|
|
}
|
2020-11-24 12:53:53 -05:00
|
|
|
setbuf(nullptr, 4096);
|
2010-05-11 19:42:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
basic_filebuf<_CharT, _Traits>::basic_filebuf(basic_filebuf&& __rhs) : basic_streambuf<_CharT, _Traits>(__rhs) {
|
|
|
|
if (__rhs.__extbuf_ == __rhs.__extbuf_min_) {
|
|
|
|
__extbuf_ = __extbuf_min_;
|
|
|
|
__extbufnext_ = __extbuf_ + (__rhs.__extbufnext_ - __rhs.__extbuf_);
|
|
|
|
__extbufend_ = __extbuf_ + (__rhs.__extbufend_ - __rhs.__extbuf_);
|
2023-12-18 14:01:33 -05:00
|
|
|
} else {
|
2010-05-11 19:42:16 +00:00
|
|
|
__extbuf_ = __rhs.__extbuf_;
|
|
|
|
__extbufnext_ = __rhs.__extbufnext_;
|
|
|
|
__extbufend_ = __rhs.__extbufend_;
|
|
|
|
}
|
|
|
|
__ebs_ = __rhs.__ebs_;
|
|
|
|
__intbuf_ = __rhs.__intbuf_;
|
|
|
|
__ibs_ = __rhs.__ibs_;
|
|
|
|
__file_ = __rhs.__file_;
|
|
|
|
__cv_ = __rhs.__cv_;
|
|
|
|
__st_ = __rhs.__st_;
|
2012-08-24 21:20:56 +00:00
|
|
|
__st_last_ = __rhs.__st_last_;
|
2010-05-11 19:42:16 +00:00
|
|
|
__om_ = __rhs.__om_;
|
|
|
|
__cm_ = __rhs.__cm_;
|
|
|
|
__owns_eb_ = __rhs.__owns_eb_;
|
|
|
|
__owns_ib_ = __rhs.__owns_ib_;
|
|
|
|
__always_noconv_ = __rhs.__always_noconv_;
|
|
|
|
if (__rhs.pbase()) {
|
|
|
|
if (__rhs.pbase() == __rhs.__intbuf_)
|
|
|
|
this->setp(__intbuf_, __intbuf_ + (__rhs.epptr() - __rhs.pbase()));
|
|
|
|
else
|
|
|
|
this->setp((char_type*)__extbuf_, (char_type*)__extbuf_ + (__rhs.epptr() - __rhs.pbase()));
|
2017-09-12 15:00:43 +00:00
|
|
|
this->__pbump(__rhs.pptr() - __rhs.pbase());
|
2010-05-11 19:42:16 +00:00
|
|
|
} else if (__rhs.eback()) {
|
|
|
|
if (__rhs.eback() == __rhs.__intbuf_)
|
|
|
|
this->setg(__intbuf_, __intbuf_ + (__rhs.gptr() - __rhs.eback()), __intbuf_ + (__rhs.egptr() - __rhs.eback()));
|
|
|
|
else
|
2022-04-14 16:17:24 +02:00
|
|
|
this->setg((char_type*)__extbuf_,
|
|
|
|
(char_type*)__extbuf_ + (__rhs.gptr() - __rhs.eback()),
|
|
|
|
(char_type*)__extbuf_ + (__rhs.egptr() - __rhs.eback()));
|
2023-12-18 14:01:33 -05:00
|
|
|
}
|
2022-04-14 16:17:24 +02:00
|
|
|
__rhs.__extbuf_ = nullptr;
|
|
|
|
__rhs.__extbufnext_ = nullptr;
|
|
|
|
__rhs.__extbufend_ = nullptr;
|
2010-05-11 19:42:16 +00:00
|
|
|
__rhs.__ebs_ = 0;
|
|
|
|
__rhs.__intbuf_ = 0;
|
|
|
|
__rhs.__ibs_ = 0;
|
2022-04-14 16:17:24 +02:00
|
|
|
__rhs.__file_ = nullptr;
|
|
|
|
__rhs.__st_ = state_type();
|
2010-05-11 19:42:16 +00:00
|
|
|
__rhs.__st_last_ = state_type();
|
|
|
|
__rhs.__om_ = 0;
|
|
|
|
__rhs.__cm_ = 0;
|
|
|
|
__rhs.__owns_eb_ = false;
|
|
|
|
__rhs.__owns_ib_ = false;
|
2022-04-14 16:17:24 +02:00
|
|
|
__rhs.setg(0, 0, 0);
|
|
|
|
__rhs.setp(0, 0);
|
2023-12-18 14:01:33 -05:00
|
|
|
}
|
|
|
|
|
2022-04-14 16:17:24 +02:00
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
inline basic_filebuf<_CharT, _Traits>& basic_filebuf<_CharT, _Traits>::operator=(basic_filebuf&& __rhs) {
|
|
|
|
close();
|
|
|
|
swap(__rhs);
|
2012-10-13 02:03:45 +00:00
|
|
|
return *this;
|
2023-12-18 14:01:33 -05:00
|
|
|
}
|
|
|
|
|
2022-04-14 16:17:24 +02:00
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
basic_filebuf<_CharT, _Traits>::~basic_filebuf() {
|
2024-10-12 09:49:52 +02:00
|
|
|
# if _LIBCPP_HAS_EXCEPTIONS
|
2023-12-18 14:01:33 -05:00
|
|
|
try {
|
2024-10-12 09:49:52 +02:00
|
|
|
# endif // _LIBCPP_HAS_EXCEPTIONS
|
2023-12-18 14:01:33 -05:00
|
|
|
close();
|
2024-10-12 09:49:52 +02:00
|
|
|
# if _LIBCPP_HAS_EXCEPTIONS
|
2010-05-11 19:42:16 +00:00
|
|
|
} catch (...) {
|
2023-12-18 14:01:33 -05:00
|
|
|
}
|
2024-10-12 09:49:52 +02:00
|
|
|
# endif // _LIBCPP_HAS_EXCEPTIONS
|
2010-05-11 19:42:16 +00:00
|
|
|
if (__owns_eb_)
|
|
|
|
delete[] __extbuf_;
|
2011-06-30 21:18:19 +00:00
|
|
|
if (__owns_ib_)
|
|
|
|
delete[] __intbuf_;
|
2023-12-18 14:01:33 -05:00
|
|
|
}
|
|
|
|
|
2011-06-30 21:18:19 +00:00
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
void basic_filebuf<_CharT, _Traits>::swap(basic_filebuf& __rhs) {
|
2012-08-24 21:20:56 +00:00
|
|
|
basic_streambuf<char_type, traits_type>::swap(__rhs);
|
2011-06-30 21:18:19 +00:00
|
|
|
if (__extbuf_ != __extbuf_min_ && __rhs.__extbuf_ != __rhs.__extbuf_min_) {
|
|
|
|
// Neither *this nor __rhs uses the small buffer, so we can simply swap the pointers.
|
|
|
|
std::swap(__extbuf_, __rhs.__extbuf_);
|
|
|
|
std::swap(__extbufnext_, __rhs.__extbufnext_);
|
2010-05-11 19:42:16 +00:00
|
|
|
std::swap(__extbufend_, __rhs.__extbufend_);
|
|
|
|
} else {
|
|
|
|
ptrdiff_t __ln = __extbufnext_ ? __extbufnext_ - __extbuf_ : 0;
|
|
|
|
ptrdiff_t __le = __extbufend_ ? __extbufend_ - __extbuf_ : 0;
|
|
|
|
ptrdiff_t __rn = __rhs.__extbufnext_ ? __rhs.__extbufnext_ - __rhs.__extbuf_ : 0;
|
|
|
|
ptrdiff_t __re = __rhs.__extbufend_ ? __rhs.__extbufend_ - __rhs.__extbuf_ : 0;
|
|
|
|
if (__extbuf_ == __extbuf_min_ && __rhs.__extbuf_ != __rhs.__extbuf_min_) {
|
|
|
|
// *this uses the small buffer, but __rhs doesn't.
|
|
|
|
__extbuf_ = __rhs.__extbuf_;
|
|
|
|
__rhs.__extbuf_ = __rhs.__extbuf_min_;
|
|
|
|
std::memmove(__rhs.__extbuf_min_, __extbuf_min_, sizeof(__extbuf_min_));
|
|
|
|
} else if (__extbuf_ != __extbuf_min_ && __rhs.__extbuf_ == __rhs.__extbuf_min_) {
|
|
|
|
// *this doesn't use the small buffer, but __rhs does.
|
|
|
|
__rhs.__extbuf_ = __extbuf_;
|
|
|
|
__extbuf_ = __extbuf_min_;
|
|
|
|
std::memmove(__extbuf_min_, __rhs.__extbuf_min_, sizeof(__extbuf_min_));
|
2023-12-18 14:01:33 -05:00
|
|
|
} else {
|
2010-05-11 19:42:16 +00:00
|
|
|
// Both *this and __rhs use the small buffer.
|
|
|
|
char __tmp[sizeof(__extbuf_min_)];
|
2022-04-14 16:17:24 +02:00
|
|
|
std::memmove(__tmp, __extbuf_min_, sizeof(__extbuf_min_));
|
2010-05-11 19:42:16 +00:00
|
|
|
std::memmove(__extbuf_min_, __rhs.__extbuf_min_, sizeof(__extbuf_min_));
|
|
|
|
std::memmove(__rhs.__extbuf_min_, __tmp, sizeof(__extbuf_min_));
|
|
|
|
}
|
|
|
|
__extbufnext_ = __extbuf_ + __rn;
|
|
|
|
__extbufend_ = __extbuf_ + __re;
|
|
|
|
__rhs.__extbufnext_ = __rhs.__extbuf_ + __ln;
|
2022-04-14 16:17:24 +02:00
|
|
|
__rhs.__extbufend_ = __rhs.__extbuf_ + __le;
|
2023-12-18 14:01:33 -05:00
|
|
|
}
|
2011-06-30 21:18:19 +00:00
|
|
|
std::swap(__ebs_, __rhs.__ebs_);
|
2022-04-14 16:17:24 +02:00
|
|
|
std::swap(__intbuf_, __rhs.__intbuf_);
|
2011-06-30 21:18:19 +00:00
|
|
|
std::swap(__ibs_, __rhs.__ibs_);
|
|
|
|
std::swap(__file_, __rhs.__file_);
|
2022-04-14 16:17:24 +02:00
|
|
|
std::swap(__cv_, __rhs.__cv_);
|
2011-06-30 21:18:19 +00:00
|
|
|
std::swap(__st_, __rhs.__st_);
|
|
|
|
std::swap(__st_last_, __rhs.__st_last_);
|
|
|
|
std::swap(__om_, __rhs.__om_);
|
|
|
|
std::swap(__cm_, __rhs.__cm_);
|
|
|
|
std::swap(__owns_eb_, __rhs.__owns_eb_);
|
|
|
|
std::swap(__owns_ib_, __rhs.__owns_ib_);
|
2010-05-11 19:42:16 +00:00
|
|
|
std::swap(__always_noconv_, __rhs.__always_noconv_);
|
|
|
|
if (this->eback() == (char_type*)__rhs.__extbuf_min_) {
|
|
|
|
ptrdiff_t __n = this->gptr() - this->eback();
|
|
|
|
ptrdiff_t __e = this->egptr() - this->eback();
|
2019-03-20 14:34:00 +00:00
|
|
|
this->setg((char_type*)__extbuf_min_, (char_type*)__extbuf_min_ + __n, (char_type*)__extbuf_min_ + __e);
|
2010-05-11 19:42:16 +00:00
|
|
|
} else if (this->pbase() == (char_type*)__rhs.__extbuf_min_) {
|
|
|
|
ptrdiff_t __n = this->pptr() - this->pbase();
|
|
|
|
ptrdiff_t __e = this->epptr() - this->pbase();
|
2019-03-20 14:34:00 +00:00
|
|
|
this->setp((char_type*)__extbuf_min_, (char_type*)__extbuf_min_ + __e);
|
2017-09-12 15:00:43 +00:00
|
|
|
this->__pbump(__n);
|
2023-12-18 14:01:33 -05:00
|
|
|
}
|
2010-05-11 19:42:16 +00:00
|
|
|
if (__rhs.eback() == (char_type*)__extbuf_min_) {
|
|
|
|
ptrdiff_t __n = __rhs.gptr() - __rhs.eback();
|
|
|
|
ptrdiff_t __e = __rhs.egptr() - __rhs.eback();
|
|
|
|
__rhs.setg(
|
|
|
|
(char_type*)__rhs.__extbuf_min_, (char_type*)__rhs.__extbuf_min_ + __n, (char_type*)__rhs.__extbuf_min_ + __e);
|
|
|
|
} else if (__rhs.pbase() == (char_type*)__extbuf_min_) {
|
|
|
|
ptrdiff_t __n = __rhs.pptr() - __rhs.pbase();
|
|
|
|
ptrdiff_t __e = __rhs.epptr() - __rhs.pbase();
|
2019-03-20 14:34:00 +00:00
|
|
|
__rhs.setp((char_type*)__rhs.__extbuf_min_, (char_type*)__rhs.__extbuf_min_ + __e);
|
2017-09-12 15:00:43 +00:00
|
|
|
__rhs.__pbump(__n);
|
2023-12-18 14:01:33 -05:00
|
|
|
}
|
2010-05-11 19:42:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
inline _LIBCPP_HIDE_FROM_ABI void swap(basic_filebuf<_CharT, _Traits>& __x, basic_filebuf<_CharT, _Traits>& __y) {
|
|
|
|
__x.swap(__y);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
inline bool basic_filebuf<_CharT, _Traits>::is_open() const {
|
2020-11-24 12:53:53 -05:00
|
|
|
return __file_ != nullptr;
|
2010-05-11 19:42:16 +00:00
|
|
|
}
|
|
|
|
|
2018-07-22 02:00:53 +00:00
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
const char* basic_filebuf<_CharT, _Traits>::__make_mdstring(ios_base::openmode __mode) _NOEXCEPT {
|
|
|
|
switch (__mode & ~ios_base::ate) {
|
|
|
|
case ios_base::out:
|
|
|
|
case ios_base::out | ios_base::trunc:
|
2019-09-16 19:26:41 +00:00
|
|
|
return "w" _LIBCPP_FOPEN_CLOEXEC_MODE;
|
2018-07-22 02:00:53 +00:00
|
|
|
case ios_base::out | ios_base::app:
|
|
|
|
case ios_base::app:
|
2019-09-16 19:26:41 +00:00
|
|
|
return "a" _LIBCPP_FOPEN_CLOEXEC_MODE;
|
2018-07-22 02:00:53 +00:00
|
|
|
case ios_base::in:
|
2019-09-16 19:26:41 +00:00
|
|
|
return "r" _LIBCPP_FOPEN_CLOEXEC_MODE;
|
2018-07-22 02:00:53 +00:00
|
|
|
case ios_base::in | ios_base::out:
|
2019-09-16 19:26:41 +00:00
|
|
|
return "r+" _LIBCPP_FOPEN_CLOEXEC_MODE;
|
2018-07-22 02:00:53 +00:00
|
|
|
case ios_base::in | ios_base::out | ios_base::trunc:
|
2019-09-16 19:26:41 +00:00
|
|
|
return "w+" _LIBCPP_FOPEN_CLOEXEC_MODE;
|
2018-07-22 02:00:53 +00:00
|
|
|
case ios_base::in | ios_base::out | ios_base::app:
|
|
|
|
case ios_base::in | ios_base::app:
|
2019-09-16 19:26:41 +00:00
|
|
|
return "a+" _LIBCPP_FOPEN_CLOEXEC_MODE;
|
2018-07-22 02:00:53 +00:00
|
|
|
case ios_base::out | ios_base::binary:
|
|
|
|
case ios_base::out | ios_base::trunc | ios_base::binary:
|
2019-09-16 19:26:41 +00:00
|
|
|
return "wb" _LIBCPP_FOPEN_CLOEXEC_MODE;
|
2018-07-22 02:00:53 +00:00
|
|
|
case ios_base::out | ios_base::app | ios_base::binary:
|
|
|
|
case ios_base::app | ios_base::binary:
|
2019-09-16 19:26:41 +00:00
|
|
|
return "ab" _LIBCPP_FOPEN_CLOEXEC_MODE;
|
2018-07-22 02:00:53 +00:00
|
|
|
case ios_base::in | ios_base::binary:
|
2019-09-16 19:26:41 +00:00
|
|
|
return "rb" _LIBCPP_FOPEN_CLOEXEC_MODE;
|
2018-07-22 02:00:53 +00:00
|
|
|
case ios_base::in | ios_base::out | ios_base::binary:
|
2019-09-16 19:26:41 +00:00
|
|
|
return "r+b" _LIBCPP_FOPEN_CLOEXEC_MODE;
|
2018-07-22 02:00:53 +00:00
|
|
|
case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary:
|
2019-09-16 19:26:41 +00:00
|
|
|
return "w+b" _LIBCPP_FOPEN_CLOEXEC_MODE;
|
2018-07-22 02:00:53 +00:00
|
|
|
case ios_base::in | ios_base::out | ios_base::app | ios_base::binary:
|
|
|
|
case ios_base::in | ios_base::app | ios_base::binary:
|
2019-09-16 19:26:41 +00:00
|
|
|
return "a+b" _LIBCPP_FOPEN_CLOEXEC_MODE;
|
2023-09-18 16:32:02 -04:00
|
|
|
# if _LIBCPP_STD_VER >= 23
|
|
|
|
case ios_base::out | ios_base::noreplace:
|
|
|
|
case ios_base::out | ios_base::trunc | ios_base::noreplace:
|
|
|
|
return "wx" _LIBCPP_FOPEN_CLOEXEC_MODE;
|
|
|
|
case ios_base::in | ios_base::out | ios_base::trunc | ios_base::noreplace:
|
|
|
|
return "w+x" _LIBCPP_FOPEN_CLOEXEC_MODE;
|
|
|
|
case ios_base::out | ios_base::binary | ios_base::noreplace:
|
|
|
|
case ios_base::out | ios_base::trunc | ios_base::binary | ios_base::noreplace:
|
|
|
|
return "wbx" _LIBCPP_FOPEN_CLOEXEC_MODE;
|
|
|
|
case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary | ios_base::noreplace:
|
|
|
|
return "w+bx" _LIBCPP_FOPEN_CLOEXEC_MODE;
|
|
|
|
# endif // _LIBCPP_STD_VER >= 23
|
2018-07-22 02:00:53 +00:00
|
|
|
default:
|
|
|
|
return nullptr;
|
|
|
|
}
|
2022-02-14 18:26:02 +01:00
|
|
|
__libcpp_unreachable();
|
2018-07-22 02:00:53 +00:00
|
|
|
}
|
|
|
|
|
2024-10-12 09:49:52 +02:00
|
|
|
# if _LIBCPP_HAS_OPEN_WITH_WCHAR
|
2010-05-11 19:42:16 +00:00
|
|
|
template <class _CharT, class _Traits>
|
2024-03-03 13:23:41 +01:00
|
|
|
const wchar_t* basic_filebuf<_CharT, _Traits>::__make_mdwstring(ios_base::openmode __mode) _NOEXCEPT {
|
|
|
|
switch (__mode & ~ios_base::ate) {
|
|
|
|
case ios_base::out:
|
|
|
|
case ios_base::out | ios_base::trunc:
|
|
|
|
return L"w";
|
|
|
|
case ios_base::out | ios_base::app:
|
|
|
|
case ios_base::app:
|
|
|
|
return L"a";
|
|
|
|
case ios_base::in:
|
|
|
|
return L"r";
|
|
|
|
case ios_base::in | ios_base::out:
|
|
|
|
return L"r+";
|
|
|
|
case ios_base::in | ios_base::out | ios_base::trunc:
|
|
|
|
return L"w+";
|
|
|
|
case ios_base::in | ios_base::out | ios_base::app:
|
|
|
|
case ios_base::in | ios_base::app:
|
|
|
|
return L"a+";
|
|
|
|
case ios_base::out | ios_base::binary:
|
|
|
|
case ios_base::out | ios_base::trunc | ios_base::binary:
|
|
|
|
return L"wb";
|
|
|
|
case ios_base::out | ios_base::app | ios_base::binary:
|
|
|
|
case ios_base::app | ios_base::binary:
|
|
|
|
return L"ab";
|
|
|
|
case ios_base::in | ios_base::binary:
|
|
|
|
return L"rb";
|
|
|
|
case ios_base::in | ios_base::out | ios_base::binary:
|
|
|
|
return L"r+b";
|
|
|
|
case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary:
|
|
|
|
return L"w+b";
|
|
|
|
case ios_base::in | ios_base::out | ios_base::app | ios_base::binary:
|
|
|
|
case ios_base::in | ios_base::app | ios_base::binary:
|
|
|
|
return L"a+b";
|
|
|
|
# if _LIBCPP_STD_VER >= 23
|
|
|
|
case ios_base::out | ios_base::noreplace:
|
|
|
|
case ios_base::out | ios_base::trunc | ios_base::noreplace:
|
|
|
|
return L"wx";
|
|
|
|
case ios_base::in | ios_base::out | ios_base::trunc | ios_base::noreplace:
|
|
|
|
return L"w+x";
|
|
|
|
case ios_base::out | ios_base::binary | ios_base::noreplace:
|
|
|
|
case ios_base::out | ios_base::trunc | ios_base::binary | ios_base::noreplace:
|
|
|
|
return L"wbx";
|
|
|
|
case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary | ios_base::noreplace:
|
|
|
|
return L"w+bx";
|
|
|
|
# endif // _LIBCPP_STD_VER >= 23
|
|
|
|
default:
|
|
|
|
return nullptr;
|
2023-12-18 14:01:33 -05:00
|
|
|
}
|
2024-03-03 13:23:41 +01:00
|
|
|
__libcpp_unreachable();
|
|
|
|
}
|
|
|
|
# endif
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
basic_filebuf<_CharT, _Traits>* basic_filebuf<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode) {
|
|
|
|
if (__file_)
|
|
|
|
return nullptr;
|
|
|
|
const char* __mdstr = __make_mdstring(__mode);
|
|
|
|
if (!__mdstr)
|
|
|
|
return nullptr;
|
|
|
|
|
|
|
|
return __do_open(fopen(__s, __mdstr), __mode);
|
2010-05-11 19:42:16 +00:00
|
|
|
}
|
|
|
|
|
2018-07-22 02:00:53 +00:00
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
inline basic_filebuf<_CharT, _Traits>* basic_filebuf<_CharT, _Traits>::__open(int __fd, ios_base::openmode __mode) {
|
2024-03-03 13:23:41 +01:00
|
|
|
if (__file_)
|
|
|
|
return nullptr;
|
|
|
|
const char* __mdstr = __make_mdstring(__mode);
|
|
|
|
if (!__mdstr)
|
|
|
|
return nullptr;
|
|
|
|
|
|
|
|
return __do_open(fdopen(__fd, __mdstr), __mode);
|
2018-07-22 02:00:53 +00:00
|
|
|
}
|
|
|
|
|
2024-10-12 09:49:52 +02:00
|
|
|
# if _LIBCPP_HAS_OPEN_WITH_WCHAR
|
2018-01-23 02:07:27 +00:00
|
|
|
// This is basically the same as the char* overload except that it uses _wfopen
|
|
|
|
// and long mode strings.
|
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
basic_filebuf<_CharT, _Traits>* basic_filebuf<_CharT, _Traits>::open(const wchar_t* __s, ios_base::openmode __mode) {
|
2024-03-03 13:23:41 +01:00
|
|
|
if (__file_)
|
|
|
|
return nullptr;
|
|
|
|
const wchar_t* __mdstr = __make_mdwstring(__mode);
|
|
|
|
if (!__mdstr)
|
|
|
|
return nullptr;
|
|
|
|
|
|
|
|
return __do_open(_wfopen(__s, __mdstr), __mode);
|
2018-01-23 02:07:27 +00:00
|
|
|
}
|
|
|
|
# endif
|
|
|
|
|
2010-05-11 19:42:16 +00:00
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
inline basic_filebuf<_CharT, _Traits>*
|
|
|
|
basic_filebuf<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode) {
|
|
|
|
return open(__s.c_str(), __mode);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
basic_filebuf<_CharT, _Traits>* basic_filebuf<_CharT, _Traits>::close() {
|
2020-11-24 12:53:53 -05:00
|
|
|
basic_filebuf<_CharT, _Traits>* __rt = nullptr;
|
2010-05-11 19:42:16 +00:00
|
|
|
if (__file_) {
|
|
|
|
__rt = this;
|
|
|
|
unique_ptr<FILE, int (*)(FILE*)> __h(__file_, fclose);
|
2012-01-12 23:37:51 +00:00
|
|
|
if (sync())
|
2020-11-24 12:53:53 -05:00
|
|
|
__rt = nullptr;
|
2019-07-22 19:54:34 +00:00
|
|
|
if (fclose(__h.release()))
|
2020-11-24 12:53:53 -05:00
|
|
|
__rt = nullptr;
|
|
|
|
__file_ = nullptr;
|
2019-01-08 02:48:45 +00:00
|
|
|
setbuf(0, 0);
|
2010-05-11 19:42:16 +00:00
|
|
|
}
|
|
|
|
return __rt;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
typename basic_filebuf<_CharT, _Traits>::int_type basic_filebuf<_CharT, _Traits>::underflow() {
|
2020-11-24 12:53:53 -05:00
|
|
|
if (__file_ == nullptr)
|
2010-05-11 19:42:16 +00:00
|
|
|
return traits_type::eof();
|
|
|
|
bool __initial = __read_mode();
|
2020-12-07 21:50:15 -05:00
|
|
|
char_type __1buf;
|
2010-05-11 19:42:16 +00:00
|
|
|
if (this->gptr() == nullptr)
|
[libc++] Add custom clang-tidy checks
Reviewed By: #libc, ldionne
Spies: jwakely, beanz, smeenai, cfe-commits, tschuett, avogelsgesang, Mordante, sstefan1, libcxx-commits, ldionne, mgorny, arichardson, miyuki
Differential Revision: https://reviews.llvm.org/D131963
2022-08-13 22:33:12 +02:00
|
|
|
this->setg(&__1buf, &__1buf + 1, &__1buf + 1);
|
2012-08-24 20:37:00 +00:00
|
|
|
const size_t __unget_sz = __initial ? 0 : std::min<size_t>((this->egptr() - this->eback()) / 2, 4);
|
2017-06-14 20:00:36 +00:00
|
|
|
int_type __c = traits_type::eof();
|
2010-05-11 19:42:16 +00:00
|
|
|
if (this->gptr() == this->egptr()) {
|
|
|
|
std::memmove(this->eback(), this->egptr() - __unget_sz, __unget_sz * sizeof(char_type));
|
|
|
|
if (__always_noconv_) {
|
|
|
|
size_t __nmemb = static_cast<size_t>(this->egptr() - this->eback() - __unget_sz);
|
|
|
|
__nmemb = ::fread(this->eback() + __unget_sz, 1, __nmemb, __file_);
|
|
|
|
if (__nmemb != 0) {
|
|
|
|
this->setg(this->eback(), this->eback() + __unget_sz, this->eback() + __unget_sz + __nmemb);
|
2011-02-02 17:37:16 +00:00
|
|
|
__c = traits_type::to_int_type(*this->gptr());
|
2023-12-18 14:01:33 -05:00
|
|
|
}
|
|
|
|
} else {
|
2010-05-11 19:42:16 +00:00
|
|
|
if (__extbufend_ != __extbufnext_) {
|
2020-11-24 12:53:53 -05:00
|
|
|
_LIBCPP_ASSERT_NON_NULL(__extbufnext_ != nullptr, "underflow moving from nullptr");
|
2010-05-11 19:42:16 +00:00
|
|
|
_LIBCPP_ASSERT_NON_NULL(__extbuf_ != nullptr, "underflow moving into nullptr");
|
|
|
|
std::memmove(__extbuf_, __extbufnext_, __extbufend_ - __extbufnext_);
|
2023-12-18 14:01:33 -05:00
|
|
|
}
|
2010-05-11 19:42:16 +00:00
|
|
|
__extbufnext_ = __extbuf_ + (__extbufend_ - __extbufnext_);
|
|
|
|
__extbufend_ = __extbuf_ + (__extbuf_ == __extbuf_min_ ? sizeof(__extbuf_min_) : __ebs_);
|
|
|
|
size_t __nmemb =
|
|
|
|
std::min(static_cast<size_t>(__ibs_ - __unget_sz), static_cast<size_t>(__extbufend_ - __extbufnext_));
|
|
|
|
codecvt_base::result __r;
|
2012-08-24 21:20:56 +00:00
|
|
|
__st_last_ = __st_;
|
2010-05-11 19:42:16 +00:00
|
|
|
size_t __nr = fread((void*)const_cast<char*>(__extbufnext_), 1, __nmemb, __file_);
|
|
|
|
if (__nr != 0) {
|
2012-08-24 16:52:47 +00:00
|
|
|
if (!__cv_)
|
2010-05-11 19:42:16 +00:00
|
|
|
__throw_bad_cast();
|
2023-12-18 14:01:33 -05:00
|
|
|
|
2010-05-11 19:42:16 +00:00
|
|
|
__extbufend_ = __extbufnext_ + __nr;
|
|
|
|
char_type* __inext;
|
|
|
|
__r = __cv_->in(
|
|
|
|
__st_, __extbuf_, __extbufend_, __extbufnext_, this->eback() + __unget_sz, this->eback() + __ibs_, __inext);
|
|
|
|
if (__r == codecvt_base::noconv) {
|
|
|
|
this->setg((char_type*)__extbuf_, (char_type*)__extbuf_, (char_type*)const_cast<char*>(__extbufend_));
|
|
|
|
__c = traits_type::to_int_type(*this->gptr());
|
|
|
|
} else if (__inext != this->eback() + __unget_sz) {
|
|
|
|
this->setg(this->eback(), this->eback() + __unget_sz, __inext);
|
|
|
|
__c = traits_type::to_int_type(*this->gptr());
|
|
|
|
}
|
2023-12-18 14:01:33 -05:00
|
|
|
}
|
2010-05-11 19:42:16 +00:00
|
|
|
}
|
2023-12-18 14:01:33 -05:00
|
|
|
} else
|
2010-05-11 19:42:16 +00:00
|
|
|
__c = traits_type::to_int_type(*this->gptr());
|
|
|
|
if (this->eback() == &__1buf)
|
2020-11-24 12:53:53 -05:00
|
|
|
this->setg(nullptr, nullptr, nullptr);
|
2010-05-11 19:42:16 +00:00
|
|
|
return __c;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
typename basic_filebuf<_CharT, _Traits>::int_type basic_filebuf<_CharT, _Traits>::pbackfail(int_type __c) {
|
2020-11-24 12:53:53 -05:00
|
|
|
if (__file_ && this->eback() < this->gptr()) {
|
2010-05-11 19:42:16 +00:00
|
|
|
if (traits_type::eq_int_type(__c, traits_type::eof())) {
|
|
|
|
this->gbump(-1);
|
|
|
|
return traits_type::not_eof(__c);
|
|
|
|
}
|
[libc++] Add custom clang-tidy checks
Reviewed By: #libc, ldionne
Spies: jwakely, beanz, smeenai, cfe-commits, tschuett, avogelsgesang, Mordante, sstefan1, libcxx-commits, ldionne, mgorny, arichardson, miyuki
Differential Revision: https://reviews.llvm.org/D131963
2022-08-13 22:33:12 +02:00
|
|
|
if ((__om_ & ios_base::out) || traits_type::eq(traits_type::to_char_type(__c), this->gptr()[-1])) {
|
2010-05-11 19:42:16 +00:00
|
|
|
this->gbump(-1);
|
2017-06-14 20:00:36 +00:00
|
|
|
*this->gptr() = traits_type::to_char_type(__c);
|
2010-05-11 19:42:16 +00:00
|
|
|
return __c;
|
|
|
|
}
|
2023-12-18 14:01:33 -05:00
|
|
|
}
|
2010-05-11 19:42:16 +00:00
|
|
|
return traits_type::eof();
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
typename basic_filebuf<_CharT, _Traits>::int_type basic_filebuf<_CharT, _Traits>::overflow(int_type __c) {
|
2020-11-24 12:53:53 -05:00
|
|
|
if (__file_ == nullptr)
|
|
|
|
return traits_type::eof();
|
2010-05-11 19:42:16 +00:00
|
|
|
__write_mode();
|
|
|
|
char_type __1buf;
|
2020-11-24 12:53:53 -05:00
|
|
|
char_type* __pb_save = this->pbase();
|
|
|
|
char_type* __epb_save = this->epptr();
|
2010-05-11 19:42:16 +00:00
|
|
|
if (!traits_type::eq_int_type(__c, traits_type::eof())) {
|
2020-11-24 12:53:53 -05:00
|
|
|
if (this->pptr() == nullptr)
|
2010-05-11 19:42:16 +00:00
|
|
|
this->setp(&__1buf, &__1buf + 1);
|
|
|
|
*this->pptr() = traits_type::to_char_type(__c);
|
|
|
|
this->pbump(1);
|
2023-12-18 14:01:33 -05:00
|
|
|
}
|
2010-05-11 19:42:16 +00:00
|
|
|
if (this->pptr() != this->pbase()) {
|
|
|
|
if (__always_noconv_) {
|
|
|
|
size_t __nmemb = static_cast<size_t>(this->pptr() - this->pbase());
|
|
|
|
if (std::fwrite(this->pbase(), sizeof(char_type), __nmemb, __file_) != __nmemb)
|
|
|
|
return traits_type::eof();
|
|
|
|
} else {
|
|
|
|
char* __extbe = __extbuf_;
|
|
|
|
codecvt_base::result __r;
|
2023-12-18 14:01:33 -05:00
|
|
|
do {
|
2012-08-24 16:52:47 +00:00
|
|
|
if (!__cv_)
|
2010-05-11 19:42:16 +00:00
|
|
|
__throw_bad_cast();
|
2023-12-18 14:01:33 -05:00
|
|
|
|
2010-05-11 19:42:16 +00:00
|
|
|
const char_type* __e;
|
|
|
|
__r = __cv_->out(__st_, this->pbase(), this->pptr(), __e, __extbuf_, __extbuf_ + __ebs_, __extbe);
|
|
|
|
if (__e == this->pbase())
|
|
|
|
return traits_type::eof();
|
|
|
|
if (__r == codecvt_base::noconv) {
|
|
|
|
size_t __nmemb = static_cast<size_t>(this->pptr() - this->pbase());
|
[libc++] Add custom clang-tidy checks
Reviewed By: #libc, ldionne
Spies: jwakely, beanz, smeenai, cfe-commits, tschuett, avogelsgesang, Mordante, sstefan1, libcxx-commits, ldionne, mgorny, arichardson, miyuki
Differential Revision: https://reviews.llvm.org/D131963
2022-08-13 22:33:12 +02:00
|
|
|
if (std::fwrite(this->pbase(), 1, __nmemb, __file_) != __nmemb)
|
2010-05-11 19:42:16 +00:00
|
|
|
return traits_type::eof();
|
|
|
|
} else if (__r == codecvt_base::ok || __r == codecvt_base::partial) {
|
|
|
|
size_t __nmemb = static_cast<size_t>(__extbe - __extbuf_);
|
|
|
|
if (fwrite(__extbuf_, 1, __nmemb, __file_) != __nmemb)
|
|
|
|
return traits_type::eof();
|
|
|
|
if (__r == codecvt_base::partial) {
|
|
|
|
this->setp(const_cast<char_type*>(__e), this->pptr());
|
2017-09-12 15:00:43 +00:00
|
|
|
this->__pbump(this->epptr() - this->pbase());
|
2023-12-18 14:01:33 -05:00
|
|
|
}
|
2010-05-11 19:42:16 +00:00
|
|
|
} else
|
|
|
|
return traits_type::eof();
|
|
|
|
} while (__r == codecvt_base::partial);
|
|
|
|
}
|
|
|
|
this->setp(__pb_save, __epb_save);
|
2023-12-18 14:01:33 -05:00
|
|
|
}
|
2010-05-11 19:42:16 +00:00
|
|
|
return traits_type::not_eof(__c);
|
2023-12-18 14:01:33 -05:00
|
|
|
}
|
|
|
|
|
2010-05-11 19:42:16 +00:00
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
basic_streambuf<_CharT, _Traits>* basic_filebuf<_CharT, _Traits>::setbuf(char_type* __s, streamsize __n) {
|
2020-11-24 12:53:53 -05:00
|
|
|
this->setg(nullptr, nullptr, nullptr);
|
|
|
|
this->setp(nullptr, nullptr);
|
2024-03-14 17:55:05 +01:00
|
|
|
__request_unbuffered_mode(__s, __n);
|
2010-05-11 19:42:16 +00:00
|
|
|
if (__owns_eb_)
|
|
|
|
delete[] __extbuf_;
|
|
|
|
if (__owns_ib_)
|
|
|
|
delete[] __intbuf_;
|
|
|
|
__ebs_ = __n;
|
2023-07-05 10:12:03 -04:00
|
|
|
if (__ebs_ > sizeof(__extbuf_min_)) {
|
|
|
|
if (__always_noconv_ && __s) {
|
2010-05-11 19:42:16 +00:00
|
|
|
__extbuf_ = (char*)__s;
|
|
|
|
__owns_eb_ = false;
|
|
|
|
} else {
|
|
|
|
__extbuf_ = new char[__ebs_];
|
|
|
|
__owns_eb_ = true;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
__extbuf_ = __extbuf_min_;
|
|
|
|
__ebs_ = sizeof(__extbuf_min_);
|
|
|
|
__owns_eb_ = false;
|
2023-12-18 14:01:33 -05:00
|
|
|
}
|
2010-05-11 19:42:16 +00:00
|
|
|
if (!__always_noconv_) {
|
|
|
|
__ibs_ = max<streamsize>(__n, sizeof(__extbuf_min_));
|
|
|
|
if (__s && __ibs_ > sizeof(__extbuf_min_)) {
|
2020-11-24 12:53:53 -05:00
|
|
|
__intbuf_ = __s;
|
2010-05-11 19:42:16 +00:00
|
|
|
__owns_ib_ = false;
|
2023-12-18 14:01:33 -05:00
|
|
|
} else {
|
2010-05-11 19:42:16 +00:00
|
|
|
__intbuf_ = new char_type[__ibs_];
|
|
|
|
__owns_ib_ = true;
|
|
|
|
}
|
2023-12-18 14:01:33 -05:00
|
|
|
} else {
|
2010-05-11 19:42:16 +00:00
|
|
|
__ibs_ = 0;
|
2020-11-24 12:53:53 -05:00
|
|
|
__intbuf_ = nullptr;
|
2010-05-11 19:42:16 +00:00
|
|
|
__owns_ib_ = false;
|
2023-12-18 14:01:33 -05:00
|
|
|
}
|
2010-05-11 19:42:16 +00:00
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
typename basic_filebuf<_CharT, _Traits>::pos_type
|
|
|
|
basic_filebuf<_CharT, _Traits>::seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode) {
|
2012-08-24 16:52:47 +00:00
|
|
|
if (!__cv_)
|
2016-08-25 15:09:01 +00:00
|
|
|
__throw_bad_cast();
|
2023-12-18 14:01:33 -05:00
|
|
|
|
2010-05-11 19:42:16 +00:00
|
|
|
int __width = __cv_->encoding();
|
2020-11-24 12:53:53 -05:00
|
|
|
if (__file_ == nullptr || (__width <= 0 && __off != 0) || sync())
|
2010-05-11 19:42:16 +00:00
|
|
|
return pos_type(off_type(-1));
|
|
|
|
// __width > 0 || __off == 0
|
|
|
|
int __whence;
|
|
|
|
switch (__way) {
|
|
|
|
case ios_base::beg:
|
|
|
|
__whence = SEEK_SET;
|
|
|
|
break;
|
|
|
|
case ios_base::cur:
|
|
|
|
__whence = SEEK_CUR;
|
|
|
|
break;
|
|
|
|
case ios_base::end:
|
|
|
|
__whence = SEEK_END;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return pos_type(off_type(-1));
|
|
|
|
}
|
2024-10-12 09:49:52 +02:00
|
|
|
# if !_LIBCPP_HAS_OFF_T_FUNCTIONS
|
2013-04-02 22:14:51 +00:00
|
|
|
if (fseek(__file_, __width > 0 ? __width * __off : 0, __whence))
|
|
|
|
return pos_type(off_type(-1));
|
|
|
|
pos_type __r = ftell(__file_);
|
|
|
|
# else
|
[libc++] Add custom clang-tidy checks
Reviewed By: #libc, ldionne
Spies: jwakely, beanz, smeenai, cfe-commits, tschuett, avogelsgesang, Mordante, sstefan1, libcxx-commits, ldionne, mgorny, arichardson, miyuki
Differential Revision: https://reviews.llvm.org/D131963
2022-08-13 22:33:12 +02:00
|
|
|
if (::fseeko(__file_, __width > 0 ? __width * __off : 0, __whence))
|
2010-05-11 19:42:16 +00:00
|
|
|
return pos_type(off_type(-1));
|
|
|
|
pos_type __r = ftello(__file_);
|
2013-04-02 22:14:51 +00:00
|
|
|
# endif
|
2010-05-11 19:42:16 +00:00
|
|
|
__r.state(__st_);
|
|
|
|
return __r;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
typename basic_filebuf<_CharT, _Traits>::pos_type
|
2010-07-15 18:18:07 +00:00
|
|
|
basic_filebuf<_CharT, _Traits>::seekpos(pos_type __sp, ios_base::openmode) {
|
2020-11-24 12:53:53 -05:00
|
|
|
if (__file_ == nullptr || sync())
|
2010-05-11 19:42:16 +00:00
|
|
|
return pos_type(off_type(-1));
|
2024-10-12 09:49:52 +02:00
|
|
|
# if !_LIBCPP_HAS_OFF_T_FUNCTIONS
|
2013-04-02 22:14:51 +00:00
|
|
|
if (fseek(__file_, __sp, SEEK_SET))
|
|
|
|
return pos_type(off_type(-1));
|
|
|
|
# else
|
[libc++] Add custom clang-tidy checks
Reviewed By: #libc, ldionne
Spies: jwakely, beanz, smeenai, cfe-commits, tschuett, avogelsgesang, Mordante, sstefan1, libcxx-commits, ldionne, mgorny, arichardson, miyuki
Differential Revision: https://reviews.llvm.org/D131963
2022-08-13 22:33:12 +02:00
|
|
|
if (::fseeko(__file_, __sp, SEEK_SET))
|
2010-05-11 19:42:16 +00:00
|
|
|
return pos_type(off_type(-1));
|
2013-04-02 22:14:51 +00:00
|
|
|
# endif
|
2012-08-24 21:20:56 +00:00
|
|
|
__st_ = __sp.state();
|
2010-05-11 19:42:16 +00:00
|
|
|
return __sp;
|
|
|
|
}
|
2023-12-18 14:01:33 -05:00
|
|
|
|
2010-05-11 19:42:16 +00:00
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
int basic_filebuf<_CharT, _Traits>::sync() {
|
2020-11-24 12:53:53 -05:00
|
|
|
if (__file_ == nullptr)
|
2010-05-11 19:42:16 +00:00
|
|
|
return 0;
|
2012-08-24 16:52:47 +00:00
|
|
|
if (!__cv_)
|
2016-08-25 15:09:01 +00:00
|
|
|
__throw_bad_cast();
|
|
|
|
|
2010-05-11 19:42:16 +00:00
|
|
|
if (__cm_ & ios_base::out) {
|
|
|
|
if (this->pptr() != this->pbase())
|
|
|
|
if (overflow() == traits_type::eof())
|
|
|
|
return -1;
|
|
|
|
codecvt_base::result __r;
|
|
|
|
do {
|
|
|
|
char* __extbe;
|
|
|
|
__r = __cv_->unshift(__st_, __extbuf_, __extbuf_ + __ebs_, __extbe);
|
|
|
|
size_t __nmemb = static_cast<size_t>(__extbe - __extbuf_);
|
|
|
|
if (fwrite(__extbuf_, 1, __nmemb, __file_) != __nmemb)
|
|
|
|
return -1;
|
|
|
|
} while (__r == codecvt_base::partial);
|
|
|
|
if (__r == codecvt_base::error)
|
|
|
|
return -1;
|
|
|
|
if (fflush(__file_))
|
|
|
|
return -1;
|
|
|
|
} else if (__cm_ & ios_base::in) {
|
|
|
|
off_type __c;
|
2012-08-24 21:20:56 +00:00
|
|
|
state_type __state = __st_last_;
|
|
|
|
bool __update_st = false;
|
2010-05-11 19:42:16 +00:00
|
|
|
if (__always_noconv_)
|
|
|
|
__c = this->egptr() - this->gptr();
|
|
|
|
else {
|
|
|
|
int __width = __cv_->encoding();
|
|
|
|
__c = __extbufend_ - __extbufnext_;
|
|
|
|
if (__width > 0)
|
|
|
|
__c += __width * (this->egptr() - this->gptr());
|
|
|
|
else {
|
|
|
|
if (this->gptr() != this->egptr()) {
|
2012-08-24 21:20:56 +00:00
|
|
|
const int __off = __cv_->length(__state, __extbuf_, __extbufnext_, this->gptr() - this->eback());
|
|
|
|
__c += __extbufnext_ - __extbuf_ - __off;
|
|
|
|
__update_st = true;
|
2010-05-11 19:42:16 +00:00
|
|
|
}
|
2023-12-18 14:01:33 -05:00
|
|
|
}
|
2010-05-11 19:42:16 +00:00
|
|
|
}
|
2024-10-12 09:49:52 +02:00
|
|
|
# if !_LIBCPP_HAS_OFF_T_FUNCTIONS
|
2013-04-02 22:14:51 +00:00
|
|
|
if (fseek(__file_, -__c, SEEK_CUR))
|
|
|
|
return -1;
|
2023-12-18 14:01:33 -05:00
|
|
|
# else
|
[libc++] Add custom clang-tidy checks
Reviewed By: #libc, ldionne
Spies: jwakely, beanz, smeenai, cfe-commits, tschuett, avogelsgesang, Mordante, sstefan1, libcxx-commits, ldionne, mgorny, arichardson, miyuki
Differential Revision: https://reviews.llvm.org/D131963
2022-08-13 22:33:12 +02:00
|
|
|
if (::fseeko(__file_, -__c, SEEK_CUR))
|
2013-04-02 22:14:51 +00:00
|
|
|
return -1;
|
2023-12-18 14:01:33 -05:00
|
|
|
# endif
|
2012-08-24 21:20:56 +00:00
|
|
|
if (__update_st)
|
|
|
|
__st_ = __state;
|
|
|
|
__extbufnext_ = __extbufend_ = __extbuf_;
|
2020-11-24 12:53:53 -05:00
|
|
|
this->setg(nullptr, nullptr, nullptr);
|
2010-05-11 19:42:16 +00:00
|
|
|
__cm_ = 0;
|
2023-12-18 14:01:33 -05:00
|
|
|
}
|
2010-05-11 19:42:16 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
void basic_filebuf<_CharT, _Traits>::imbue(const locale& __loc) {
|
|
|
|
sync();
|
[libc++] Add custom clang-tidy checks
Reviewed By: #libc, ldionne
Spies: jwakely, beanz, smeenai, cfe-commits, tschuett, avogelsgesang, Mordante, sstefan1, libcxx-commits, ldionne, mgorny, arichardson, miyuki
Differential Revision: https://reviews.llvm.org/D131963
2022-08-13 22:33:12 +02:00
|
|
|
__cv_ = &std::use_facet<codecvt<char_type, char, state_type> >(__loc);
|
2010-05-11 19:42:16 +00:00
|
|
|
bool __old_anc = __always_noconv_;
|
|
|
|
__always_noconv_ = __cv_->always_noconv();
|
|
|
|
if (__old_anc != __always_noconv_) {
|
2020-11-24 12:53:53 -05:00
|
|
|
this->setg(nullptr, nullptr, nullptr);
|
|
|
|
this->setp(nullptr, nullptr);
|
2010-05-11 19:42:16 +00:00
|
|
|
// invariant, char_type is char, else we couldn't get here
|
|
|
|
if (__always_noconv_) // need to dump __intbuf_
|
|
|
|
{
|
|
|
|
if (__owns_eb_)
|
|
|
|
delete[] __extbuf_;
|
|
|
|
__owns_eb_ = __owns_ib_;
|
|
|
|
__ebs_ = __ibs_;
|
|
|
|
__extbuf_ = (char*)__intbuf_;
|
|
|
|
__ibs_ = 0;
|
2020-11-24 12:53:53 -05:00
|
|
|
__intbuf_ = nullptr;
|
2010-05-11 19:42:16 +00:00
|
|
|
__owns_ib_ = false;
|
|
|
|
} else // need to obtain an __intbuf_.
|
|
|
|
{ // If __extbuf_ is user-supplied, use it, else new __intbuf_
|
|
|
|
if (!__owns_eb_ && __extbuf_ != __extbuf_min_) {
|
|
|
|
__ibs_ = __ebs_;
|
|
|
|
__intbuf_ = (char_type*)__extbuf_;
|
|
|
|
__owns_ib_ = false;
|
|
|
|
__extbuf_ = new char[__ebs_];
|
|
|
|
__owns_eb_ = true;
|
|
|
|
} else {
|
|
|
|
__ibs_ = __ebs_;
|
|
|
|
__intbuf_ = new char_type[__ibs_];
|
|
|
|
__owns_ib_ = true;
|
|
|
|
}
|
|
|
|
}
|
2023-12-18 14:01:33 -05:00
|
|
|
}
|
2010-05-11 19:42:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
bool basic_filebuf<_CharT, _Traits>::__read_mode() {
|
|
|
|
if (!(__cm_ & ios_base::in)) {
|
2020-11-24 12:53:53 -05:00
|
|
|
this->setp(nullptr, nullptr);
|
2010-05-11 19:42:16 +00:00
|
|
|
if (__always_noconv_)
|
|
|
|
this->setg((char_type*)__extbuf_, (char_type*)__extbuf_ + __ebs_, (char_type*)__extbuf_ + __ebs_);
|
|
|
|
else
|
|
|
|
this->setg(__intbuf_, __intbuf_ + __ibs_, __intbuf_ + __ibs_);
|
|
|
|
__cm_ = ios_base::in;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
void basic_filebuf<_CharT, _Traits>::__write_mode() {
|
|
|
|
if (!(__cm_ & ios_base::out)) {
|
2020-11-24 12:53:53 -05:00
|
|
|
this->setg(nullptr, nullptr, nullptr);
|
2010-05-11 19:42:16 +00:00
|
|
|
if (__ebs_ > sizeof(__extbuf_min_)) {
|
|
|
|
if (__always_noconv_)
|
|
|
|
this->setp((char_type*)__extbuf_, (char_type*)__extbuf_ + (__ebs_ - 1));
|
|
|
|
else
|
|
|
|
this->setp(__intbuf_, __intbuf_ + (__ibs_ - 1));
|
|
|
|
} else
|
2020-11-24 12:53:53 -05:00
|
|
|
this->setp(nullptr, nullptr);
|
2010-05-11 19:42:16 +00:00
|
|
|
__cm_ = ios_base::out;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// basic_ifstream
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
2017-01-04 23:56:00 +00:00
|
|
|
class _LIBCPP_TEMPLATE_VIS basic_ifstream : public basic_istream<_CharT, _Traits> {
|
2010-05-11 19:42:16 +00:00
|
|
|
public:
|
|
|
|
typedef _CharT char_type;
|
|
|
|
typedef _Traits traits_type;
|
|
|
|
typedef typename traits_type::int_type int_type;
|
|
|
|
typedef typename traits_type::pos_type pos_type;
|
|
|
|
typedef typename traits_type::off_type off_type;
|
2024-01-07 18:01:03 +02:00
|
|
|
# if _LIBCPP_STD_VER >= 26
|
|
|
|
using native_handle_type = typename basic_filebuf<_CharT, _Traits>::native_handle_type;
|
|
|
|
# endif
|
2023-12-18 14:01:33 -05:00
|
|
|
|
2023-05-24 08:46:13 -07:00
|
|
|
_LIBCPP_HIDE_FROM_ABI basic_ifstream();
|
2010-05-11 19:42:16 +00:00
|
|
|
_LIBCPP_HIDE_FROM_ABI explicit basic_ifstream(const char* __s, ios_base::openmode __mode = ios_base::in);
|
2024-10-12 09:49:52 +02:00
|
|
|
# if _LIBCPP_HAS_OPEN_WITH_WCHAR
|
2018-01-23 02:07:27 +00:00
|
|
|
_LIBCPP_HIDE_FROM_ABI explicit basic_ifstream(const wchar_t* __s, ios_base::openmode __mode = ios_base::in);
|
|
|
|
# endif
|
2010-05-11 19:42:16 +00:00
|
|
|
_LIBCPP_HIDE_FROM_ABI explicit basic_ifstream(const string& __s, ios_base::openmode __mode = ios_base::in);
|
2023-05-31 11:20:24 -07:00
|
|
|
# if _LIBCPP_STD_VER >= 17
|
2024-04-06 20:33:41 +08:00
|
|
|
template <class _Tp, class = enable_if_t<is_same_v<_Tp, filesystem::path>>>
|
2023-06-05 08:20:39 -07:00
|
|
|
_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY
|
2024-04-06 20:33:41 +08:00
|
|
|
_LIBCPP_HIDE_FROM_ABI explicit basic_ifstream(const _Tp& __p, ios_base::openmode __mode = ios_base::in)
|
Implement <filesystem>
This patch implements the <filesystem> header and uses that
to provide <experimental/filesystem>.
Unlike other standard headers, the symbols needed for <filesystem>
have not yet been placed in libc++.so. Instead they live in the
new libc++fs.a library. Users of filesystem are required to link this
library. (Also note that libc++experimental no longer contains the
definition of <experimental/filesystem>, which now requires linking libc++fs).
The reason for keeping <filesystem> out of the dylib for now is that
it's still somewhat experimental, and the possibility of requiring an
ABI breaking change is very real. In the future the symbols will likely
be moved into the dylib, or the dylib will be made to link libc++fs automagically).
Note that moving the symbols out of libc++experimental may break user builds
until they update to -lc++fs. This should be OK, because the experimental
library provides no stability guarantees. However, I plan on looking into
ways we can force libc++experimental to automagically link libc++fs.
In order to use a single implementation and set of tests for <filesystem>, it
has been placed in a special `__fs` namespace. This namespace is inline in
C++17 onward, but not before that. As such implementation is available
in C++11 onward, but no filesystem namespace is present "directly", and
as such name conflicts shouldn't occur in C++11 or C++14.
llvm-svn: 338093
2018-07-27 03:07:09 +00:00
|
|
|
: basic_ifstream(__p.c_str(), __mode) {}
|
|
|
|
# endif // _LIBCPP_STD_VER >= 17
|
2010-05-11 19:42:16 +00:00
|
|
|
_LIBCPP_HIDE_FROM_ABI basic_ifstream(basic_ifstream&& __rhs);
|
|
|
|
_LIBCPP_HIDE_FROM_ABI basic_ifstream& operator=(basic_ifstream&& __rhs);
|
|
|
|
_LIBCPP_HIDE_FROM_ABI void swap(basic_ifstream& __rhs);
|
2023-12-18 14:01:33 -05:00
|
|
|
|
2010-05-11 19:42:16 +00:00
|
|
|
_LIBCPP_HIDE_FROM_ABI basic_filebuf<char_type, traits_type>* rdbuf() const;
|
2024-01-07 18:01:03 +02:00
|
|
|
# if _LIBCPP_STD_VER >= 26
|
|
|
|
_LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() const noexcept { return rdbuf()->native_handle(); }
|
|
|
|
# endif
|
2023-05-24 08:46:13 -07:00
|
|
|
_LIBCPP_HIDE_FROM_ABI bool is_open() const;
|
2010-05-11 19:42:16 +00:00
|
|
|
void open(const char* __s, ios_base::openmode __mode = ios_base::in);
|
2024-10-12 09:49:52 +02:00
|
|
|
# if _LIBCPP_HAS_OPEN_WITH_WCHAR
|
2018-01-23 02:07:27 +00:00
|
|
|
void open(const wchar_t* __s, ios_base::openmode __mode = ios_base::in);
|
|
|
|
# endif
|
2010-05-11 19:42:16 +00:00
|
|
|
void open(const string& __s, ios_base::openmode __mode = ios_base::in);
|
2023-05-31 11:20:24 -07:00
|
|
|
# if _LIBCPP_STD_VER >= 17
|
2023-06-05 08:20:39 -07:00
|
|
|
_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_HIDE_FROM_ABI void
|
Implement <filesystem>
This patch implements the <filesystem> header and uses that
to provide <experimental/filesystem>.
Unlike other standard headers, the symbols needed for <filesystem>
have not yet been placed in libc++.so. Instead they live in the
new libc++fs.a library. Users of filesystem are required to link this
library. (Also note that libc++experimental no longer contains the
definition of <experimental/filesystem>, which now requires linking libc++fs).
The reason for keeping <filesystem> out of the dylib for now is that
it's still somewhat experimental, and the possibility of requiring an
ABI breaking change is very real. In the future the symbols will likely
be moved into the dylib, or the dylib will be made to link libc++fs automagically).
Note that moving the symbols out of libc++experimental may break user builds
until they update to -lc++fs. This should be OK, because the experimental
library provides no stability guarantees. However, I plan on looking into
ways we can force libc++experimental to automagically link libc++fs.
In order to use a single implementation and set of tests for <filesystem>, it
has been placed in a special `__fs` namespace. This namespace is inline in
C++17 onward, but not before that. As such implementation is available
in C++11 onward, but no filesystem namespace is present "directly", and
as such name conflicts shouldn't occur in C++11 or C++14.
llvm-svn: 338093
2018-07-27 03:07:09 +00:00
|
|
|
open(const filesystem::path& __p, ios_base::openmode __mode = ios_base::in) {
|
|
|
|
return open(__p.c_str(), __mode);
|
|
|
|
}
|
|
|
|
# endif // _LIBCPP_STD_VER >= 17
|
2018-07-22 02:00:53 +00:00
|
|
|
|
|
|
|
_LIBCPP_HIDE_FROM_ABI void __open(int __fd, ios_base::openmode __mode);
|
2023-05-24 08:46:13 -07:00
|
|
|
_LIBCPP_HIDE_FROM_ABI void close();
|
2010-05-11 19:42:16 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
basic_filebuf<char_type, traits_type> __sb_;
|
|
|
|
};
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
2024-08-06 19:47:56 +02:00
|
|
|
inline basic_ifstream<_CharT, _Traits>::basic_ifstream()
|
|
|
|
: basic_istream<char_type, traits_type>(std::addressof(__sb_)) {}
|
2010-05-11 19:42:16 +00:00
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
inline basic_ifstream<_CharT, _Traits>::basic_ifstream(const char* __s, ios_base::openmode __mode)
|
2024-08-06 19:47:56 +02:00
|
|
|
: basic_istream<char_type, traits_type>(std::addressof(__sb_)) {
|
2020-11-24 12:53:53 -05:00
|
|
|
if (__sb_.open(__s, __mode | ios_base::in) == nullptr)
|
2010-05-11 19:42:16 +00:00
|
|
|
this->setstate(ios_base::failbit);
|
|
|
|
}
|
|
|
|
|
2024-10-12 09:49:52 +02:00
|
|
|
# if _LIBCPP_HAS_OPEN_WITH_WCHAR
|
2018-01-23 02:07:27 +00:00
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
inline basic_ifstream<_CharT, _Traits>::basic_ifstream(const wchar_t* __s, ios_base::openmode __mode)
|
2024-08-06 19:47:56 +02:00
|
|
|
: basic_istream<char_type, traits_type>(std::addressof(__sb_)) {
|
2020-11-24 12:53:53 -05:00
|
|
|
if (__sb_.open(__s, __mode | ios_base::in) == nullptr)
|
2018-01-23 02:07:27 +00:00
|
|
|
this->setstate(ios_base::failbit);
|
|
|
|
}
|
|
|
|
# endif
|
|
|
|
|
2024-08-06 19:47:56 +02:00
|
|
|
// extension
|
2010-05-11 19:42:16 +00:00
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
inline basic_ifstream<_CharT, _Traits>::basic_ifstream(const string& __s, ios_base::openmode __mode)
|
2024-08-06 19:47:56 +02:00
|
|
|
: basic_istream<char_type, traits_type>(std::addressof(__sb_)) {
|
2020-11-24 12:53:53 -05:00
|
|
|
if (__sb_.open(__s, __mode | ios_base::in) == nullptr)
|
2010-05-11 19:42:16 +00:00
|
|
|
this->setstate(ios_base::failbit);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
inline basic_ifstream<_CharT, _Traits>::basic_ifstream(basic_ifstream&& __rhs)
|
2011-06-30 21:18:19 +00:00
|
|
|
: basic_istream<char_type, traits_type>(std::move(__rhs)), __sb_(std::move(__rhs.__sb_)) {
|
2024-08-06 19:47:56 +02:00
|
|
|
this->set_rdbuf(std::addressof(__sb_));
|
2010-05-11 19:42:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
inline basic_ifstream<_CharT, _Traits>& basic_ifstream<_CharT, _Traits>::operator=(basic_ifstream&& __rhs) {
|
2011-06-30 21:18:19 +00:00
|
|
|
basic_istream<char_type, traits_type>::operator=(std::move(__rhs));
|
|
|
|
__sb_ = std::move(__rhs.__sb_);
|
2010-05-11 19:42:16 +00:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
inline void basic_ifstream<_CharT, _Traits>::swap(basic_ifstream& __rhs) {
|
|
|
|
basic_istream<char_type, traits_type>::swap(__rhs);
|
|
|
|
__sb_.swap(__rhs.__sb_);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
inline _LIBCPP_HIDE_FROM_ABI void swap(basic_ifstream<_CharT, _Traits>& __x, basic_ifstream<_CharT, _Traits>& __y) {
|
|
|
|
__x.swap(__y);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
inline basic_filebuf<_CharT, _Traits>* basic_ifstream<_CharT, _Traits>::rdbuf() const {
|
2024-08-06 19:47:56 +02:00
|
|
|
return const_cast<basic_filebuf<char_type, traits_type>*>(std::addressof(__sb_));
|
2010-05-11 19:42:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
inline bool basic_ifstream<_CharT, _Traits>::is_open() const {
|
|
|
|
return __sb_.is_open();
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
void basic_ifstream<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode) {
|
|
|
|
if (__sb_.open(__s, __mode | ios_base::in))
|
|
|
|
this->clear();
|
|
|
|
else
|
|
|
|
this->setstate(ios_base::failbit);
|
|
|
|
}
|
|
|
|
|
2024-10-12 09:49:52 +02:00
|
|
|
# if _LIBCPP_HAS_OPEN_WITH_WCHAR
|
2018-01-23 02:07:27 +00:00
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
void basic_ifstream<_CharT, _Traits>::open(const wchar_t* __s, ios_base::openmode __mode) {
|
|
|
|
if (__sb_.open(__s, __mode | ios_base::in))
|
|
|
|
this->clear();
|
|
|
|
else
|
|
|
|
this->setstate(ios_base::failbit);
|
|
|
|
}
|
|
|
|
# endif
|
|
|
|
|
2010-05-11 19:42:16 +00:00
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
void basic_ifstream<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode) {
|
|
|
|
if (__sb_.open(__s, __mode | ios_base::in))
|
|
|
|
this->clear();
|
|
|
|
else
|
|
|
|
this->setstate(ios_base::failbit);
|
|
|
|
}
|
2018-07-22 02:00:53 +00:00
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
inline void basic_ifstream<_CharT, _Traits>::__open(int __fd, ios_base::openmode __mode) {
|
|
|
|
if (__sb_.__open(__fd, __mode | ios_base::in))
|
|
|
|
this->clear();
|
|
|
|
else
|
|
|
|
this->setstate(ios_base::failbit);
|
|
|
|
}
|
2010-05-11 19:42:16 +00:00
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
inline void basic_ifstream<_CharT, _Traits>::close() {
|
|
|
|
if (__sb_.close() == 0)
|
|
|
|
this->setstate(ios_base::failbit);
|
|
|
|
}
|
|
|
|
|
|
|
|
// basic_ofstream
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
2017-01-04 23:56:00 +00:00
|
|
|
class _LIBCPP_TEMPLATE_VIS basic_ofstream : public basic_ostream<_CharT, _Traits> {
|
2010-05-11 19:42:16 +00:00
|
|
|
public:
|
|
|
|
typedef _CharT char_type;
|
|
|
|
typedef _Traits traits_type;
|
|
|
|
typedef typename traits_type::int_type int_type;
|
|
|
|
typedef typename traits_type::pos_type pos_type;
|
|
|
|
typedef typename traits_type::off_type off_type;
|
2024-01-07 18:01:03 +02:00
|
|
|
# if _LIBCPP_STD_VER >= 26
|
|
|
|
using native_handle_type = typename basic_filebuf<_CharT, _Traits>::native_handle_type;
|
|
|
|
# endif
|
2023-12-18 14:01:33 -05:00
|
|
|
|
2023-05-24 08:46:13 -07:00
|
|
|
_LIBCPP_HIDE_FROM_ABI basic_ofstream();
|
2010-05-11 19:42:16 +00:00
|
|
|
_LIBCPP_HIDE_FROM_ABI explicit basic_ofstream(const char* __s, ios_base::openmode __mode = ios_base::out);
|
2024-10-12 09:49:52 +02:00
|
|
|
# if _LIBCPP_HAS_OPEN_WITH_WCHAR
|
2018-01-23 02:07:27 +00:00
|
|
|
_LIBCPP_HIDE_FROM_ABI explicit basic_ofstream(const wchar_t* __s, ios_base::openmode __mode = ios_base::out);
|
|
|
|
# endif
|
2010-05-11 19:42:16 +00:00
|
|
|
_LIBCPP_HIDE_FROM_ABI explicit basic_ofstream(const string& __s, ios_base::openmode __mode = ios_base::out);
|
2023-12-18 14:01:33 -05:00
|
|
|
|
2023-05-31 11:20:24 -07:00
|
|
|
# if _LIBCPP_STD_VER >= 17
|
2024-04-06 20:33:41 +08:00
|
|
|
template <class _Tp, class = enable_if_t<is_same_v<_Tp, filesystem::path>>>
|
2023-06-05 08:20:39 -07:00
|
|
|
_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY
|
2024-04-06 20:33:41 +08:00
|
|
|
_LIBCPP_HIDE_FROM_ABI explicit basic_ofstream(const _Tp& __p, ios_base::openmode __mode = ios_base::out)
|
Implement <filesystem>
This patch implements the <filesystem> header and uses that
to provide <experimental/filesystem>.
Unlike other standard headers, the symbols needed for <filesystem>
have not yet been placed in libc++.so. Instead they live in the
new libc++fs.a library. Users of filesystem are required to link this
library. (Also note that libc++experimental no longer contains the
definition of <experimental/filesystem>, which now requires linking libc++fs).
The reason for keeping <filesystem> out of the dylib for now is that
it's still somewhat experimental, and the possibility of requiring an
ABI breaking change is very real. In the future the symbols will likely
be moved into the dylib, or the dylib will be made to link libc++fs automagically).
Note that moving the symbols out of libc++experimental may break user builds
until they update to -lc++fs. This should be OK, because the experimental
library provides no stability guarantees. However, I plan on looking into
ways we can force libc++experimental to automagically link libc++fs.
In order to use a single implementation and set of tests for <filesystem>, it
has been placed in a special `__fs` namespace. This namespace is inline in
C++17 onward, but not before that. As such implementation is available
in C++11 onward, but no filesystem namespace is present "directly", and
as such name conflicts shouldn't occur in C++11 or C++14.
llvm-svn: 338093
2018-07-27 03:07:09 +00:00
|
|
|
: basic_ofstream(__p.c_str(), __mode) {}
|
|
|
|
# endif // _LIBCPP_STD_VER >= 17
|
2023-12-18 14:01:33 -05:00
|
|
|
|
2010-05-11 19:42:16 +00:00
|
|
|
_LIBCPP_HIDE_FROM_ABI basic_ofstream(basic_ofstream&& __rhs);
|
|
|
|
_LIBCPP_HIDE_FROM_ABI basic_ofstream& operator=(basic_ofstream&& __rhs);
|
|
|
|
_LIBCPP_HIDE_FROM_ABI void swap(basic_ofstream& __rhs);
|
2023-12-18 14:01:33 -05:00
|
|
|
|
2010-05-11 19:42:16 +00:00
|
|
|
_LIBCPP_HIDE_FROM_ABI basic_filebuf<char_type, traits_type>* rdbuf() const;
|
2024-01-07 18:01:03 +02:00
|
|
|
# if _LIBCPP_STD_VER >= 26
|
|
|
|
_LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() const noexcept { return rdbuf()->native_handle(); }
|
|
|
|
# endif
|
2023-05-24 08:46:13 -07:00
|
|
|
_LIBCPP_HIDE_FROM_ABI bool is_open() const;
|
2010-05-11 19:42:16 +00:00
|
|
|
void open(const char* __s, ios_base::openmode __mode = ios_base::out);
|
2024-10-12 09:49:52 +02:00
|
|
|
# if _LIBCPP_HAS_OPEN_WITH_WCHAR
|
2018-01-23 02:07:27 +00:00
|
|
|
void open(const wchar_t* __s, ios_base::openmode __mode = ios_base::out);
|
|
|
|
# endif
|
2010-05-11 19:42:16 +00:00
|
|
|
void open(const string& __s, ios_base::openmode __mode = ios_base::out);
|
2023-12-18 14:01:33 -05:00
|
|
|
|
2023-05-31 11:20:24 -07:00
|
|
|
# if _LIBCPP_STD_VER >= 17
|
2023-06-05 08:20:39 -07:00
|
|
|
_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_HIDE_FROM_ABI void
|
Implement <filesystem>
This patch implements the <filesystem> header and uses that
to provide <experimental/filesystem>.
Unlike other standard headers, the symbols needed for <filesystem>
have not yet been placed in libc++.so. Instead they live in the
new libc++fs.a library. Users of filesystem are required to link this
library. (Also note that libc++experimental no longer contains the
definition of <experimental/filesystem>, which now requires linking libc++fs).
The reason for keeping <filesystem> out of the dylib for now is that
it's still somewhat experimental, and the possibility of requiring an
ABI breaking change is very real. In the future the symbols will likely
be moved into the dylib, or the dylib will be made to link libc++fs automagically).
Note that moving the symbols out of libc++experimental may break user builds
until they update to -lc++fs. This should be OK, because the experimental
library provides no stability guarantees. However, I plan on looking into
ways we can force libc++experimental to automagically link libc++fs.
In order to use a single implementation and set of tests for <filesystem>, it
has been placed in a special `__fs` namespace. This namespace is inline in
C++17 onward, but not before that. As such implementation is available
in C++11 onward, but no filesystem namespace is present "directly", and
as such name conflicts shouldn't occur in C++11 or C++14.
llvm-svn: 338093
2018-07-27 03:07:09 +00:00
|
|
|
open(const filesystem::path& __p, ios_base::openmode __mode = ios_base::out) {
|
|
|
|
return open(__p.c_str(), __mode);
|
|
|
|
}
|
|
|
|
# endif // _LIBCPP_STD_VER >= 17
|
|
|
|
|
2018-07-22 02:00:53 +00:00
|
|
|
_LIBCPP_HIDE_FROM_ABI void __open(int __fd, ios_base::openmode __mode);
|
2023-05-24 08:46:13 -07:00
|
|
|
_LIBCPP_HIDE_FROM_ABI void close();
|
2010-05-11 19:42:16 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
basic_filebuf<char_type, traits_type> __sb_;
|
|
|
|
};
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
2024-08-06 19:47:56 +02:00
|
|
|
inline basic_ofstream<_CharT, _Traits>::basic_ofstream()
|
|
|
|
: basic_ostream<char_type, traits_type>(std::addressof(__sb_)) {}
|
2010-05-11 19:42:16 +00:00
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
inline basic_ofstream<_CharT, _Traits>::basic_ofstream(const char* __s, ios_base::openmode __mode)
|
2024-08-06 19:47:56 +02:00
|
|
|
: basic_ostream<char_type, traits_type>(std::addressof(__sb_)) {
|
2020-11-24 12:53:53 -05:00
|
|
|
if (__sb_.open(__s, __mode | ios_base::out) == nullptr)
|
2010-05-11 19:42:16 +00:00
|
|
|
this->setstate(ios_base::failbit);
|
|
|
|
}
|
|
|
|
|
2024-10-12 09:49:52 +02:00
|
|
|
# if _LIBCPP_HAS_OPEN_WITH_WCHAR
|
2018-01-23 02:07:27 +00:00
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
inline basic_ofstream<_CharT, _Traits>::basic_ofstream(const wchar_t* __s, ios_base::openmode __mode)
|
2024-08-06 19:47:56 +02:00
|
|
|
: basic_ostream<char_type, traits_type>(std::addressof(__sb_)) {
|
2020-11-24 12:53:53 -05:00
|
|
|
if (__sb_.open(__s, __mode | ios_base::out) == nullptr)
|
2018-01-23 02:07:27 +00:00
|
|
|
this->setstate(ios_base::failbit);
|
|
|
|
}
|
|
|
|
# endif
|
|
|
|
|
2024-08-06 19:47:56 +02:00
|
|
|
// extension
|
2010-05-11 19:42:16 +00:00
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
inline basic_ofstream<_CharT, _Traits>::basic_ofstream(const string& __s, ios_base::openmode __mode)
|
2024-08-06 19:47:56 +02:00
|
|
|
: basic_ostream<char_type, traits_type>(std::addressof(__sb_)) {
|
2020-11-24 12:53:53 -05:00
|
|
|
if (__sb_.open(__s, __mode | ios_base::out) == nullptr)
|
2010-05-11 19:42:16 +00:00
|
|
|
this->setstate(ios_base::failbit);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
inline basic_ofstream<_CharT, _Traits>::basic_ofstream(basic_ofstream&& __rhs)
|
2011-06-30 21:18:19 +00:00
|
|
|
: basic_ostream<char_type, traits_type>(std::move(__rhs)), __sb_(std::move(__rhs.__sb_)) {
|
2024-08-06 19:47:56 +02:00
|
|
|
this->set_rdbuf(std::addressof(__sb_));
|
2010-05-11 19:42:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
inline basic_ofstream<_CharT, _Traits>& basic_ofstream<_CharT, _Traits>::operator=(basic_ofstream&& __rhs) {
|
2011-06-30 21:18:19 +00:00
|
|
|
basic_ostream<char_type, traits_type>::operator=(std::move(__rhs));
|
|
|
|
__sb_ = std::move(__rhs.__sb_);
|
2010-05-11 19:42:16 +00:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
inline void basic_ofstream<_CharT, _Traits>::swap(basic_ofstream& __rhs) {
|
|
|
|
basic_ostream<char_type, traits_type>::swap(__rhs);
|
|
|
|
__sb_.swap(__rhs.__sb_);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
inline _LIBCPP_HIDE_FROM_ABI void swap(basic_ofstream<_CharT, _Traits>& __x, basic_ofstream<_CharT, _Traits>& __y) {
|
|
|
|
__x.swap(__y);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
inline basic_filebuf<_CharT, _Traits>* basic_ofstream<_CharT, _Traits>::rdbuf() const {
|
2024-08-06 19:47:56 +02:00
|
|
|
return const_cast<basic_filebuf<char_type, traits_type>*>(std::addressof(__sb_));
|
2010-05-11 19:42:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
inline bool basic_ofstream<_CharT, _Traits>::is_open() const {
|
|
|
|
return __sb_.is_open();
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
void basic_ofstream<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode) {
|
|
|
|
if (__sb_.open(__s, __mode | ios_base::out))
|
|
|
|
this->clear();
|
|
|
|
else
|
|
|
|
this->setstate(ios_base::failbit);
|
|
|
|
}
|
|
|
|
|
2024-10-12 09:49:52 +02:00
|
|
|
# if _LIBCPP_HAS_OPEN_WITH_WCHAR
|
2018-01-23 02:07:27 +00:00
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
void basic_ofstream<_CharT, _Traits>::open(const wchar_t* __s, ios_base::openmode __mode) {
|
|
|
|
if (__sb_.open(__s, __mode | ios_base::out))
|
|
|
|
this->clear();
|
|
|
|
else
|
|
|
|
this->setstate(ios_base::failbit);
|
|
|
|
}
|
|
|
|
# endif
|
|
|
|
|
2010-05-11 19:42:16 +00:00
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
void basic_ofstream<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode) {
|
|
|
|
if (__sb_.open(__s, __mode | ios_base::out))
|
|
|
|
this->clear();
|
|
|
|
else
|
|
|
|
this->setstate(ios_base::failbit);
|
|
|
|
}
|
2018-07-22 02:00:53 +00:00
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
inline void basic_ofstream<_CharT, _Traits>::__open(int __fd, ios_base::openmode __mode) {
|
|
|
|
if (__sb_.__open(__fd, __mode | ios_base::out))
|
|
|
|
this->clear();
|
|
|
|
else
|
|
|
|
this->setstate(ios_base::failbit);
|
|
|
|
}
|
2010-05-11 19:42:16 +00:00
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
inline void basic_ofstream<_CharT, _Traits>::close() {
|
2020-11-24 12:53:53 -05:00
|
|
|
if (__sb_.close() == nullptr)
|
2010-05-11 19:42:16 +00:00
|
|
|
this->setstate(ios_base::failbit);
|
|
|
|
}
|
|
|
|
|
|
|
|
// basic_fstream
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
class _LIBCPP_TEMPLATE_VIS basic_fstream : public basic_iostream<_CharT, _Traits> {
|
|
|
|
public:
|
|
|
|
typedef _CharT char_type;
|
|
|
|
typedef _Traits traits_type;
|
|
|
|
typedef typename traits_type::int_type int_type;
|
|
|
|
typedef typename traits_type::pos_type pos_type;
|
|
|
|
typedef typename traits_type::off_type off_type;
|
2024-01-07 18:01:03 +02:00
|
|
|
# if _LIBCPP_STD_VER >= 26
|
|
|
|
using native_handle_type = typename basic_filebuf<_CharT, _Traits>::native_handle_type;
|
|
|
|
# endif
|
2023-12-18 14:01:33 -05:00
|
|
|
|
2016-04-22 01:04:55 +00:00
|
|
|
_LIBCPP_HIDE_FROM_ABI basic_fstream();
|
2010-05-11 19:42:16 +00:00
|
|
|
_LIBCPP_HIDE_FROM_ABI explicit basic_fstream(const char* __s,
|
|
|
|
ios_base::openmode __mode = ios_base::in | ios_base::out);
|
2024-10-12 09:49:52 +02:00
|
|
|
# if _LIBCPP_HAS_OPEN_WITH_WCHAR
|
2018-01-23 02:07:27 +00:00
|
|
|
_LIBCPP_HIDE_FROM_ABI explicit basic_fstream(const wchar_t* __s,
|
|
|
|
ios_base::openmode __mode = ios_base::in | ios_base::out);
|
|
|
|
# endif
|
2010-05-11 19:42:16 +00:00
|
|
|
_LIBCPP_HIDE_FROM_ABI explicit basic_fstream(const string& __s,
|
|
|
|
ios_base::openmode __mode = ios_base::in | ios_base::out);
|
2023-12-18 14:01:33 -05:00
|
|
|
|
2023-05-31 11:20:24 -07:00
|
|
|
# if _LIBCPP_STD_VER >= 17
|
2024-04-06 20:33:41 +08:00
|
|
|
template <class _Tp, class = enable_if_t<is_same_v<_Tp, filesystem::path>>>
|
2023-06-05 08:20:39 -07:00
|
|
|
_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_HIDE_FROM_ABI explicit basic_fstream(
|
2024-04-06 20:33:41 +08:00
|
|
|
const _Tp& __p, ios_base::openmode __mode = ios_base::in | ios_base::out)
|
Implement <filesystem>
This patch implements the <filesystem> header and uses that
to provide <experimental/filesystem>.
Unlike other standard headers, the symbols needed for <filesystem>
have not yet been placed in libc++.so. Instead they live in the
new libc++fs.a library. Users of filesystem are required to link this
library. (Also note that libc++experimental no longer contains the
definition of <experimental/filesystem>, which now requires linking libc++fs).
The reason for keeping <filesystem> out of the dylib for now is that
it's still somewhat experimental, and the possibility of requiring an
ABI breaking change is very real. In the future the symbols will likely
be moved into the dylib, or the dylib will be made to link libc++fs automagically).
Note that moving the symbols out of libc++experimental may break user builds
until they update to -lc++fs. This should be OK, because the experimental
library provides no stability guarantees. However, I plan on looking into
ways we can force libc++experimental to automagically link libc++fs.
In order to use a single implementation and set of tests for <filesystem>, it
has been placed in a special `__fs` namespace. This namespace is inline in
C++17 onward, but not before that. As such implementation is available
in C++11 onward, but no filesystem namespace is present "directly", and
as such name conflicts shouldn't occur in C++11 or C++14.
llvm-svn: 338093
2018-07-27 03:07:09 +00:00
|
|
|
: basic_fstream(__p.c_str(), __mode) {}
|
|
|
|
# endif // _LIBCPP_STD_VER >= 17
|
|
|
|
|
2010-05-11 19:42:16 +00:00
|
|
|
_LIBCPP_HIDE_FROM_ABI basic_fstream(basic_fstream&& __rhs);
|
|
|
|
|
|
|
|
_LIBCPP_HIDE_FROM_ABI basic_fstream& operator=(basic_fstream&& __rhs);
|
2021-06-15 12:47:05 -04:00
|
|
|
|
2010-05-11 19:42:16 +00:00
|
|
|
_LIBCPP_HIDE_FROM_ABI void swap(basic_fstream& __rhs);
|
|
|
|
|
|
|
|
_LIBCPP_HIDE_FROM_ABI basic_filebuf<char_type, traits_type>* rdbuf() const;
|
2024-01-07 18:01:03 +02:00
|
|
|
# if _LIBCPP_STD_VER >= 26
|
|
|
|
_LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() const noexcept { return rdbuf()->native_handle(); }
|
|
|
|
# endif
|
2016-04-22 01:04:55 +00:00
|
|
|
_LIBCPP_HIDE_FROM_ABI bool is_open() const;
|
2023-01-23 10:27:14 +01:00
|
|
|
_LIBCPP_HIDE_FROM_ABI void open(const char* __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
|
2024-10-12 09:49:52 +02:00
|
|
|
# if _LIBCPP_HAS_OPEN_WITH_WCHAR
|
2018-01-23 02:07:27 +00:00
|
|
|
void open(const wchar_t* __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
|
|
|
|
# endif
|
2023-01-23 10:27:14 +01:00
|
|
|
_LIBCPP_HIDE_FROM_ABI void open(const string& __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
|
Implement <filesystem>
This patch implements the <filesystem> header and uses that
to provide <experimental/filesystem>.
Unlike other standard headers, the symbols needed for <filesystem>
have not yet been placed in libc++.so. Instead they live in the
new libc++fs.a library. Users of filesystem are required to link this
library. (Also note that libc++experimental no longer contains the
definition of <experimental/filesystem>, which now requires linking libc++fs).
The reason for keeping <filesystem> out of the dylib for now is that
it's still somewhat experimental, and the possibility of requiring an
ABI breaking change is very real. In the future the symbols will likely
be moved into the dylib, or the dylib will be made to link libc++fs automagically).
Note that moving the symbols out of libc++experimental may break user builds
until they update to -lc++fs. This should be OK, because the experimental
library provides no stability guarantees. However, I plan on looking into
ways we can force libc++experimental to automagically link libc++fs.
In order to use a single implementation and set of tests for <filesystem>, it
has been placed in a special `__fs` namespace. This namespace is inline in
C++17 onward, but not before that. As such implementation is available
in C++11 onward, but no filesystem namespace is present "directly", and
as such name conflicts shouldn't occur in C++11 or C++14.
llvm-svn: 338093
2018-07-27 03:07:09 +00:00
|
|
|
|
2023-05-31 11:20:24 -07:00
|
|
|
# if _LIBCPP_STD_VER >= 17
|
2023-06-05 08:20:39 -07:00
|
|
|
_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_HIDE_FROM_ABI void
|
Implement <filesystem>
This patch implements the <filesystem> header and uses that
to provide <experimental/filesystem>.
Unlike other standard headers, the symbols needed for <filesystem>
have not yet been placed in libc++.so. Instead they live in the
new libc++fs.a library. Users of filesystem are required to link this
library. (Also note that libc++experimental no longer contains the
definition of <experimental/filesystem>, which now requires linking libc++fs).
The reason for keeping <filesystem> out of the dylib for now is that
it's still somewhat experimental, and the possibility of requiring an
ABI breaking change is very real. In the future the symbols will likely
be moved into the dylib, or the dylib will be made to link libc++fs automagically).
Note that moving the symbols out of libc++experimental may break user builds
until they update to -lc++fs. This should be OK, because the experimental
library provides no stability guarantees. However, I plan on looking into
ways we can force libc++experimental to automagically link libc++fs.
In order to use a single implementation and set of tests for <filesystem>, it
has been placed in a special `__fs` namespace. This namespace is inline in
C++17 onward, but not before that. As such implementation is available
in C++11 onward, but no filesystem namespace is present "directly", and
as such name conflicts shouldn't occur in C++11 or C++14.
llvm-svn: 338093
2018-07-27 03:07:09 +00:00
|
|
|
open(const filesystem::path& __p, ios_base::openmode __mode = ios_base::in | ios_base::out) {
|
|
|
|
return open(__p.c_str(), __mode);
|
|
|
|
}
|
|
|
|
# endif // _LIBCPP_STD_VER >= 17
|
|
|
|
|
2016-04-22 01:04:55 +00:00
|
|
|
_LIBCPP_HIDE_FROM_ABI void close();
|
2010-05-11 19:42:16 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
basic_filebuf<char_type, traits_type> __sb_;
|
|
|
|
};
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
2024-08-06 19:47:56 +02:00
|
|
|
inline basic_fstream<_CharT, _Traits>::basic_fstream()
|
|
|
|
: basic_iostream<char_type, traits_type>(std::addressof(__sb_)) {}
|
2010-05-11 19:42:16 +00:00
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
inline basic_fstream<_CharT, _Traits>::basic_fstream(const char* __s, ios_base::openmode __mode)
|
2024-08-06 19:47:56 +02:00
|
|
|
: basic_iostream<char_type, traits_type>(std::addressof(__sb_)) {
|
2020-11-24 12:53:53 -05:00
|
|
|
if (__sb_.open(__s, __mode) == nullptr)
|
2010-05-11 19:42:16 +00:00
|
|
|
this->setstate(ios_base::failbit);
|
|
|
|
}
|
|
|
|
|
2024-10-12 09:49:52 +02:00
|
|
|
# if _LIBCPP_HAS_OPEN_WITH_WCHAR
|
2018-01-23 02:07:27 +00:00
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
inline basic_fstream<_CharT, _Traits>::basic_fstream(const wchar_t* __s, ios_base::openmode __mode)
|
2024-08-06 19:47:56 +02:00
|
|
|
: basic_iostream<char_type, traits_type>(std::addressof(__sb_)) {
|
2020-11-24 12:53:53 -05:00
|
|
|
if (__sb_.open(__s, __mode) == nullptr)
|
2018-01-23 02:07:27 +00:00
|
|
|
this->setstate(ios_base::failbit);
|
|
|
|
}
|
|
|
|
# endif
|
|
|
|
|
2010-05-11 19:42:16 +00:00
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
inline basic_fstream<_CharT, _Traits>::basic_fstream(const string& __s, ios_base::openmode __mode)
|
2024-08-06 19:47:56 +02:00
|
|
|
: basic_iostream<char_type, traits_type>(std::addressof(__sb_)) {
|
2020-11-24 12:53:53 -05:00
|
|
|
if (__sb_.open(__s, __mode) == nullptr)
|
2010-05-11 19:42:16 +00:00
|
|
|
this->setstate(ios_base::failbit);
|
|
|
|
}
|
|
|
|
|
2024-08-06 19:47:56 +02:00
|
|
|
// extension
|
2010-05-11 19:42:16 +00:00
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
inline basic_fstream<_CharT, _Traits>::basic_fstream(basic_fstream&& __rhs)
|
2011-06-30 21:18:19 +00:00
|
|
|
: basic_iostream<char_type, traits_type>(std::move(__rhs)), __sb_(std::move(__rhs.__sb_)) {
|
2024-08-06 19:47:56 +02:00
|
|
|
this->set_rdbuf(std::addressof(__sb_));
|
2010-05-11 19:42:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
inline basic_fstream<_CharT, _Traits>& basic_fstream<_CharT, _Traits>::operator=(basic_fstream&& __rhs) {
|
2011-06-30 21:18:19 +00:00
|
|
|
basic_iostream<char_type, traits_type>::operator=(std::move(__rhs));
|
|
|
|
__sb_ = std::move(__rhs.__sb_);
|
2010-05-11 19:42:16 +00:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
inline void basic_fstream<_CharT, _Traits>::swap(basic_fstream& __rhs) {
|
|
|
|
basic_iostream<char_type, traits_type>::swap(__rhs);
|
|
|
|
__sb_.swap(__rhs.__sb_);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
inline _LIBCPP_HIDE_FROM_ABI void swap(basic_fstream<_CharT, _Traits>& __x, basic_fstream<_CharT, _Traits>& __y) {
|
|
|
|
__x.swap(__y);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
inline basic_filebuf<_CharT, _Traits>* basic_fstream<_CharT, _Traits>::rdbuf() const {
|
2024-08-06 19:47:56 +02:00
|
|
|
return const_cast<basic_filebuf<char_type, traits_type>*>(std::addressof(__sb_));
|
2010-05-11 19:42:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
inline bool basic_fstream<_CharT, _Traits>::is_open() const {
|
|
|
|
return __sb_.is_open();
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
void basic_fstream<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode) {
|
|
|
|
if (__sb_.open(__s, __mode))
|
|
|
|
this->clear();
|
|
|
|
else
|
|
|
|
this->setstate(ios_base::failbit);
|
|
|
|
}
|
|
|
|
|
2024-10-12 09:49:52 +02:00
|
|
|
# if _LIBCPP_HAS_OPEN_WITH_WCHAR
|
2018-01-23 02:07:27 +00:00
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
void basic_fstream<_CharT, _Traits>::open(const wchar_t* __s, ios_base::openmode __mode) {
|
|
|
|
if (__sb_.open(__s, __mode))
|
|
|
|
this->clear();
|
|
|
|
else
|
|
|
|
this->setstate(ios_base::failbit);
|
|
|
|
}
|
|
|
|
# endif
|
|
|
|
|
2010-05-11 19:42:16 +00:00
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
void basic_fstream<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode) {
|
|
|
|
if (__sb_.open(__s, __mode))
|
|
|
|
this->clear();
|
|
|
|
else
|
|
|
|
this->setstate(ios_base::failbit);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
inline void basic_fstream<_CharT, _Traits>::close() {
|
2020-11-24 12:53:53 -05:00
|
|
|
if (__sb_.close() == nullptr)
|
2010-05-11 19:42:16 +00:00
|
|
|
this->setstate(ios_base::failbit);
|
|
|
|
}
|
|
|
|
|
2023-11-24 23:45:17 +01:00
|
|
|
# if _LIBCPP_AVAILABILITY_HAS_ADDITIONAL_IOSTREAM_EXPLICIT_INSTANTIATIONS_1
|
2021-06-08 17:25:08 -04:00
|
|
|
extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ifstream<char>;
|
|
|
|
extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ofstream<char>;
|
|
|
|
extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_filebuf<char>;
|
2020-10-21 11:11:45 -04:00
|
|
|
# endif
|
|
|
|
|
2010-05-11 19:42:16 +00:00
|
|
|
_LIBCPP_END_NAMESPACE_STD
|
|
|
|
|
2024-11-06 10:39:19 +01:00
|
|
|
#endif // _LIBCPP_HAS_FILESYSTEM && _LIBCPP_HAS_LOCALIZATION
|
2022-11-18 15:01:33 -05:00
|
|
|
|
2017-05-31 22:07:49 +00:00
|
|
|
_LIBCPP_POP_MACROS
|
|
|
|
|
2022-11-02 20:27:42 +01:00
|
|
|
#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
|
2022-09-22 21:53:13 +02:00
|
|
|
# include <atomic>
|
2022-11-02 20:27:42 +01:00
|
|
|
# include <concepts>
|
2023-01-08 16:47:53 +01:00
|
|
|
# include <cstdlib>
|
2022-09-22 21:53:13 +02:00
|
|
|
# include <iosfwd>
|
|
|
|
# include <limits>
|
2023-07-17 12:42:00 -04:00
|
|
|
# include <mutex>
|
2022-09-22 21:53:13 +02:00
|
|
|
# include <new>
|
|
|
|
# include <stdexcept>
|
2022-12-20 21:13:12 +01:00
|
|
|
# include <type_traits>
|
2022-11-02 20:27:42 +01:00
|
|
|
#endif
|
|
|
|
|
2024-09-16 15:06:20 -04:00
|
|
|
#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 23
|
|
|
|
# include <filesystem>
|
|
|
|
#endif
|
|
|
|
|
2021-04-20 12:03:32 -04:00
|
|
|
#endif // _LIBCPP_FSTREAM
|