Skip to main content
added 9 characters in body
Source Link
bluedragon
  • 365
  • 1
  • 9

also, does it make sense to replace class _stdout_object while their pointers with something like

namespace detail {
  class _stdout_object;
  class _stderr_object;
} // namespace detail

namespace printing_shortcuts {

  template <typename T> detail::_stdout_object *operator<<(detail::_stdout_object *, const T &arg) {
    auto s = to_string(arg);
    fwrite(s.data(), 1, s.size(), stdout);
    return nullptr;
  }

  template <typename T> detail::_stderr_object *operator<<(detail::_stderr_object *, const T &arg) {
    auto s = to_string(arg);
    fwrite(s.data(), 1, s.size(), stderr);
    return nullptr;
  }

  detail::_stdout_object *print() { return nullptr; }
  detail::_stderr_object *debug() { return nullptr; }

} // namespace printing_shortcuts

also, does it make sense to replace class _stdout_object while their pointers with something like

namespace detail {
  class _stdout_object;
  class _stderr_object;
} // namespace detail

namespace printing_shortcuts {

  template <typename T> detail::_stdout_object *operator<<(detail::_stdout_object *, const T &arg) {
    auto s = to_string(arg);
    fwrite(s.data(), 1, s.size(), stdout);
    return nullptr;
  }

  template <typename T> detail::_stderr_object *operator<<(detail::_stderr_object *, const T &arg) {
    auto s = to_string(arg);
    fwrite(s.data(), 1, s.size(), stderr);
    return nullptr;
  }

  detail::_stdout_object *print() { return nullptr; }
  detail::_stderr_object *debug() { return nullptr; }

} // namespace printing_shortcuts
added 9 characters in body
Source Link
bluedragon
  • 365
  • 1
  • 9

I am learning C++ and currently playing with variadic template functions and formatting string, So here is my small attempt to write a formatting function and provide a simple iostream-like interface for std::FILE, I am using '%' as a format specifier f.e

I am learning C++ and currently playing with variadic functions and formatting string, So here is my small attempt to write a formatting function and provide a simple iostream-like interface for std::FILE, I am using '%' as a format specifier f.e

I am learning C++ and currently playing with variadic template functions and formatting string, So here is my small attempt to write a formatting function and provide a simple iostream-like interface for std::FILE, I am using '%' as a format specifier f.e

Source Link
bluedragon
  • 365
  • 1
  • 9

Small Formatting Library

I am learning C++ and currently playing with variadic functions and formatting string, So here is my small attempt to write a formatting function and provide a simple iostream-like interface for std::FILE, I am using '%' as a format specifier f.e

format("const CharT *str") == "const CharT *str"
format("HelloWorld - %", 10) == "HelloWorld - 10"

here is the code:

#include <cstdlib>
#include <string>

namespace gupta {
using string_t = std::string;
using CharT = string_t::value_type;

inline string_t format(const CharT *str) { return str; }
template <typename T> inline string_t to_string(const T &f) { return std::to_string(f); }
inline string_t to_string(const char *str) { return std::string{str}; }
inline string_t to_string(string_t s) { return (s); }

template <typename T, typename... Ts>
string_t format(const CharT *str, const T &arg, const Ts &... args) {
  string_t res;
  for(; *str; str++) {
    if(*str == '%') {
      if(*(str + 1) == '%') {
        str++;
      }
      else {
        res += to_string(arg);
        return res += format(str + 1, args...);
      }
    }
    res += *str;
  }
  return res;
}

template <typename... Ts> auto fprint(std::FILE *f, const char *str, Ts &&... args) {
  auto s = std::move(format(str, std::forward<Ts>(args)...));
  return fwrite(s.data(), 1, s.size(), f);
}

template <typename... Ts> inline auto print(const char *str, Ts &&... args) {
  return fprint(stdout, str, std::forward<Ts>(args)...);
}

template <typename... Ts> inline auto debug(const char *str, Ts &&... args) {
  return fprint(stderr, str, std::forward<Ts>(args)...);
}

namespace detail {
  class _stdout_object {};
  class _stderr_object {};
} // namespace detail

namespace printing_shortcuts {

  template <typename T> detail::_stdout_object operator<<(detail::_stdout_object f, const T &arg) {
    auto s = to_string(arg);
    fwrite(s.data(), 1, s.size(), stdout);
    return f;
  }

  template <typename T> detail::_stderr_object operator<<(detail::_stderr_object f, const T &arg) {
    auto s = to_string(arg);
    fwrite(s.data(), 1, s.size(), stderr);
    return f;
  }

  detail::_stdout_object print() { return {}; }
  detail::_stderr_object debug() { return {}; }

} // namespace printing_shortcuts

using namespace printing_shortcuts;

} // namespace gupta

using namespace gupta::printing_shortcuts;

class test {};

std::string to_string(const test &) { return "test"; }

#include <assert.h>
int main() {
  using namespace gupta;
  assert(format("const CharT *str") == "const CharT *str");
  assert(format("HelloWorld - %", 10) == "HelloWorld - 10");
  print("%s\n", format("HelloWorld - %,%", 10, test{}));
  assert(format("HelloWorld - %,%", 10, test{}) == "HelloWorld - 10,test");
}