formatstring.hpp 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. /// @file
  2. /// FormatString functionality
  3. #ifndef SOPHUS_FORMATSTRING_HPP
  4. #define SOPHUS_FORMATSTRING_HPP
  5. #include <iostream>
  6. namespace Sophus {
  7. namespace details {
  8. // Following: http://stackoverflow.com/a/22759544
  9. template <class T>
  10. class IsStreamable {
  11. private:
  12. template <class TT>
  13. static auto test(int)
  14. -> decltype(std::declval<std::stringstream&>() << std::declval<TT>(),
  15. std::true_type());
  16. template <class>
  17. static auto test(...) -> std::false_type;
  18. public:
  19. static bool const value = decltype(test<T>(0))::value;
  20. };
  21. template <class T>
  22. class ArgToStream {
  23. public:
  24. static void impl(std::stringstream& stream, T&& arg) {
  25. stream << std::forward<T>(arg);
  26. }
  27. };
  28. inline void FormatStream(std::stringstream& stream, char const* text) {
  29. stream << text;
  30. return;
  31. }
  32. // Following: http://en.cppreference.com/w/cpp/language/parameter_pack
  33. template <class T, typename... Args>
  34. void FormatStream(std::stringstream& stream, char const* text, T&& arg,
  35. Args&&... args) {
  36. static_assert(IsStreamable<T>::value,
  37. "One of the args has no ostream overload!");
  38. for (; *text != '\0'; ++text) {
  39. if (*text == '%') {
  40. ArgToStream<T&&>::impl(stream, std::forward<T>(arg));
  41. FormatStream(stream, text + 1, std::forward<Args>(args)...);
  42. return;
  43. }
  44. stream << *text;
  45. }
  46. stream << "\nFormat-Warning: There are " << sizeof...(Args) + 1
  47. << " args unused.";
  48. return;
  49. }
  50. template <class... Args>
  51. std::string FormatString(char const* text, Args&&... args) {
  52. std::stringstream stream;
  53. FormatStream(stream, text, std::forward<Args>(args)...);
  54. return stream.str();
  55. }
  56. inline std::string FormatString() { return std::string(); }
  57. } // namespace details
  58. } // namespace Sophus
  59. #endif //SOPHUS_FORMATSTRING_HPP