@mbozzi very thanks to your post.
Firstly I must admit that, nowadays, I implement tiny libraries to improve my C++ and programming skills. So I see these implementations as attempts. Sometimes, I find myself in a sitation where I overengineered about the topic or implemented inefficient/wrong/bad way. Nevertheless, I believe that those concrete attempts are required for improvement. So if
tableprinter is completely useless I would not be very sad. That's how I approach to the matter.
I will try to make some explanations.
Actually, I have thought about whether to print table in a
class or a
function. I decided not to do in a function because I want to introduce table notion which consists of rows and columns. So I decided that implementing in a class is a better way to express this notion. Btw, If i had decided to implement as a function I would not implement this library.
Also I assumed that there might be a situtation which another class want to print a row without knowing where it prints. This is the reasoning of why it retains
m_streams with it.
An example :
1 2 3 4 5 6 7 8 9 10 11
|
struct analyser
{
tableprinter::printer& m_printer;
analyser( tableprinter::printer& p ) : m_printer { p }
{}
void do_some()
{
m_printer.print( 1 , 2 , 3 );
}
};
|
The table notion which courages the user to think with it. So it is different than implementing a function which incidentally outputs like a table. Functionality might exactly be the same but the
printer courages the user to think over the table notion.
I restrict the user to access
m_streams because I don't want to access it freely. Either add or remove streams, nothing else is needed according to my perspective.
Constructor of
printer tells that it needs references to
ostreams which means they cannot be null. Dangling reference could happen but user already knows that the library expects non-null. Even though, I agree that it introduces some potential problems, it is up to him.
Answers of numbered issues :
1. - In my other library which is
https://github.com/OzanCansel/fsconfig/blob/master/include/fsconfig/fsconfig.hpp#L12-L70, I implemented exceptions as you have said but in tableprinter I wanted to try to express over built-in stl exception classes but I agree that specialized exception classes are better, I will refactor this part.
2. - In this line
https://github.com/OzanCansel/tableprinter/blob/master/src/tableprinter/tableprinter.hpp#L527 the elements of vector is used to concat column names.
3. - I didn't know that, functionality is same but it is better not to move. I will refactor this.
4. - I realized before last release but forgotten again. I will refactor this.
5. - Same question arose but I decided to use
is_base_of but now I see
is_convertible expresses intent better. I will refactor this.
6. - Nice catch, I wasn't aware of that. I will refactor this.
7. - Do you mean should
F be taken as
F rather than
F&& at this line ?
https://github.com/OzanCansel/tableprinter/blob/master/src/tableprinter/tableprinter.hpp#L137
Again very thanks for your detailed examination while you think that it is not a useful library.