ostdstream.hpp 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. // Copyright (c) 2018-2025 Jean-Louis Leroy
  2. // Distributed under the Boost Software License, Version 1.0.
  3. // See accompanying file LICENSE_1_0.txt
  4. // or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. #ifndef BOOST_OPENMETHOD_DETAIL_OSTDSTREAM_HPP
  6. #define BOOST_OPENMETHOD_DETAIL_OSTDSTREAM_HPP
  7. #include <array>
  8. #include <cstdio>
  9. #include <charconv>
  10. #include <random>
  11. namespace boost::openmethod {
  12. namespace detail {
  13. // -----------------------------------------------------------------------------
  14. // lightweight ostream
  15. struct ostdstream {
  16. FILE* stream = nullptr;
  17. ostdstream(FILE* s = nullptr) : stream(s) {
  18. }
  19. void on(FILE* s = stderr) {
  20. this->stream = s;
  21. }
  22. void off() {
  23. stream = nullptr;
  24. }
  25. auto is_on() const -> bool {
  26. return stream != nullptr;
  27. }
  28. };
  29. struct ostderr : ostdstream {
  30. ostderr() : ostdstream(stderr) {
  31. }
  32. };
  33. inline ostdstream cerr;
  34. inline auto operator<<(ostdstream& os, const char* str) -> ostdstream& {
  35. if (os.stream) {
  36. fputs(str, os.stream);
  37. }
  38. return os;
  39. }
  40. inline auto
  41. operator<<(ostdstream& os, const std::string_view& view) -> ostdstream& {
  42. if (os.stream) {
  43. fwrite(view.data(), sizeof(*view.data()), view.length(), os.stream);
  44. }
  45. return os;
  46. }
  47. inline auto operator<<(ostdstream& os, const void* value) -> ostdstream& {
  48. if (os.stream) {
  49. std::array<char, 20> str;
  50. auto end = std::to_chars(
  51. str.data(), str.data() + str.size(),
  52. reinterpret_cast<uintptr_t>(value), 16)
  53. .ptr;
  54. os << std::string_view(str.data(), end - str.data());
  55. }
  56. return os;
  57. }
  58. inline auto operator<<(ostdstream& os, void (*value)()) -> ostdstream& {
  59. if (os.stream) {
  60. std::array<char, 20> str;
  61. auto end = std::to_chars(
  62. str.data(), str.data() + str.size(),
  63. reinterpret_cast<uintptr_t>(value), 16)
  64. .ptr;
  65. os << std::string_view(str.data(), end - str.data());
  66. }
  67. return os;
  68. }
  69. inline auto operator<<(ostdstream& os, std::size_t value) -> ostdstream& {
  70. if (os.stream) {
  71. std::array<char, 20> str;
  72. auto end =
  73. std::to_chars(str.data(), str.data() + str.size(), value).ptr;
  74. os << std::string_view(str.data(), end - str.data());
  75. }
  76. return os;
  77. }
  78. } // namespace detail
  79. } // namespace boost::openmethod
  80. #endif