Comments (12)
It seems like it would be quite helping in your case if your printf-implementation would recognize "callable" arguments. It could then call them when they are needed and they serialize themselves into a buffer (and they all could use the same one), or something like that. But that is on a layer that is completely off from where pprintpp works... I see that it's tempting to do something in pprintpp, but it's hard to see where this would really fit when thinking this through.
from pprintpp.
Well, there is this ancient school of philosophy that claims: "nothing must break encapsulation and decoupling" ...
pprint(" Hey Ma, Look: { %foo } !", _foo_instance ) ;
They go as far as claiming above "integration" naturally breaks both in one go, for the foo
type... I might be sure they would advise on this course of action:
pprint("Hey, Ma, look: { }!", foo::to_string( _foo_instance ) ) ;
Complete decoupling and complete encapsulation ... Silly people ...
from pprintpp.
Well, this requires some kind of std::string
. Being in the embedded world, providing a statically allocated buffer, that can be used for multiple invocations of to_string
could take the buffer and "consume" portion of it by taking it by reference. Something like this:
char buffer[100];
auto buf = create_consumable( buffer );
pprint("Multiple Foos: {} / {}", to_string( buf, foo1 ), to_string( buf, foo2 ) );
Which of cause won't work as both calls to to_string()
must have a side effect on buf, but the order of evaluating would be undefined.
Thanks for your suggestion.
from pprintpp.
and of cause, it requires some kind of support for std::string
in pprint
.
from pprintpp.
Encapsulation and decoupling. That is a fundamental postulate. Not a "suggestion".
There is a rumor some of them ancients have developed ancient parts of std::
twilight zone.
Your line of thinking is not that uncommon. Whan I aksed that question, in particular std::exception
has been brought to my meek persona attention, so I can learn by example:
// two instances of some offsprings of std::exception
// x1 and x2, came in
pprintp("Look Ma, no integration and no std::strings ! {s} {s} ", x1.what(), x2.what() ) ;
They actully use const char *
... Silly people ...
from pprintpp.
@TorstenRobitzki i am glad that the language turns out to be useful in your project! I keep seeing new issue items very late because for some reason i don't get emails about it.
I think the cleanest way to extend this is this:
- for your type
MyType
provide some nonstandard%FOO
format implementation in yourprintf
implementation that handles the formatting of the variable's content in the output. This part would happen without any change topprintpp
yet. - then add something like
as seen between the other types here.
namespace pprintpp { template <> struct type2fmt<MyType> { using type = char_tl_t<'F', 'O', 'O'>; }; }
Is this something that might work for you?
pprintpp
is simply a format string preprocessor that creates no runtime code. Thinking about different models might be possible, but i guess we would need kind of rethink the whole thing from the beginning (which would be fun of course). This is why i suggest this approach with separated concerns.
from pprintpp.
Yes, we are fully aware, that pprintpp "just" turns a typelist and a format string in a new format, but we though, that we are probably not the only and first one, that have the requirements to use user defined types. As we are basically using snprintf()
and not printf()
, we wrapped snprintf()
already to have some formatting like this:
char buffer[ 100 ];
const std::size_t buffer_used = format( buffer, "{s} = {}\r\n", "Elf", 11 );
I though about your approach already, but rejected the idea, because it inverses the usual library dependencies (in addition, we have printf() in conan package that would then be under constant change).
I'm currently thinking of wrapping buffer
in some kind of type to select a different overload of snprintf()
and to change pprintf()
to check if unsupported types (aka user defined) type support a specific overloaded function, that could be used to pass the buffer and the object to, to fill the buffer.
I also try to understand, if pprintpp
would still be the right place to start with or if it might be easier to start from scratch.
from pprintpp.
@TorstenRobitzki first I hope you do not mind my approach before. :)
Your project has requirements which we do not know but, I really do not see what might be wrong with:
// just a sketch
struct Foo {
whatever data_ ;
const char * to_string () const {
// 1. somehow put data_ string presentation to this->buffy_
// 2. return the native pointer to it
return this->buffy_ ;
};
private:
char buffy_[BUFSIZ]{char(0)};
} ;
// ... somewhere else
void test ( Foo const & foo_ ) {
pprintf(" Foo instance: { s } \n\n", foo_.to_string() ) ;
}
pprintf
is simple, effective and feasible as it is ... Perhaps we should think of it as we think of stdio.h
printf()
: it is there it is useful and it is unchangeable :)
from pprintpp.
Your project has requirements which we do not know but, I really do not see what might be wrong with:
Well, having a buffer inside every data type that has to have a string representation is simply overkill and it won't work for enumerations and it requires support by the user defined type, which might be unsuitable for types from existing libraries.
from pprintpp.
@TorstenRobitzki , The point is in the last sentence :
pprintf
is simple, effective and feasible as it is ... Perhaps we should think of it, as we think of stdio.h printf() : it is there it is useful and it is unchangeable :)
Yes ... "callable arguments" is one OK way of doing it. It does not change pprintf
... There are many C++ variadic arguments based designs, working that way, for example...
from pprintpp.
Thanks for the open discussion. I will think about this a little bit longer, but I think the solution to our requirements are somewhere outside of pprintfpp.
from pprintpp.
@TorstenRobitzki You might consider this schema
#include "../pprintpp.hpp"
#include <cassert>
#include <cstdio>
#include <memory>
using namespace std;
/*
somewhat inspired with
https://msdn.microsoft.com/en-us/magazine/dn913181.aspx
*/
template <typename T>
inline T frm_arg(T value) noexcept
{
return value;
}
template<typename ... Args>
inline auto to_buff
(char const* fmt, Args ...args)
noexcept -> unique_ptr<char[]>
{
assert(fmt != nullptr);
// 1: what is the size required
size_t size = 1 + std::snprintf(nullptr, 0, fmt, frm_arg(args) ...);
assert(size > 0);
// 2: use it at runtime
auto buf = std::make_unique<char[]>(size + 1);
size = std::snprintf(buf.get(), size, fmt, frm_arg(args) ...);
assert(size > 0);
return buf;
}
///////////////////////////////////////////////////////////////////////
struct Foo {
const char* name = "Foo";
};
inline constexpr char const * frm_arg(Foo const & foo_ ) noexcept
{
return foo_.name;
}
///////////////////////////////////////////////////////////////////////
extern "C" int test_4(int, wchar_t* [])
{
auto rez{ to_buff(
"\n\nFoo: %s, Foo: %s, %s %d\n\n", Foo{"A"}, Foo{"B"}, "The answer is:", 42
)};
pprintf("{s}", rez.get() );
return EXIT_SUCCESS;
}
from pprintpp.
Related Issues (15)
- reorder printf paramters HOT 1
- C++11 Lambda expression instead of local class/struct in AUTOFORMAT HOT 2
- Thank you! HOT 2
- Does {s} work with std::string_view? HOT 1
- pprintpp needs extra cstdio include
- Mixing format syles causes wrong output HOT 1
- Add support for string view? HOT 3
- Explicit hexadecimal format with signed argument HOT 1
- Explicit length identifier broken HOT 2
- AVOID_STL requires STL includes HOT 1
- Grouping HOT 3
- Header soup HOT 3
- tie_types ... no implementation ? HOT 1
- https://github.com/dbj-systems/pprintpp_msvc HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from pprintpp.