File indexing completed on 2025-12-16 09:40:55
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #ifndef ABSL_RANDOM_INTERNAL_IOSTREAM_STATE_SAVER_H_
0016 #define ABSL_RANDOM_INTERNAL_IOSTREAM_STATE_SAVER_H_
0017
0018 #include <cmath>
0019 #include <iostream>
0020 #include <limits>
0021 #include <type_traits>
0022
0023 #include "absl/meta/type_traits.h"
0024 #include "absl/numeric/int128.h"
0025
0026 namespace absl {
0027 ABSL_NAMESPACE_BEGIN
0028 namespace random_internal {
0029
0030
0031 template <typename T>
0032 class null_state_saver {
0033 public:
0034 using stream_type = T;
0035 using flags_type = std::ios_base::fmtflags;
0036
0037 null_state_saver(T&, flags_type) {}
0038 ~null_state_saver() {}
0039 };
0040
0041
0042
0043
0044 template <typename OStream>
0045 class ostream_state_saver {
0046 public:
0047 using ostream_type = OStream;
0048 using flags_type = std::ios_base::fmtflags;
0049 using fill_type = typename ostream_type::char_type;
0050 using precision_type = std::streamsize;
0051
0052 ostream_state_saver(ostream_type& os,
0053 flags_type flags, fill_type fill)
0054 : os_(os),
0055 flags_(os.flags(flags)),
0056 fill_(os.fill(fill)),
0057 precision_(os.precision()) {
0058
0059 }
0060
0061 ~ostream_state_saver() {
0062
0063 os_.precision(precision_);
0064 os_.fill(fill_);
0065 os_.flags(flags_);
0066 }
0067
0068 private:
0069 ostream_type& os_;
0070 const flags_type flags_;
0071 const fill_type fill_;
0072 const precision_type precision_;
0073 };
0074
0075 #if defined(__NDK_MAJOR__) && __NDK_MAJOR__ < 16
0076 #define ABSL_RANDOM_INTERNAL_IOSTREAM_HEXFLOAT 1
0077 #else
0078 #define ABSL_RANDOM_INTERNAL_IOSTREAM_HEXFLOAT 0
0079 #endif
0080
0081 template <typename CharT, typename Traits>
0082 ostream_state_saver<std::basic_ostream<CharT, Traits>> make_ostream_state_saver(
0083 std::basic_ostream<CharT, Traits>& os,
0084 std::ios_base::fmtflags flags = std::ios_base::dec | std::ios_base::left |
0085 #if ABSL_RANDOM_INTERNAL_IOSTREAM_HEXFLOAT
0086 std::ios_base::fixed |
0087 #endif
0088 std::ios_base::scientific) {
0089 using result_type = ostream_state_saver<std::basic_ostream<CharT, Traits>>;
0090 return result_type(os, flags, os.widen(' '));
0091 }
0092
0093 template <typename T>
0094 typename absl::enable_if_t<!std::is_base_of<std::ios_base, T>::value,
0095 null_state_saver<T>>
0096 make_ostream_state_saver(T& is,
0097 std::ios_base::fmtflags flags = std::ios_base::dec) {
0098 std::cerr << "null_state_saver";
0099 using result_type = null_state_saver<T>;
0100 return result_type(is, flags);
0101 }
0102
0103
0104
0105
0106 template <typename T>
0107 struct stream_precision_helper {
0108
0109 static constexpr int kPrecision =
0110 (std::numeric_limits<T>::max_digits10 > std::numeric_limits<T>::digits10)
0111 ? std::numeric_limits<T>::max_digits10
0112 : (std::numeric_limits<T>::digits10 + 3);
0113 };
0114
0115 template <>
0116 struct stream_precision_helper<float> {
0117 static constexpr int kPrecision = 9;
0118 };
0119 template <>
0120 struct stream_precision_helper<double> {
0121 static constexpr int kPrecision = 17;
0122 };
0123 template <>
0124 struct stream_precision_helper<long double> {
0125 static constexpr int kPrecision = 36;
0126 };
0127
0128
0129
0130
0131 template <typename IStream>
0132 class istream_state_saver {
0133 public:
0134 using istream_type = IStream;
0135 using flags_type = std::ios_base::fmtflags;
0136
0137 istream_state_saver(istream_type& is,
0138 flags_type flags)
0139 : is_(is), flags_(is.flags(flags)) {}
0140
0141 ~istream_state_saver() { is_.flags(flags_); }
0142
0143 private:
0144 istream_type& is_;
0145 flags_type flags_;
0146 };
0147
0148 template <typename CharT, typename Traits>
0149 istream_state_saver<std::basic_istream<CharT, Traits>> make_istream_state_saver(
0150 std::basic_istream<CharT, Traits>& is,
0151 std::ios_base::fmtflags flags = std::ios_base::dec |
0152 std::ios_base::scientific |
0153 std::ios_base::skipws) {
0154 using result_type = istream_state_saver<std::basic_istream<CharT, Traits>>;
0155 return result_type(is, flags);
0156 }
0157
0158 template <typename T>
0159 typename absl::enable_if_t<!std::is_base_of<std::ios_base, T>::value,
0160 null_state_saver<T>>
0161 make_istream_state_saver(T& is,
0162 std::ios_base::fmtflags flags = std::ios_base::dec) {
0163 using result_type = null_state_saver<T>;
0164 return result_type(is, flags);
0165 }
0166
0167
0168
0169
0170
0171
0172
0173 template <typename T>
0174 struct stream_format_type
0175 : public std::conditional<(sizeof(T) == sizeof(char)), int, T> {};
0176
0177
0178
0179
0180 template <typename T>
0181 struct stream_u128_helper;
0182
0183 template <>
0184 struct stream_u128_helper<absl::uint128> {
0185 template <typename IStream>
0186 inline absl::uint128 read(IStream& in) {
0187 uint64_t h = 0;
0188 uint64_t l = 0;
0189 in >> h >> l;
0190 return absl::MakeUint128(h, l);
0191 }
0192
0193 template <typename OStream>
0194 inline void write(absl::uint128 val, OStream& out) {
0195 uint64_t h = absl::Uint128High64(val);
0196 uint64_t l = absl::Uint128Low64(val);
0197 out << h << out.fill() << l;
0198 }
0199 };
0200
0201 #ifdef ABSL_HAVE_INTRINSIC_INT128
0202 template <>
0203 struct stream_u128_helper<__uint128_t> {
0204 template <typename IStream>
0205 inline __uint128_t read(IStream& in) {
0206 uint64_t h = 0;
0207 uint64_t l = 0;
0208 in >> h >> l;
0209 return (static_cast<__uint128_t>(h) << 64) | l;
0210 }
0211
0212 template <typename OStream>
0213 inline void write(__uint128_t val, OStream& out) {
0214 uint64_t h = static_cast<uint64_t>(val >> 64u);
0215 uint64_t l = static_cast<uint64_t>(val);
0216 out << h << out.fill() << l;
0217 }
0218 };
0219 #endif
0220
0221 template <typename FloatType, typename IStream>
0222 inline FloatType read_floating_point(IStream& is) {
0223 static_assert(std::is_floating_point<FloatType>::value, "");
0224 FloatType dest;
0225 is >> dest;
0226
0227
0228
0229
0230
0231
0232
0233 if (is.fail() &&
0234 (std::fabs(dest) == (std::numeric_limits<FloatType>::min)() ||
0235 std::fpclassify(dest) == FP_SUBNORMAL)) {
0236 is.clear(is.rdstate() & (~std::ios_base::failbit));
0237 }
0238 return dest;
0239 }
0240
0241 }
0242 ABSL_NAMESPACE_END
0243 }
0244
0245 #endif