3
\$\begingroup\$

I use console a lot, so I thought this may help me. It's supposed to be simple, safe, and fast. Any ideas?

http://ideone.com/INXub0

#include <iostream>
using namespace std;
class Console
{
public:
 template<typename ...Args>
 static bool WriteLine(const std::string& format, Args&&... args)
 {
 bool success = write(format.c_str(), std::forward<Args>(args)...);
 std::cout << std::endl;
 return success;
 }
 template <typename ...Args>
 static bool Write(const std::string& format, Args&&... args)
 {
 return write(format.c_str(), std::forward<Args>(args)...);
 }
 template<typename T>
 static void WriteLine(T&& value)
 {
 std::cout << std::forward<T>(value) << std::endl;
 }
 template<typename T>
 static void Write(T&& value)
 {
 std::cout << std::forward<T>(value);
 }
private:
 template<typename ...Args>
 static bool write(const char * format, Args&&... args)
 {
 while (*format)
 {
 if (*format == '{')
 {
 bool found_closing_brace = false;
 short value_position = -1;
 while (*(++format))
 {
 if (*format == '}')
 {
 if (value_position == -1)
 return false; // {} is not allowed.
 write_value(value_position, 0, std::forward<Args>(args)...);
 found_closing_brace = true;
 break;
 }
 else
 {
 if (value_position >= 10)
 return false; //Only range {0 ~ 99} is allowed. 
 if (value_position == -1)
 value_position = *format - '0';
 else
 value_position = (value_position * 10) + (*format - '0');
 }
 }
 if (!found_closing_brace)
 return false; 
 // Continue back to the main loop. This is required.
 // We need to process the next character, because it could be a '0円' or a '{'
 format++;
 continue;
 }
 std::cout << *format;
 format++;
 }
 return true;
 }
 template<typename T, typename ...Args>
 static void write_value(int x, int i, T&& value, Args&&... values)
 {
 if (i == x)
 std::cout << std::forward<T>(value);
 else
 write_value(x, ++i, std::forward<Args>(values)...);
 }
 static void write_value(int x, int i) { } 
};
int main()
{
 Console::WriteLine("Big {11} Bang {0} Theory {6} [{11}, {12}]",
 "Zero", "One", "Two", "Three", "Four", "Five",
 "Six", "Seven", 8, "Nine", "Teen", 11, 12.5f);
 // your code goes here
 return 0;
}
200_success
145k22 gold badges190 silver badges478 bronze badges
asked Mar 19, 2016 at 16:32
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

You must allow the escape character for { and } otherwise this doesn't works.

Console::WriteLine("int {0}(){ return 0; }", function_name);

Apart from that I would add an override to specify the output stream.

std::ofstream logger("log.err");
Console::WriteLine(logger, "String");

It must be a class? Probably it's only a style issue, but I don't like class with only static methods. I prefer namespace and a console_details namespace for private functions.

answered Mar 20, 2016 at 13:13
\$\endgroup\$
1
  • \$\begingroup\$ Welcome to Code Review! Good job on your first answer. \$\endgroup\$ Commented Mar 20, 2016 at 13:53

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.