@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
ostream
s 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.