Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/fmt/ostream.h was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 // Formatting library for C++ - std::ostream support
0002 //
0003 // Copyright (c) 2012 - present, Victor Zverovich
0004 // All rights reserved.
0005 //
0006 // For the license information refer to format.h.
0007 
0008 #ifndef FMT_OSTREAM_H_
0009 #define FMT_OSTREAM_H_
0010 
0011 #ifndef FMT_MODULE
0012 #  include <fstream>  // std::filebuf
0013 #endif
0014 
0015 #ifdef _WIN32
0016 #  ifdef __GLIBCXX__
0017 #    include <ext/stdio_filebuf.h>
0018 #    include <ext/stdio_sync_filebuf.h>
0019 #  endif
0020 #  include <io.h>
0021 #endif
0022 
0023 #include "chrono.h"  // formatbuf
0024 
0025 #ifdef _MSVC_STL_UPDATE
0026 #  define FMT_MSVC_STL_UPDATE _MSVC_STL_UPDATE
0027 #elif defined(_MSC_VER) && _MSC_VER < 1912  // VS 15.5
0028 #  define FMT_MSVC_STL_UPDATE _MSVC_LANG
0029 #else
0030 #  define FMT_MSVC_STL_UPDATE 0
0031 #endif
0032 
0033 FMT_BEGIN_NAMESPACE
0034 namespace detail {
0035 
0036 // Generate a unique explicit instantion in every translation unit using a tag
0037 // type in an anonymous namespace.
0038 namespace {
0039 struct file_access_tag {};
0040 }  // namespace
0041 template <typename Tag, typename BufType, FILE* BufType::*FileMemberPtr>
0042 class file_access {
0043   friend auto get_file(BufType& obj) -> FILE* { return obj.*FileMemberPtr; }
0044 };
0045 
0046 #if FMT_MSVC_STL_UPDATE
0047 template class file_access<file_access_tag, std::filebuf,
0048                            &std::filebuf::_Myfile>;
0049 auto get_file(std::filebuf&) -> FILE*;
0050 #endif
0051 
0052 // Write the content of buf to os.
0053 // It is a separate function rather than a part of vprint to simplify testing.
0054 template <typename Char>
0055 void write_buffer(std::basic_ostream<Char>& os, buffer<Char>& buf) {
0056   const Char* buf_data = buf.data();
0057   using unsigned_streamsize = make_unsigned_t<std::streamsize>;
0058   unsigned_streamsize size = buf.size();
0059   unsigned_streamsize max_size = to_unsigned(max_value<std::streamsize>());
0060   do {
0061     unsigned_streamsize n = size <= max_size ? size : max_size;
0062     os.write(buf_data, static_cast<std::streamsize>(n));
0063     buf_data += n;
0064     size -= n;
0065   } while (size != 0);
0066 }
0067 
0068 template <typename T> struct streamed_view {
0069   const T& value;
0070 };
0071 }  // namespace detail
0072 
0073 // Formats an object of type T that has an overloaded ostream operator<<.
0074 template <typename Char>
0075 struct basic_ostream_formatter : formatter<basic_string_view<Char>, Char> {
0076   void set_debug_format() = delete;
0077 
0078   template <typename T, typename Context>
0079   auto format(const T& value, Context& ctx) const -> decltype(ctx.out()) {
0080     auto buffer = basic_memory_buffer<Char>();
0081     auto&& formatbuf = detail::formatbuf<std::basic_streambuf<Char>>(buffer);
0082     auto&& output = std::basic_ostream<Char>(&formatbuf);
0083     output.imbue(std::locale::classic());  // The default is always unlocalized.
0084     output << value;
0085     output.exceptions(std::ios_base::failbit | std::ios_base::badbit);
0086     return formatter<basic_string_view<Char>, Char>::format(
0087         {buffer.data(), buffer.size()}, ctx);
0088   }
0089 };
0090 
0091 using ostream_formatter = basic_ostream_formatter<char>;
0092 
0093 template <typename T, typename Char>
0094 struct formatter<detail::streamed_view<T>, Char>
0095     : basic_ostream_formatter<Char> {
0096   template <typename Context>
0097   auto format(detail::streamed_view<T> view, Context& ctx) const
0098       -> decltype(ctx.out()) {
0099     return basic_ostream_formatter<Char>::format(view.value, ctx);
0100   }
0101 };
0102 
0103 /**
0104  * Returns a view that formats `value` via an ostream `operator<<`.
0105  *
0106  * **Example**:
0107  *
0108  *     fmt::print("Current thread id: {}\n",
0109  *                fmt::streamed(std::this_thread::get_id()));
0110  */
0111 template <typename T>
0112 constexpr auto streamed(const T& value) -> detail::streamed_view<T> {
0113   return {value};
0114 }
0115 
0116 inline void vprint(std::ostream& os, string_view fmt, format_args args) {
0117   auto buffer = memory_buffer();
0118   detail::vformat_to(buffer, fmt, args);
0119   FILE* f = nullptr;
0120 #if FMT_MSVC_STL_UPDATE && FMT_USE_RTTI
0121   if (auto* buf = dynamic_cast<std::filebuf*>(os.rdbuf()))
0122     f = detail::get_file(*buf);
0123 #elif defined(_WIN32) && defined(__GLIBCXX__) && FMT_USE_RTTI
0124   auto* rdbuf = os.rdbuf();
0125   if (auto* sfbuf = dynamic_cast<__gnu_cxx::stdio_sync_filebuf<char>*>(rdbuf))
0126     f = sfbuf->file();
0127   else if (auto* fbuf = dynamic_cast<__gnu_cxx::stdio_filebuf<char>*>(rdbuf))
0128     f = fbuf->file();
0129 #endif
0130 #ifdef _WIN32
0131   if (f) {
0132     int fd = _fileno(f);
0133     if (_isatty(fd)) {
0134       os.flush();
0135       if (detail::write_console(fd, {buffer.data(), buffer.size()})) return;
0136     }
0137   }
0138 #endif
0139   detail::ignore_unused(f);
0140   detail::write_buffer(os, buffer);
0141 }
0142 
0143 /**
0144  * Prints formatted data to the stream `os`.
0145  *
0146  * **Example**:
0147  *
0148  *     fmt::print(cerr, "Don't {}!", "panic");
0149  */
0150 FMT_EXPORT template <typename... T>
0151 void print(std::ostream& os, format_string<T...> fmt, T&&... args) {
0152   fmt::vargs<T...> vargs = {{args...}};
0153   if (detail::const_check(detail::use_utf8)) return vprint(os, fmt.str, vargs);
0154   auto buffer = memory_buffer();
0155   detail::vformat_to(buffer, fmt.str, vargs);
0156   detail::write_buffer(os, buffer);
0157 }
0158 
0159 FMT_EXPORT template <typename... T>
0160 void println(std::ostream& os, format_string<T...> fmt, T&&... args) {
0161   fmt::print(os, FMT_STRING("{}\n"),
0162              fmt::format(fmt, std::forward<T>(args)...));
0163 }
0164 
0165 FMT_END_NAMESPACE
0166 
0167 #endif  // FMT_OSTREAM_H_