Nikolas Klauser b9a2658a3e
[libc++][C++03] Use __cxx03/ headers in C++03 mode (#109002)
This patch implements the forwarding to frozen C++03 headers as
discussed in
https://discourse.llvm.org/t/rfc-freezing-c-03-headers-in-libc. In the
RFC, we initially proposed selecting the right headers from the Clang
driver, however consensus seemed to steer towards handling this in the
library itself. This patch implements that direction.

At a high level, the changes basically amount to making each public
header look like this:

```
// inside <vector>
#ifdef _LIBCPP_CXX03_LANG
#  include <__cxx03/vector>
#else
  // normal <vector> content
#endif
```

In most cases, public headers are simple umbrella headers so there isn't
much code in the #else branch. In other cases, the #else branch contains
the actual implementation of the header.
2024-12-21 13:01:48 +01:00

570 lines
18 KiB
C++

// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
#ifndef _LIBCPP_IOMANIP
#define _LIBCPP_IOMANIP
/*
iomanip synopsis
namespace std {
// types T1, T2, ... are unspecified implementation types
T1 resetiosflags(ios_base::fmtflags mask);
T2 setiosflags (ios_base::fmtflags mask);
T3 setbase(int base);
template<charT> T4 setfill(charT c);
T5 setprecision(int n);
T6 setw(int n);
template <class moneyT> T7 get_money(moneyT& mon, bool intl = false);
template <class charT, class moneyT> T8 put_money(const moneyT& mon, bool intl = false);
template <class charT> T9 get_time(struct tm* tmb, const charT* fmt);
template <class charT> T10 put_time(const struct tm* tmb, const charT* fmt);
template <class charT>
T11 quoted(const charT* s, charT delim=charT('"'), charT escape=charT('\\')); // C++14
template <class charT, class traits, class Allocator>
T12 quoted(const basic_string<charT, traits, Allocator>& s,
charT delim=charT('"'), charT escape=charT('\\')); // C++14
template <class charT, class traits, class Allocator>
T13 quoted(basic_string<charT, traits, Allocator>& s,
charT delim=charT('"'), charT escape=charT('\\')); // C++14
} // std
*/
#if __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
# include <__cxx03/iomanip>
#else
# include <__config>
# if _LIBCPP_HAS_LOCALIZATION
# include <__ostream/put_character_sequence.h>
# include <ios>
# include <iosfwd>
# include <locale>
# include <version>
# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
# endif
_LIBCPP_BEGIN_NAMESPACE_STD
// resetiosflags
class __iom_t1 {
ios_base::fmtflags __mask_;
public:
_LIBCPP_HIDE_FROM_ABI explicit __iom_t1(ios_base::fmtflags __m) : __mask_(__m) {}
template <class _CharT, class _Traits>
friend _LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&
operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t1& __x) {
__is.unsetf(__x.__mask_);
return __is;
}
template <class _CharT, class _Traits>
friend _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t1& __x) {
__os.unsetf(__x.__mask_);
return __os;
}
};
inline _LIBCPP_HIDE_FROM_ABI __iom_t1 resetiosflags(ios_base::fmtflags __mask) { return __iom_t1(__mask); }
// setiosflags
class __iom_t2 {
ios_base::fmtflags __mask_;
public:
_LIBCPP_HIDE_FROM_ABI explicit __iom_t2(ios_base::fmtflags __m) : __mask_(__m) {}
template <class _CharT, class _Traits>
friend _LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&
operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t2& __x) {
__is.setf(__x.__mask_);
return __is;
}
template <class _CharT, class _Traits>
friend _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t2& __x) {
__os.setf(__x.__mask_);
return __os;
}
};
inline _LIBCPP_HIDE_FROM_ABI __iom_t2 setiosflags(ios_base::fmtflags __mask) { return __iom_t2(__mask); }
// setbase
class __iom_t3 {
int __base_;
public:
_LIBCPP_HIDE_FROM_ABI explicit __iom_t3(int __b) : __base_(__b) {}
template <class _CharT, class _Traits>
friend _LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&
operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t3& __x) {
__is.setf(__x.__base_ == 8 ? ios_base::oct
: __x.__base_ == 10 ? ios_base::dec
: __x.__base_ == 16 ? ios_base::hex
: ios_base::fmtflags(0),
ios_base::basefield);
return __is;
}
template <class _CharT, class _Traits>
friend _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t3& __x) {
__os.setf(__x.__base_ == 8 ? ios_base::oct
: __x.__base_ == 10 ? ios_base::dec
: __x.__base_ == 16 ? ios_base::hex
: ios_base::fmtflags(0),
ios_base::basefield);
return __os;
}
};
inline _LIBCPP_HIDE_FROM_ABI __iom_t3 setbase(int __base) { return __iom_t3(__base); }
// setfill
template <class _CharT>
class __iom_t4 {
_CharT __fill_;
public:
_LIBCPP_HIDE_FROM_ABI explicit __iom_t4(_CharT __c) : __fill_(__c) {}
template <class _Traits>
friend _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t4& __x) {
__os.fill(__x.__fill_);
return __os;
}
};
template <class _CharT>
inline _LIBCPP_HIDE_FROM_ABI __iom_t4<_CharT> setfill(_CharT __c) {
return __iom_t4<_CharT>(__c);
}
// setprecision
class __iom_t5 {
int __n_;
public:
_LIBCPP_HIDE_FROM_ABI explicit __iom_t5(int __n) : __n_(__n) {}
template <class _CharT, class _Traits>
friend _LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&
operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t5& __x) {
__is.precision(__x.__n_);
return __is;
}
template <class _CharT, class _Traits>
friend _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t5& __x) {
__os.precision(__x.__n_);
return __os;
}
};
inline _LIBCPP_HIDE_FROM_ABI __iom_t5 setprecision(int __n) { return __iom_t5(__n); }
// setw
class __iom_t6 {
int __n_;
public:
_LIBCPP_HIDE_FROM_ABI explicit __iom_t6(int __n) : __n_(__n) {}
template <class _CharT, class _Traits>
friend _LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&
operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t6& __x) {
__is.width(__x.__n_);
return __is;
}
template <class _CharT, class _Traits>
friend _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t6& __x) {
__os.width(__x.__n_);
return __os;
}
};
inline _LIBCPP_HIDE_FROM_ABI __iom_t6 setw(int __n) { return __iom_t6(__n); }
// get_money
template <class _MoneyT>
class __iom_t7;
template <class _CharT, class _Traits, class _MoneyT>
_LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&
operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t7<_MoneyT>& __x);
template <class _MoneyT>
class __iom_t7 {
_MoneyT& __mon_;
bool __intl_;
public:
_LIBCPP_HIDE_FROM_ABI __iom_t7(_MoneyT& __mon, bool __intl) : __mon_(__mon), __intl_(__intl) {}
template <class _CharT, class _Traits, class _Mp>
friend basic_istream<_CharT, _Traits>& operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t7<_Mp>& __x);
};
template <class _CharT, class _Traits, class _MoneyT>
_LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&
operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t7<_MoneyT>& __x) {
# if _LIBCPP_HAS_EXCEPTIONS
try {
# endif // _LIBCPP_HAS_EXCEPTIONS
typename basic_istream<_CharT, _Traits>::sentry __s(__is);
if (__s) {
typedef istreambuf_iterator<_CharT, _Traits> _Ip;
typedef money_get<_CharT, _Ip> _Fp;
ios_base::iostate __err = ios_base::goodbit;
const _Fp& __mf = std::use_facet<_Fp>(__is.getloc());
__mf.get(_Ip(__is), _Ip(), __x.__intl_, __is, __err, __x.__mon_);
__is.setstate(__err);
}
# if _LIBCPP_HAS_EXCEPTIONS
} catch (...) {
__is.__set_badbit_and_consider_rethrow();
}
# endif // _LIBCPP_HAS_EXCEPTIONS
return __is;
}
template <class _MoneyT>
inline _LIBCPP_HIDE_FROM_ABI __iom_t7<_MoneyT> get_money(_MoneyT& __mon, bool __intl = false) {
return __iom_t7<_MoneyT>(__mon, __intl);
}
// put_money
template <class _MoneyT>
class __iom_t8;
template <class _CharT, class _Traits, class _MoneyT>
_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t8<_MoneyT>& __x);
template <class _MoneyT>
class __iom_t8 {
const _MoneyT& __mon_;
bool __intl_;
public:
_LIBCPP_HIDE_FROM_ABI __iom_t8(const _MoneyT& __mon, bool __intl) : __mon_(__mon), __intl_(__intl) {}
template <class _CharT, class _Traits, class _Mp>
friend basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t8<_Mp>& __x);
};
template <class _CharT, class _Traits, class _MoneyT>
_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t8<_MoneyT>& __x) {
# if _LIBCPP_HAS_EXCEPTIONS
try {
# endif // _LIBCPP_HAS_EXCEPTIONS
typename basic_ostream<_CharT, _Traits>::sentry __s(__os);
if (__s) {
typedef ostreambuf_iterator<_CharT, _Traits> _Op;
typedef money_put<_CharT, _Op> _Fp;
const _Fp& __mf = std::use_facet<_Fp>(__os.getloc());
if (__mf.put(_Op(__os), __x.__intl_, __os, __os.fill(), __x.__mon_).failed())
__os.setstate(ios_base::badbit);
}
# if _LIBCPP_HAS_EXCEPTIONS
} catch (...) {
__os.__set_badbit_and_consider_rethrow();
}
# endif // _LIBCPP_HAS_EXCEPTIONS
return __os;
}
template <class _MoneyT>
inline _LIBCPP_HIDE_FROM_ABI __iom_t8<_MoneyT> put_money(const _MoneyT& __mon, bool __intl = false) {
return __iom_t8<_MoneyT>(__mon, __intl);
}
// get_time
template <class _CharT>
class __iom_t9;
template <class _CharT, class _Traits>
_LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&
operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t9<_CharT>& __x);
template <class _CharT>
class __iom_t9 {
tm* __tm_;
const _CharT* __fmt_;
public:
_LIBCPP_HIDE_FROM_ABI __iom_t9(tm* __tm, const _CharT* __fmt) : __tm_(__tm), __fmt_(__fmt) {}
template <class _Cp, class _Traits>
friend basic_istream<_Cp, _Traits>& operator>>(basic_istream<_Cp, _Traits>& __is, const __iom_t9<_Cp>& __x);
};
template <class _CharT, class _Traits>
_LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&
operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t9<_CharT>& __x) {
# if _LIBCPP_HAS_EXCEPTIONS
try {
# endif // _LIBCPP_HAS_EXCEPTIONS
typename basic_istream<_CharT, _Traits>::sentry __s(__is);
if (__s) {
typedef istreambuf_iterator<_CharT, _Traits> _Ip;
typedef time_get<_CharT, _Ip> _Fp;
ios_base::iostate __err = ios_base::goodbit;
const _Fp& __tf = std::use_facet<_Fp>(__is.getloc());
__tf.get(_Ip(__is), _Ip(), __is, __err, __x.__tm_, __x.__fmt_, __x.__fmt_ + _Traits::length(__x.__fmt_));
__is.setstate(__err);
}
# if _LIBCPP_HAS_EXCEPTIONS
} catch (...) {
__is.__set_badbit_and_consider_rethrow();
}
# endif // _LIBCPP_HAS_EXCEPTIONS
return __is;
}
template <class _CharT>
inline _LIBCPP_HIDE_FROM_ABI __iom_t9<_CharT> get_time(tm* __tm, const _CharT* __fmt) {
return __iom_t9<_CharT>(__tm, __fmt);
}
// put_time
template <class _CharT>
class __iom_t10;
template <class _CharT, class _Traits>
_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t10<_CharT>& __x);
template <class _CharT>
class __iom_t10 {
const tm* __tm_;
const _CharT* __fmt_;
public:
_LIBCPP_HIDE_FROM_ABI __iom_t10(const tm* __tm, const _CharT* __fmt) : __tm_(__tm), __fmt_(__fmt) {}
template <class _Cp, class _Traits>
friend basic_ostream<_Cp, _Traits>& operator<<(basic_ostream<_Cp, _Traits>& __os, const __iom_t10<_Cp>& __x);
};
template <class _CharT, class _Traits>
_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t10<_CharT>& __x) {
# if _LIBCPP_HAS_EXCEPTIONS
try {
# endif // _LIBCPP_HAS_EXCEPTIONS
typename basic_ostream<_CharT, _Traits>::sentry __s(__os);
if (__s) {
typedef ostreambuf_iterator<_CharT, _Traits> _Op;
typedef time_put<_CharT, _Op> _Fp;
const _Fp& __tf = std::use_facet<_Fp>(__os.getloc());
if (__tf.put(_Op(__os), __os, __os.fill(), __x.__tm_, __x.__fmt_, __x.__fmt_ + _Traits::length(__x.__fmt_))
.failed())
__os.setstate(ios_base::badbit);
}
# if _LIBCPP_HAS_EXCEPTIONS
} catch (...) {
__os.__set_badbit_and_consider_rethrow();
}
# endif // _LIBCPP_HAS_EXCEPTIONS
return __os;
}
template <class _CharT>
inline _LIBCPP_HIDE_FROM_ABI __iom_t10<_CharT> put_time(const tm* __tm, const _CharT* __fmt) {
return __iom_t10<_CharT>(__tm, __fmt);
}
template <class _CharT, class _Traits>
_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>& __quoted_output(
basic_ostream<_CharT, _Traits>& __os,
const _CharT* __first,
const _CharT* __last,
_CharT __delim,
_CharT __escape) {
basic_string<_CharT, _Traits> __str;
__str.push_back(__delim);
for (; __first != __last; ++__first) {
if (_Traits::eq(*__first, __escape) || _Traits::eq(*__first, __delim))
__str.push_back(__escape);
__str.push_back(*__first);
}
__str.push_back(__delim);
return std::__put_character_sequence(__os, __str.data(), __str.size());
}
template <class _CharT, class _Traits, class _String>
_LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&
__quoted_input(basic_istream<_CharT, _Traits>& __is, _String& __string, _CharT __delim, _CharT __escape) {
__string.clear();
_CharT __c;
__is >> __c;
if (__is.fail())
return __is;
if (!_Traits::eq(__c, __delim)) {
// no delimiter, read the whole string
__is.unget();
__is >> __string;
return __is;
}
__save_flags<_CharT, _Traits> __sf(__is);
std::noskipws(__is);
while (true) {
__is >> __c;
if (__is.fail())
break;
if (_Traits::eq(__c, __escape)) {
__is >> __c;
if (__is.fail())
break;
} else if (_Traits::eq(__c, __delim))
break;
__string.push_back(__c);
}
return __is;
}
template <class _CharT, class _Traits>
struct _LIBCPP_HIDDEN __quoted_output_proxy {
const _CharT* __first_;
const _CharT* __last_;
_CharT __delim_;
_CharT __escape_;
_LIBCPP_HIDE_FROM_ABI explicit __quoted_output_proxy(const _CharT* __f, const _CharT* __l, _CharT __d, _CharT __e)
: __first_(__f), __last_(__l), __delim_(__d), __escape_(__e) {}
template <class _T2, __enable_if_t<_IsSame<_Traits, void>::value || _IsSame<_Traits, _T2>::value, int> = 0>
friend _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _T2>&
operator<<(basic_ostream<_CharT, _T2>& __os, const __quoted_output_proxy& __p) {
return std::__quoted_output(__os, __p.__first_, __p.__last_, __p.__delim_, __p.__escape_);
}
};
template <class _CharT, class _Traits, class _Allocator>
struct _LIBCPP_HIDDEN __quoted_proxy {
basic_string<_CharT, _Traits, _Allocator>& __string_;
_CharT __delim_;
_CharT __escape_;
_LIBCPP_HIDE_FROM_ABI explicit __quoted_proxy(basic_string<_CharT, _Traits, _Allocator>& __s, _CharT __d, _CharT __e)
: __string_(__s), __delim_(__d), __escape_(__e) {}
friend _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
operator<<(basic_ostream<_CharT, _Traits>& __os, const __quoted_proxy& __p) {
return std::__quoted_output(
__os, __p.__string_.data(), __p.__string_.data() + __p.__string_.size(), __p.__delim_, __p.__escape_);
}
friend _LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&
operator>>(basic_istream<_CharT, _Traits>& __is, const __quoted_proxy& __p) {
return std::__quoted_input(__is, __p.__string_, __p.__delim_, __p.__escape_);
}
};
template <class _CharT, class _Traits, class _Allocator>
_LIBCPP_HIDE_FROM_ABI __quoted_output_proxy<_CharT, _Traits>
__quoted(const basic_string<_CharT, _Traits, _Allocator>& __s,
_CharT __delim = _CharT('"'),
_CharT __escape = _CharT('\\')) {
return __quoted_output_proxy<_CharT, _Traits>(__s.data(), __s.data() + __s.size(), __delim, __escape);
}
template <class _CharT, class _Traits, class _Allocator>
_LIBCPP_HIDE_FROM_ABI __quoted_proxy<_CharT, _Traits, _Allocator>
__quoted(basic_string<_CharT, _Traits, _Allocator>& __s, _CharT __delim = _CharT('"'), _CharT __escape = _CharT('\\')) {
return __quoted_proxy<_CharT, _Traits, _Allocator>(__s, __delim, __escape);
}
# if _LIBCPP_STD_VER >= 14
template <class _CharT>
_LIBCPP_HIDE_FROM_ABI auto quoted(const _CharT* __s, _CharT __delim = _CharT('"'), _CharT __escape = _CharT('\\')) {
const _CharT* __end = __s;
while (*__end)
++__end;
return __quoted_output_proxy<_CharT, void>(__s, __end, __delim, __escape);
}
template <class _CharT, class _Traits, class _Allocator>
_LIBCPP_HIDE_FROM_ABI auto
quoted(const basic_string<_CharT, _Traits, _Allocator>& __s,
_CharT __delim = _CharT('"'),
_CharT __escape = _CharT('\\')) {
return __quoted_output_proxy<_CharT, _Traits>(__s.data(), __s.data() + __s.size(), __delim, __escape);
}
template <class _CharT, class _Traits, class _Allocator>
_LIBCPP_HIDE_FROM_ABI auto
quoted(basic_string<_CharT, _Traits, _Allocator>& __s, _CharT __delim = _CharT('"'), _CharT __escape = _CharT('\\')) {
return __quoted_proxy<_CharT, _Traits, _Allocator>(__s, __delim, __escape);
}
template <class _CharT, class _Traits>
_LIBCPP_HIDE_FROM_ABI auto
quoted(basic_string_view<_CharT, _Traits> __sv, _CharT __delim = _CharT('"'), _CharT __escape = _CharT('\\')) {
return __quoted_output_proxy<_CharT, _Traits>(__sv.data(), __sv.data() + __sv.size(), __delim, __escape);
}
# endif // _LIBCPP_STD_VER >= 14
_LIBCPP_END_NAMESPACE_STD
# endif // _LIBCPP_HAS_LOCALIZATION
# if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
# include <array>
# include <bitset>
# include <deque>
# include <format>
# include <functional>
# include <istream>
# include <ostream>
# include <print>
# include <queue>
# include <stack>
# include <unordered_map>
# include <vector>
# endif
#endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
#endif // _LIBCPP_IOMANIP