Where Online Learning is simpler!
The C and C++ Include Header Files
cat -n /usr/include/c++/15/spanstream
1 // Streams based on std::span -*- C++ -*- 2 3 // Copyright The GNU Toolchain Authors. 4 // 5 // This file is part of the GNU ISO C++ Library. This library is free 6 // software; you can redistribute it and/or modify it under the 7 // terms of the GNU General Public License as published by the 8 // Free Software Foundation; either version 3, or (at your option) 9 // any later version. 10 11 // This library is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 16 // Under Section 7 of GPL version 3, you are granted additional 17 // permissions described in the GCC Runtime Library Exception, version 18 // 3.1, as published by the Free Software Foundation. 19 20 // You should have received a copy of the GNU General Public License and 21 // a copy of the GCC Runtime Library Exception along with this program; 22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 // <http://www.gnu.org/licenses/>. 24 25 /** @file spanstream 26 * This is a Standard C++ Library header. 27 */ 28 29 #ifndef _GLIBCXX_SPANSTREAM 30 #define _GLIBCXX_SPANSTREAM 1 31 32 #ifdef _GLIBCXX_SYSHDR 33 #pragma GCC system_header 34 #endif 35 36 #include <bits/requires_hosted.h> // iostreams 37 38 #define __glibcxx_want_spanstream 39 #include <bits/version.h> 40 41 #ifdef __cpp_lib_spanstream // C++ >= 23 && hosted && lib_span 42 #include <span> 43 #include <streambuf> 44 #include <istream> 45 #include <ostream> 46 #include <bits/ranges_base.h> 47 48 namespace std _GLIBCXX_VISIBILITY(default) 49 { 50 _GLIBCXX_BEGIN_NAMESPACE_VERSION 51 52 template<typename _CharT, typename _Traits> 53 class basic_spanbuf 54 : public basic_streambuf<_CharT, _Traits> 55 { 56 using __streambuf_type = basic_streambuf<_CharT, _Traits>; 57 58 public: 59 using char_type = _CharT; 60 using int_type = typename _Traits::int_type; 61 using pos_type = typename _Traits::pos_type; 62 using off_type = typename _Traits::off_type; 63 using traits_type = _Traits; 64 65 // [spanbuf.ctor], constructors 66 basic_spanbuf() : basic_spanbuf(ios_base::in | ios_base::out) 67 { } 68 69 explicit 70 basic_spanbuf(ios_base::openmode __which) 71 : __streambuf_type(), _M_mode(__which) 72 { } 73 74 explicit 75 basic_spanbuf(std::span<_CharT> __s, 76 ios_base::openmode __which = ios_base::in | ios_base::out) 77 : __streambuf_type(), _M_mode(__which) 78 { span(__s); } 79 80 basic_spanbuf(const basic_spanbuf&) = delete; 81 82 /** Move constructor. 83 * 84 * Transfers the buffer and pointers into the get and put areas from 85 * `__rhs` to `*this`. 86 * 87 * In this implementation `rhs` is left unchanged, 88 * but that is not guaranteed by the standard. 89 */ 90 basic_spanbuf(basic_spanbuf&& __rhs) 91 : __streambuf_type(__rhs), _M_mode(__rhs._M_mode), _M_buf(__rhs._M_buf) 92 { } 93 94 // [spanbuf.assign], assignment and swap 95 basic_spanbuf& operator=(const basic_spanbuf&) = delete; 96 97 basic_spanbuf& 98 operator=(basic_spanbuf&& __rhs) 99 { 100 basic_spanbuf(std::move(__rhs)).swap(*this); 101 return *this; 102 } 103 104 void 105 swap(basic_spanbuf& __rhs) 106 { 107 __streambuf_type::swap(__rhs); 108 std::swap(_M_mode, __rhs._M_mode); 109 std::swap(_M_buf, __rhs._M_buf); 110 } 111 112 // [spanbuf.members], member functions 113 [[nodiscard]] 114 std::span<_CharT> 115 span() const noexcept 116 { 117 if (_M_mode & ios_base::out) 118 return {this->pbase(), this->pptr()}; 119 else 120 return _M_buf; 121 } 122 123 void 124 span(std::span<_CharT> __s) noexcept 125 { 126 _M_buf = __s; 127 if (_M_mode & ios_base::out) 128 { 129 this->setp(__s.data(), __s.data() + __s.size()); 130 if (_M_mode & ios_base::ate) 131 this->pbump(__s.size()); 132 } 133 if (_M_mode & ios_base::in) 134 this->setg(__s.data(), __s.data(), __s.data() + __s.size()); 135 } 136 137 protected: 138 // [spanbuf.virtuals], overridden virtual functions 139 basic_streambuf<_CharT, _Traits>* 140 setbuf(_CharT* __s, streamsize __n) override 141 { 142 __glibcxx_assert(__n >= 0); 143 this->span(std::span<_CharT>(__s, __n)); 144 return this; 145 } 146 147 pos_type 148 seekoff(off_type __off, ios_base::seekdir __way, 149 ios_base::openmode __which = ios_base::in | ios_base::out) override 150 { 151 pos_type __ret = pos_type(off_type(-1)); 152 153 if (__way == ios_base::beg) 154 { 155 if (0 <= __off && __off <= _M_buf.size()) 156 { 157 if (__which & ios_base::in) 158 this->setg(this->eback(), this->eback() + __off, this->egptr()); 159 160 if (__which & ios_base::out) 161 { 162 this->setp(this->pbase(), this->epptr()); 163 this->pbump(__off); 164 } 165 166 __ret = pos_type(__off); 167 } 168 } 169 else 170 { 171 off_type __base{}; 172 __which &= (ios_base::in|ios_base::out); 173 174 if (__which == ios_base::out) 175 __base = this->pptr() - this->pbase(); 176 else if (__way == ios_base::cur) 177 { 178 if (__which == ios_base::in) 179 __base = this->gptr() - this->eback(); 180 else 181 return __ret; 182 } 183 else if (__way == ios_base::end) 184 __base = _M_buf.size(); 185 else /* way is not ios::beg, ios::cur, or ios::end */ [[unlikely]] 186 return __ret; 187 188 if (__builtin_add_overflow(__base, __off, &__off)) [[unlikely]] 189 return __ret; 190 191 if (__off < 0 || __off > _M_buf.size()) [[unlikely]] 192 return __ret; 193 194 if (__which & ios_base::in) 195 this->setg(this->eback(), this->eback() + __off, this->egptr()); 196 197 if (__which & ios_base::out) 198 { 199 this->setp(this->pbase(), this->epptr()); 200 this->pbump(__off); 201 } 202 203 __ret = pos_type(__off); 204 205 } 206 return __ret; 207 } 208 209 pos_type 210 seekpos(pos_type __sp, 211 ios_base::openmode __which = ios_base::in | ios_base::out) override 212 { return seekoff(off_type(__sp), ios_base::beg, __which); } 213 214 private: 215 216 ios_base::openmode _M_mode; 217 std::span<_CharT> _M_buf; 218 }; 219 220 template<typename _CharT, typename _Traits> 221 inline void 222 swap(basic_spanbuf<_CharT, _Traits>& __x, 223 basic_spanbuf<_CharT, _Traits>& __y) 224 { __x.swap(__y); } 225 226 using spanbuf = basic_spanbuf<char>; 227 using wspanbuf = basic_spanbuf<wchar_t>; 228 229 template<typename _CharT, typename _Traits> 230 class basic_ispanstream 231 : public basic_istream<_CharT, _Traits> 232 { 233 using __istream_type = basic_istream<_CharT, _Traits>; 234 235 public: 236 using char_type = _CharT; 237 using int_type = typename _Traits::int_type; 238 using pos_type = typename _Traits::pos_type; 239 using off_type = typename _Traits::off_type; 240 using traits_type = _Traits; 241 242 // [ispanstream.ctor], constructors 243 explicit 244 basic_ispanstream(std::span<_CharT> __s, 245 ios_base::openmode __which = ios_base::in) 246 : __istream_type(std::__addressof(_M_sb)), 247 _M_sb(__s, __which | ios_base::in) 248 { } 249 250 basic_ispanstream(const basic_ispanstream&) = delete; 251 252 basic_ispanstream(basic_ispanstream&& __rhs) 253 : __istream_type(std::move(__rhs)), _M_sb(std::move(__rhs._M_sb)) 254 { 255 __istream_type::set_rdbuf(std::addressof(_M_sb)); 256 } 257 258 template<typename _Ros> 259 requires ranges::borrowed_range<_Ros> 260 && (!convertible_to<_Ros, std::span<_CharT>>) 261 && convertible_to<_Ros, std::span<const _CharT>> 262 explicit 263 basic_ispanstream(_Ros&& __s) 264 : __istream_type(std::__addressof(_M_sb)), 265 _M_sb(ios_base::in) 266 { 267 std::span<const _CharT> __sp(std::forward<_Ros>(__s)); 268 _M_sb.span({const_cast<_CharT*>(__sp.data()), __sp.size()}); 269 } 270 271 // [ispanstream.assign], assignment and swap 272 basic_ispanstream& operator=(const basic_ispanstream&) = delete; 273 basic_ispanstream& operator=(basic_ispanstream&& __rhs) = default; 274 275 void 276 swap(basic_ispanstream& __rhs) 277 { 278 __istream_type::swap(__rhs); 279 _M_sb.swap(__rhs._M_sb); 280 } 281 282 // [ispanstream.members], member functions 283 [[nodiscard]] 284 basic_spanbuf<_CharT, _Traits>* 285 rdbuf() const noexcept 286 { 287 return const_cast<basic_spanbuf<_CharT, _Traits>*>(std::__addressof(_M_sb)); 288 } 289 290 [[nodiscard]] 291 std::span<const _CharT> 292 span() const noexcept 293 { return _M_sb.span(); } 294 295 void 296 span(std::span<_CharT> __s) noexcept 297 { return _M_sb.span(__s); } 298 299 template<typename _Ros> 300 requires ranges::borrowed_range<_Ros> 301 && (!convertible_to<_Ros, std::span<_CharT>>) 302 && convertible_to<_Ros, std::span<const _CharT>> 303 void 304 span(_Ros&& __s) noexcept 305 { 306 std::span<const _CharT> __sp(std::forward<_Ros>(__s)); 307 _M_sb.span({const_cast<_CharT*>(__sp.data()), __sp.size()}); 308 } 309 310 private: 311 basic_spanbuf<_CharT, _Traits> _M_sb; 312 }; 313 314 template<typename _CharT, typename _Traits> 315 inline void 316 swap(basic_ispanstream<_CharT, _Traits>& __x, 317 basic_ispanstream<_CharT, _Traits>& __y) 318 { __x.swap(__y); } 319 320 using ispanstream = basic_ispanstream<char>; 321 using wispanstream = basic_ispanstream<wchar_t>; 322 323 template<typename _CharT, typename _Traits> 324 class basic_ospanstream 325 : public basic_ostream<_CharT, _Traits> 326 { 327 using __ostream_type = basic_ostream<_CharT, _Traits>; 328 329 public: 330 using char_type = _CharT; 331 using int_type = typename _Traits::int_type; 332 using pos_type = typename _Traits::pos_type; 333 using off_type = typename _Traits::off_type; 334 using traits_type = _Traits; 335 336 // [ospanstream.ctor], constructors 337 explicit 338 basic_ospanstream(std::span<_CharT> __s, 339 ios_base::openmode __which = ios_base::out) 340 : __ostream_type(std::__addressof(_M_sb)), 341 _M_sb(__s, __which | ios_base::in) 342 { } 343 344 basic_ospanstream(const basic_ospanstream&) = delete; 345 346 basic_ospanstream(basic_ospanstream&& __rhs) 347 : __ostream_type(std::move(__rhs)), _M_sb(std::move(__rhs._M_sb)) 348 { 349 __ostream_type::set_rdbuf(std::addressof(_M_sb)); 350 } 351 352 // [ospanstream.assign], assignment and swap 353 basic_ospanstream& operator=(const basic_ospanstream&) = delete; 354 basic_ospanstream& operator=(basic_ospanstream&& __rhs) = default; 355 356 void 357 swap(basic_ospanstream& __rhs) 358 { 359 __ostream_type::swap(__rhs); 360 _M_sb.swap(__rhs._M_sb); 361 } 362 363 // [ospanstream.members], member functions 364 [[nodiscard]] 365 basic_spanbuf<_CharT, _Traits>* 366 rdbuf() const noexcept 367 { 368 return const_cast<basic_spanbuf<_CharT, _Traits>*>(std::__addressof(_M_sb)); 369 } 370 371 [[nodiscard]] 372 std::span<_CharT> 373 span() const noexcept 374 { return _M_sb.span(); } 375 376 void 377 span(std::span<_CharT> __s) noexcept 378 { return _M_sb.span(__s); } 379 380 private: 381 basic_spanbuf<_CharT, _Traits> _M_sb; 382 }; 383 384 template<typename _CharT, typename _Traits> 385 inline void 386 swap(basic_ospanstream<_CharT, _Traits>& __x, 387 basic_ospanstream<_CharT, _Traits>& __y) 388 { __x.swap(__y); } 389 390 using ospanstream = basic_ospanstream<char>; 391 using wospanstream = basic_ospanstream<wchar_t>; 392 393 template<typename _CharT, typename _Traits> 394 class basic_spanstream 395 : public basic_iostream<_CharT, _Traits> 396 { 397 using __iostream_type = basic_iostream<_CharT, _Traits>; 398 399 public: 400 using char_type = _CharT; 401 using int_type = typename _Traits::int_type; 402 using pos_type = typename _Traits::pos_type; 403 using off_type = typename _Traits::off_type; 404 using traits_type = _Traits; 405 406 // [spanstream.ctor], constructors 407 explicit 408 basic_spanstream(std::span<_CharT> __s, 409 ios_base::openmode __which = ios_base::out | ios_base::in) 410 : __iostream_type(std::__addressof(_M_sb)), 411 _M_sb(__s, __which) 412 { } 413 414 basic_spanstream(const basic_spanstream&) = delete; 415 416 basic_spanstream(basic_spanstream&& __rhs) 417 : __iostream_type(std::move(__rhs)), _M_sb(std::move(__rhs._M_sb)) 418 { 419 __iostream_type::set_rdbuf(std::addressof(_M_sb)); 420 } 421 422 // [spanstream.assign], assignment and swap 423 basic_spanstream& operator=(const basic_spanstream&) = delete; 424 basic_spanstream& operator=(basic_spanstream&& __rhs) = default; 425 426 void 427 swap(basic_spanstream& __rhs) 428 { 429 __iostream_type::swap(__rhs); 430 _M_sb.swap(__rhs._M_sb); 431 } 432 433 // [spanstream.members], members 434 [[nodiscard]] 435 basic_spanbuf<_CharT, _Traits>* 436 rdbuf() const noexcept 437 { 438 return const_cast<basic_spanbuf<_CharT, _Traits>*>(std::__addressof(_M_sb)); 439 } 440 441 [[nodiscard]] 442 std::span<_CharT> 443 span() const noexcept 444 { return _M_sb.span(); } 445 446 void 447 span(std::span<_CharT> __s) noexcept 448 { return _M_sb.span(__s); } 449 450 private: 451 basic_spanbuf<_CharT, _Traits> _M_sb; 452 }; 453 454 template<typename _CharT, typename _Traits> 455 inline void 456 swap(basic_spanstream<_CharT, _Traits>& __x, 457 basic_spanstream<_CharT, _Traits>& __y) 458 { __x.swap(__y); } 459 460 using spanstream = basic_spanstream<char>; 461 using wspanstream = basic_spanstream<wchar_t>; 462 463 _GLIBCXX_END_NAMESPACE_VERSION 464 } // namespace std 465 #endif // __cpp_lib_spanstream 466 #endif // _GLIBCXX_SPANSTREAM