CppCast - DAW JSON Link
Episode Date: June 11, 2021Rob and Jason are joined by Darrell Wright. They first talk about a gameboy emulator written by Ben Smith and a new regression testing tool. Then they talk to Darrell Wright about DAW JSON Link, his J...SON serialization library. News FTXUI POKEGB gameboy emulator that only plays Pokemon blue (68 lines of C++) Automated regression testing with Touca Links DAW JSON Link on GitHub DAW JSON Link Documentation Sponsors C++ Builder
Transcript
Discussion (0)
episode 303 of cpp cast with guest daryl wright recorded june 9th 2021
this episode is sponsored by c++ builder a full-featured c++ ide for building windows
apps five times faster than with other ids that's because of the rich visual frameworks
and expansive libraries prototyping developing and shipping are easy with c++ builder start for
free at embarcadero.com
In this episode, we discuss a Game Boy emulator.
And we talk to Daryl Wright.
Daryl talks to us about his library, Jason Turner.
Jason, how are you doing today?
Oh, all right, Rob.
You know, I learned from the Twitter comments that I can't just say that we're still the
only C++ podcast just because other podcasts don't necessarily release on a regular schedule.
That's true.
We try our best to be regular, but we can't hold everyone up to that standard.
We can't impose that on them.
The more the better, though.
Yeah.
And actually, just to give a shout out to the No Diagnostic Required podcast in DR,
which I do release a bit more regularly than the others and I had forgotten about them so just
comment on them again that was
Phil Nash and
Anastasia
Kazakova yeah
from JetBrains
okay well at the top of the
piece of feedback I'm
going to cheat a little bit this week and instead of
reading some feedback I'm going to
highlight this tweet that I put out,
which is that we're always looking for new guest suggestions.
Please reach out if you're interested in coming on the show.
And I just tweeted this earlier today.
And I already got a couple suggestions, which is good.
And you're using a Bernie meme here.
Yeah, I'm using the Bernie meme, CPCast listeners.
I'm once again asking for your guest suggestions.
It's a good one.
So yeah, I got a couple
suggestions.
Tim Sweeney from Epic.
That's going to be great. I don't know if he's
going to be difficult to get a hold of, though.
Is anyone of the anti-C++
developers, or am I thinking of someone else?
I'm not sure, but I know
Unreal Engine is certainly developed in C++.
That's true.
Maybe I'm thinking of someone else.
You can just ignore my comment.
I'm sure we'll get feedback about it.
Right.
But yeah, a couple other ones.
Someone suggested we have HeartMoopTizer on again.
We haven't had HeartMoop on since we had him on.
Six years, yeah.
Yeah.
Talk to the developer of ENTT Framework.
I think we've mentioned him.
News items, yeah.
Yeah, and also author of Dear I Am Gooey,
and that's another one we've mentioned a couple times.
It'd be good to have him on.
Yeah, yeah, yeah.
That could be interesting.
I wonder, Omar?
I think that's who that is.
I wonder how busy he is.
No idea.
No idea.
But yeah, keep the suggestions coming.
We will try to reach out to as many of these people as we can and have some more new guests on the show.
Or old guests. We always like having guests on as well, like HeartMute.
Okay, so we'd love to hear your thoughts about the show.
You can always reach out to us on Facebook, Twitter, or email us at feedback at cpcast.com.
And don't forget to leave us a review on iTunes
or subscribe on YouTube.
Joining us today is Daryl Wright.
Daryl has been growing as a programmer
for over 20 years in a variety of environments.
He started programming C++ with Borland C++
in the 90s as a child
and has been enjoying it ever since.
When not at work, he enjoys running in the outdoors.
He has worked on JSON link and its
current design for three years, but developed other JSON libraries prior that lead how he
approached it. Daryl, welcome to the show. Hi there. So you mentioned that you grew up with
Borland C++. We've talked about Borland a little bit lately and had some of their developers on
just out of curiosity. Have you played with any of the new generation of their tools i haven't used
it probably since university when uh you know we start i got introduced to gcc and kind of
from there um back when we got you know for loops that had scope right i just out of curiosity
just when did you enter university if you don't mind my asking?
Before the dot-com boom, so late 90s, mid to late 90s.
Okay.
Yeah.
My university was made Visual Studio as our, quote, required compiler,
but it didn't actually matter because we were also required to have FreeBSD installs,
which at the, I don't know, in retrospect,
it feels all kind of backward.
I had free BSD installed for like a week
and then I installed Linux and just used that from then on.
I remember first year we used Pascal on,
it was probably DEC Unix,
but there was a lot of Solaris too.
Like at one point I got,
I was admitting one of the Solaris servers.
I remember getting to replace the CPUs on the,
I think I had 16 of them and it was like an E4500 or something like that.
It was, it was kind of cool at the time.
Like the CS department had their own, their own, what, sorry?
Their own Solaris server. Oh, okay. Or Sun server. Yeah. Interesting.
And yeah, then, then we had, we would try to get,
because I don't think, nobody wanted to use the Sun
or the deck tooling.
We wanted the new stuff because it was newer
and generally worked better.
And then, you know, I think, I can't remember when it was,
you know, well, 98, but yeah.
And we were passing around copies of the standard
in the computer lab because it was bringing out a lot of the new...
It was much better than what we're used to.
Awesome.
The standard library was there.
It feels like we're still fighting for upgraded tools.
No matter what the environment is,
come on, why can't we get a better compiler on here or whatever?
Well, I've been happy with at least C++ 17 lately.
I haven't had the ice.
I'd be playing Vanilla Ice once a week around GCC 9 era
and playing around the same time a little less in MSVC.
You just couldn't push them into the constexpr stuff
too much it just and you know then i would okay i fuzz it kind of you know trying to make it work
just i'll try expressing it a different way and it was uh and then it was the wrong way but it
worked at that time okay well daryl we got a couple news articles to discuss.
Feel free to comment on any of these,
and we'll start talking more about your JSON library, okay?
Okay.
All right. So this first one we have is a GitHub library,
and it's called FTX UI,
which stands for Functional Terminal User Interface.
And yeah, this one looks pretty neat.
C++ library for terminal-based user interface. And yeah, this one looks pretty neat. C++ library for terminal-based user interface. It looks like it has controls for making, you know, some graphical components
within the console pretty easily. Looks pretty nice. Jason, have you dig into this one at all?
I haven't, but it's been on my radar for like at least two years. And I keep meaning to play with it, but I just haven't gotten to it yet.
Now I wonder if I should with my current project I'm working on.
Is there another one like this?
Because I keep remembering something like this, where you designed the GUI with ASCII.
Or is that another one?
That might be a different one.
This one is a little bit more like functional programming style and less.
Okay.
Yeah.
And it looked amazing.
Really nice demo GIF videos showing off some of the features of it and just like a demo user interface, which looks really nice.
I tried the inscript or the WebASM stuff,
but it wouldn't work in Safari or my browser.
Oh, that's unfortunate.
Yeah, I like Web.
Well, speaking of WebAssembly,
the next article we have is from Ben Smith's blog,
and we met him a couple months ago talking about WebAssembly.
This post is Polka GB,
a Game Boy emulator that only plays Pokemon blue.
And the entire thing is like 68 lines of code.
Um,
it's pretty impressive.
Uh,
it's a extremely long post where he goes in depth about like the Game
Boy architecture and how this emulator was written,
which I think is something he's done before.
He's written like a more full fledged emulator,
but this was just a really small one made just to run the Pokemon game.
Right.
I hope they can shrink it to get into the obfuscated C or contest.
Like they mentioned that it was just over on the site.
Yeah, the obfuscated code that he first showed
looks like Pokeballs,
but that was after running it through
some type of obfuscation tool,
and the actual code he wrote
is a little bit more easy to read,
but still pretty small.
I am, yeah, it's awesome.
I don't have much else to say other than it's awesome
oh there's actually a couple of blank comments in here i didn't notice that just to make the
the shapes be what he wanted them to be it's like c++ art yeah yeah that's um okay so what
stands out as awesome just for the record is my cousin and i had been toying with the idea of doing like a hackathon where we uh challenge each other to make a game boy emulator like rust c++
kind of thing and i don't want you know people to get too excited about that if they thought it
would be fun but part of the problem is that finding like all of the information that you
would need to do that in one place is surprisingly hard. Like NES emulation docs are like really well organized and PC and Commodore
and stuff.
But for some reason,
the Game Boy docs,
I mean,
they're all there,
but getting them like in one place,
these are the things you need to know.
This is like a perfect primer on all the things that you need to know about
the CPU architecture,
the PPP,
PPU architecture, and timing, and opcodes, and all this stuff.
Yeah, the memory map and everything there, too,
and what he used out of it.
Yeah, it's amazing.
I'm looking at this code, and I'm thinking, this is so simple.
I think I could run this through my Commodore 64 tool
and make a Game Boy emulator for the commodore
64 but then my hopes were just dashed when i read that the this pokemon cartridge is a ridiculous
one megabyte like who has that much storage that they can could you pretend it's on one of the i
don't oh we can't address it unless you pay.
Maybe if you couldn't, you need like multi-level paging.
Yeah, it would be weird.
I'd have to have some sort of paging.
I would have to use an MEU, one of the memory expansion units.
And then I'd have to have some sort of paging architecture.
And I might be
able to get it to work,
but it would be crazy slow.
I'm sure,
but it'd be fun.
Okay.
And then the next thing we have here is an article,
Tuka's vision for the future of regression testing.
Just,
you want to tell us a little bit more about this one?
There's a announcement of a new like testing software.
Yeah, I'm still like I've read the article a couple of times now and still kind of wrapping
my my mind around exactly how it works.
And hopefully we'll actually get the opportunity to speak to one of the developers about this
project.
But it's an automated regression test generating suite. And one of the projects I work on,
we have like every time master is rebuilt,
I guess on GitHub,
we save the results of those of,
of all the tests,
like in a,
in a what's the word I'm looking for?
What's the style of testing that Claire McRae talks about?
Acceptance testing?
Yeah, like acceptance test, basically.
So we say, okay, this is the baseline requirement,
and we save that as like basically regression test.
Well, it's a little bit more complicated than that for how we do this.
Then whenever you like push to develop,
it reruns all those regression tests. So you know if you broke anything at all in any way like any output file
so we have like it's like acceptance testing but with a moving target and i'm hoping from what i
understand from reading this blog uh this article that this would give you the same thing in like an
automated way because you can click any two different versions
and see what differed in their output
or in their regression test generation.
It looks pretty cool.
Yeah, it sounds really powerful.
Even visualizing differences,
like I was looking into,
I have a big JSON file of benchmarks
for the library I wrote
and tooling to visualize performance differences
with each Git revision, it's
hard to find. Or you're writing it yourself.
Oh, that's an interesting idea. And again, hopefully we'll get the opportunity
to actually talk more to the developers about this. But yeah, I could see that
for performance regression comparisons, but also then also if it could handle things like output from
bloaty and then you could look at like actual binary diff comparisons or from one of the abi
diff tools and you could see did i change the abi between these versions and how i mean abi diff is a
gnu tool i think so it's available on most Linuxes.
That sounds really cool.
I think I'd be incrementing major version every time.
Probably.
I think most of us would be.
Okay.
And then the last thing I want to mention is last week,
we mentioned the core CPP conference, which was announced.
They wanted to share with us an announcement
that their first keynote speaker
is going to be Bjarne Stroustrup.
It's going to be a live remote talk
followed by a Q&A session.
So that's really exciting.
Great to have Bjarne involved in this conference.
And again, early bird tickets are on sale,
I think until June 30th.
And I also still have the call for speakers open.
The biggest C++ event in the Mediterranean.
Coincidentally, also the only C++ event in the Mediterranean that I'm aware of.
Quite possibly, yeah.
Okay, so Daryl, can you start off by telling us a little bit about your own JSON library?
So it's different than most of the other C++ ones in that what you're doing is you're mapping directly to your data structures or even other people's.
The main requirement is you need to be able to construct something and extract the data out.
So you use declarative mapping where you,
through the, and it's using templates where,
and it was really inspired by, by Hannah's approach there with RegEx.
And I remember when she was developing that as, you know,
and talking about how it eliminated the branching in the resulting code because you don't have to make those choices anymore.
So now I know I needed a number parser.
Actually, it's down to unsigned signed floating point because I know what data type I'm going to parse into.
And then I can give an error because it's never going to fit at that point.
And so with that, in the past,
I tried using intrusive macros
and before that was the JSON DOM object
and I could never make them fast.
In this way, I don't have one location in the library
except if you count the string output,
if you output to a string and not an output iterator.
And that allows for the
constexpr because it's dependent on your data types being constexpr at that point so if you
if you imagine it it's like take your constructor you're calling your constructor for your resulting
type and each argument to it is a parser and then in and in recurs you know up the stack uh the result the those ones would have
if they were an object and not a value like a like string or something they would have you know
the little uh parsers feeding its constructor and then you know so it's just one big upside down
tree or i guess it's a right side up tree if you but upside down from the computer science
perspective right side up from the biological perspective,
although the root is that,
yeah,
the roots at the bottom.
So it's a right side up tree of constructor calls coming down into your one
value.
And,
uh,
that,
so most of the code's pretty simple.
You know,
you have a number parser.
It only cares about parsing a number or it's a, you know's a floating point one that's probably the most complicated unsigned and then
uh you know strings and but then you can now start um exploiting things in the type system okay so
i know like and if you want to go a little bit out of spec you can say i have a raw string i'm just going to go to the next quote or and just you know mem copy it
or and you know be done but or i know the data will never ever have escapes in it or you know
but it also gives you can get better errors or cheat if you want and get better performance that
way um but even with checked because you don't have a lot of the branching it's you know for some of the benchmarks it's hitting well over a gigabyte
gigabyte per second oh wow so i just want to make sure i understood you here you're saying
it doesn't have like a dom no kind of capability at all you must give it a data structure to read
into there's a delayed uh there's a delayed parsing uh type where it'll give you a lazy parsing dom where it doesn't actually part it
just skips it so it'll do the rudimentary json and structure checks as it's skipping through
because it's going to be able to uh you know get to the other side of that value that value okay
but um and you can now you and and there's some cases where you'd want to do that
I saw users using it the other day
but where you do some
it's not a simple exploration of the data and then you go and
pass and you can do the from JSON with an actual type after
but the library itself has helpers for things like,
for like variant take variant types,
key values.
Like you can map,
you'll quite often see key values in Jason as a string with the key and
whatever object on the right.
And you just map it right into a standard map.
Or if you want to support the one that nobody supports with duplicate keys, you throw it into a
multimap and it doesn't care.
And then the only requirement there
is, you know, it's the
container iterator pair of constructors.
But even then,
if that doesn't work for you, there's
a constructor
object in each type if you want to go into
the tweaks and you can
you just got to take those two iterators and do with if you want to go into the the tweaks and you can you just got to take those two
iterators and do with whatever you want to give your type it so but most of the time you're just
going to say and you know uh jason in the previous version you guess there's a new one coming out
once they get through all the documentation uh you say like jason, the name of the member, and that could be it. Or you can say, you know, specialize on integer or unsigned, whatever.
Or in the next version, you're just going to be able to say JSON link name and the type you're going to.
And it'll probably know your type because most things are either, know they follow they're an arithmetic type uh but via
especially if you now you put because it pulls in numeric limits to determine that where you'll have
uh types like um boost and boost uh big ints or the multi-precision you can um it'll see it's
it's a number and it'll actually as long as it acts like a number it'll work it's a number and it'll actually, as long as it acts like a number, it'll work.
It acts like a number from a compile time perspective, has numeric limits you're saying.
And then the operations, you know, be like an integer or be like a floating point number.
So as long as it fits the, you know, the concept of that type of value, it's going to be able to parse to it.
So if I, if I have like a static, I have a data structure of some sort, that's like,
I don't know, let's just say for arguments, like a person object, it's got like a first name, a last name, an age, whatever.
And I've put in the correct decoration that you need here and pass it into your JSON parser.
That's can be all constexpr because it
knows exactly what size thing it needs to push into and it doesn't have to do any dynamic
allocation or anything like that yeah because all it's going to care about is you you've said okay
so you know it's got name it's got age say it's got um i don't know uh city uh-huh okay so string
we'll call it a float we'll call it an integer and string.
So you would go like JSON member lists.
And then within there, you'd say JSON string with a name.
And you put the name.
In C++20, you can just put the quote, unquote name,
but it's a C++17 library.
Okay.
So now, and I think with the newer GCCs,
you can't use the old hack,
like I think Kano was using in CUTRE.
Right.
So you're just going to create a compile time string literal,
you know, a string literal, it's constexpr and pass that.
So in a lot of code,
the only difference is whether the quotes are not there.
So, you know, the member name, the type,
and what the type is already there.
And then from that, you just go from Jason, give it the type in the, you know, the in the alligator braces.
Wow. I'm having a brain block here and and pass it to any string like range of characters.
OK, so so I'm sorry. Go ahead.
No, no, that was it. Yeah. And even then, it's going to look at the type of string you pass it.
If it's a standard string or you tell it otherwise,
it will exploit that zero termination
because now there's a lot of places
it doesn't have to check first is less than last
because it knows if you're doing a digit parse,
it'll never be a digit when uh, parse your, your, it'll never,
it'll, uh, never be a digit when you hit to that null terminator. So it can just do
the work it was doing is, you know, like a while it's a number type thing. And so like every time
I see a place where you can, um, optimize based on the type, uh, trying to do that there, or the concept.
Okay.
Yeah, and there's examples in the repo of constexpr.
There's a few constexpr arrays where it's doing... I haven't actually tried the C++20 vector yet,
because getting a compiler...
I can't remember which compiler supports it.
Only Visual Studio at this point.
Okay.
I just double-checked that yesterday for reasons.
Someday soon.
Right.
Next year.
But yeah.
And it's using C++17, I said.
It'll take advantage of 20.
There's some places where 20 brings in a couple features with the dynamic stuff where you can have constexpr destructors.
So now you can do your scope exit as a constexpr type construct.
And you can now get guaranteed copy elision when even if you have to mutate something after you do the parse
so i'll parse a number and afterwards i gotta move the the cursor uh to the end of the end of
the value or like the next value i can do that uh in a scope on a scope success and uh now and
that allows you to support things like uh non-mo. It has come up where you have non-movable, non-copyable types
because you have the guaranteed copy lesion.
And you can tell it to always do aggregate construction if you want.
It'll just, you know, it'll just, and with aggregate,
you can just, it's just all you can you can do types like that.
Interesting. So I just want to clarify, like, if I pass in a, like, we were just talking about this
person or whatever with a string like thing, but we don't have C++ 20 yet. And we do want constexpr,
I can just have like a character array or something that can hold the result. And then I get
a compile time failure, the string and the JSON doesn't fit into the statically sized character
array I gave you, you would because as soon as you you leave the as soon as you leave the end of
the array, the compiler is going to say you can't access that. Right. Yeah. So you would get an actual compiler like address past end of object or whatever.
Yeah, depending on which compiler.
Yeah.
So yeah, like if you make yourself,
you know, I think anybody who's doing a lot of constexpr
has probably had the standard array,
and then you just throw a size in
and operator, index operator.
And what it requires of your type for that would be,
unless you pass in a custom callable for the constructor,
is just to, wait, string is, I think, a pointer and a size.
Right.
The containers are two pointers.
So it's using the standard library concepts quite a bit.
Okay.
We don't have concepts per se, so it just expects that you follow those.
Right.
So if we go outside of what it expects, then what do our errors end up looking like?
Sometimes they're pretty bad.
Okay.
It's hard to get right.
I'm not going to give you a hard time.
I try to catch things up front
and the static asserts or errors,
like a common error would be you didn't map the type.
So the error would say missing you know, missing data mapping.
Okay.
And, you know, like in the type name itself, because it's, you know, it's really hard to get errors or warnings out of constexpr code.
Yeah, for sure.
And I would love a static print.
Oh, yes.
Or a debugger, you know, without calling GDB.
What did somebody suggest?
Use compile GCC with dash G O zero and run it through GDB.
Right.
That would be, I can't even imagine how painful that would be.
Oh my goodness.
I don't want to.
Imagine the size of the compiler.
Right.
Yeah.
So you mentioned a couple of times link.
And is link somehow different from G or Jason parser is this whole thing called link.
What am I,
am I missing something there?
Oh,
Jason link.
Um,
I think that's the name.
I don't know how I came up with the name,
but you're linking,
you're linking C plus plus and Jason.
Okay.
It's really boring that way,
you know,
boring names, but, uh that way. You know, boring names.
Yeah, and
all you have is declarative mapping
of what
you're mapping to. Recently,
I don't need as much info because
most things I'm finding
are, you're able to figure
out what they are.
And that's
really, I got through this the other day and what's really nice
is that's going to lend itself to when we get reflection or um using one of the reflection
libraries out there where you have the member name and um you can now just pass you know the member
name and pass it um type of that member.
And you should be able to build the mapping from whatever reflection info you have.
And I want to go down that.
That's, you know, how long the lists get.
This is, I just was thinking about the fact that, you know,
we were discussing that Ben Smith has implemented
several Game Boy emulators, and one of my
toy things to do as a Mandelbrot generator, my cousin likes
to do an NES emulator when you're playing with new things. It sounded like from your
bio that you've written several JSON parsers. Is that just like
the thing that you do from time to time um i've been needing you doing this one it just seemed to stick um in the
past uh i used to do the the 3d rotating cube in each language you know i had it in quick basic
using um using trigonomic identities to do the rotations of the projection but i think i got it yeah there was a
few languages back then back when you can intend your way to graphics so so what did prompt you to
to write the this json library was it seeing hannah's uh compile time regular expression
library that i was wanting to do something like this uh a bit, and she opened my eyes into what was possible.
So it was pretty cool.
But getting down to the...
It was actually, I needed to get...
I'm diabetic, and I have an insulin pump,
and Scott Hanselman will talk about it,
where I have all my data in the cloud,
and I'm pulling it down,
but I had no... Processing it locally, but I had no processing it locally.
All the tools were just too slow.
So it was taking minutes to do tasks.
So I'm like, okay, well, I can write a parser.
And that'll be a quick job.
And, you know, a few years later.
And then like that even prompted another tool that I wrote that because there was no like
Jason schema for it or anything like that at the time.
So I had to figure out what the,
it was easier to take the Jason and to figure out the data structure.
It was like,
you know,
multi-gigabyte array of objects and just figure out what the data structure
was because reading some javascript
and node stuff is it's hard to figure out what a data structure is supposed to look like in them
because there's often it depends typescript is much nicer but yeah so um and there's a tool on
there and it'll generate the the bindings for you if If you have Jason, one of the things I have on the go is to use Jason schema to do that and
generate,
you know,
the C++ data structures.
I can do that now,
but it's,
you know,
it's fuzzy,
but it still saves a lot of time.
And,
but then once you have it in Jason schema,
it's,
you know,
as an IDL,
you can generate your C++ data structures and the bindings and you're good to go.
And reverse, generate the schema from the bindings is on the list of things in the future.
So if I had something that, I mean, we're talking about like key value pairs and stuff before, and I haven't spent so
much time parsing JSON data. But if I've got some portion of it where I'm like, okay, I do,
I have a tightly rigid structure here. And I know that these are all the C++ things I want to bind
it to. But then for this next blob of things, I really just want like a string to you know variant of float double or double
uh string and whatever you know some generic holder of things in some portion can that be
accommodated as well um i i have a an unparsed, delayed, like a lazy parsed value,
but there's no reason why you couldn't take that and put it into something.
It's not an area where I've put a lot of effort into because I always know I need to work with the data.
Okay.
You don't have to parse everything.
You can, but the default is it only cares about what you map the rest it'll just skip i see and
there's uh there's um flags to tell not to do that and it must be exact because i i assume you
know like uh you're getting it from a data provider they change it you don't know at least
you get you get the the errors the runtime errors at that point right but yeah um pretty cool you can
and you know the i i you look at the issues that a lot of the people have with a lot of the uh
with um jason libraries it's variance it always comes back to take variance and variance because
you and so there's a few ways of doing that like, and like part of this is I went and kind of did a,
um,
not a formal,
an informal survey of how people are structuring their Jason.
So,
um,
and I have a cookbook section where I kind of try to document a bunch of it,
but,
um,
the biggest,
uh,
it seemed the biggest trouble because,
uh,
people had was,
so, you know, often it'll be a
type and then the you know some object uh below that or uh before that will be mapped you know
that's the tag sometimes the tag is within the object itself you know you see that in c anyways
with like like sockets um but it so it handles those situations where you can,
where you're mostly, you know, if it's a sub member,
you give it the name and it'll parse the rest of it
as that type of object.
Very cool.
Yeah.
I wanted to wrap up the discussion for just a moment
to bring you a word from our sponsor, C++ Builder.
The IDE of choice to build Windows applications
five times faster while writing less
code. It supports you through the full development lifecycle to deliver a single-source codebase
that you simply recompile and redeploy. Featuring an enhanced Clang-based compiler,
Dyncomware STL, and packages like Boost and SDL2 in C++ Builder's Package Manager,
and many more. Integrate with continuous build configurations quickly with MSBuild,
CMake, and Ninja Support, either as a lone developer or as part of a team. Connect natively to almost 20 databases like
MariaDB, Oracle, SQL Server, Postgres, and more with FireDAC's high-speed direct access.
The key value is C++ Builder's frameworks. Powerful libraries that do more than other
C++ tools. This includes the award-winning VCL framework for high-performance native Windows apps
and the powerful FireMonkey framework
for cross-platform UIs.
Smart developers and agile software teams
write better code faster using modern OOP practices
and C++ builders' robust frameworks
and feature-rich IDE.
Test drive the latest version at Embarcadero.com.
I was looking at your GitHub for a moment
and I saw that in addition to
the daw json link library you also have this json to cpp uh which sounds like a pretty handy tool
that you can just take a json structure and create c++ classes from it is that right yeah that was
the tool i was talking about there yeah um and And, you know, it's pretty close,
but that's mostly what you need.
It was a hack, but it works.
I know that in Visual Studio,
like there's an option to do this kind of built in.
I think it only supports the managed languages like C Sharp.
So I know it's handy to have.
So it's nice to have it for C++ too. I think I did that once and then I just poured the C Sharp or something over like C sharp. So I know it's handy to have. So it's nice to have it for C++ too.
I think I did that once.
And then I just poured the C sharp or something over to C++.
Cause it was,
you know,
it's not that far.
Yeah.
Yeah.
Yeah.
It's,
um,
but yeah.
Um,
so not too sure what,
what's going to happen with C++ 20 in the future with this,
um,
still waiting for compiler support.
But the big one is going to be the CNTPs.
Just making it that much cleaner.
You don't have to sit there creating string literals.
Right.
So working on this, you said, for like three years.
I'm guessing you have some real world users
of this library now is that correct i i know a few you never know who's using things and sure
no you don't a little little hey thanks or little tidbits are always awesome like if somebody's using it um and uh so i i use it for me uh like for for my stuff
like uh whether uh just a little you know when i need to get info from web services or i want to
subscribe you know from c++ it um just bring in live lib curl and uh there you go um it's just
one less i just i don't like leaving the performance on the table.
Do you want to tell us more about the,
the thing you did with the,
you know,
getting diabetes info?
Is that like part of a tool you used that makes use of this Jason library?
I was using,
yeah,
there's some work.
There's the night scout tool and it lets you send all your,
you know, your, your blood sugar readings from
and if you have an insulin pump and a CGM, CGM will
every five minutes it pulls your blood sugar, it checks your blood sugar
and so you get nice trending instead of
using every a few times a day,
you now have 200 plus times a day.
Yeah. So you can make better decisions and then you can use that,
combine it with the other. So it's gigs and gigs of data.
And people were doing bash scripts to process it.
And, but they were doing amazing things and, you know,
being the
cocky programmer, oh let's just do it in C++
and
but there's something
to be said about the high level
that's one of the things about C++
it's such a good language for making high level APIs
but nobody does
like you know
you can do all the pain
you can do all the pain in the library
and then you don't have those restrictions
on the people using it as much
because you know what they're calling it with
and you can adapt your library around,
at least with generic programming and templates.
So if they send you a string or a string view,
well, you know of a string view,
it's, you know, pain point, there's no zero terminator
that you know of.
Yeah.
Or, like,
yeah, surprised you haven't brought up ABI, though.
Well, I was just browsing the source
code. It looks like it's header only, right?
It is, yeah.
So you don't really care about the ABI, do you?
I don't.
But I have lots of opinions.
Oh, okay. Go ahead, share your
strong opinions about ABI if you would like
to. Sure.
I think it should burn, but I think we should
maintain string vector
and the
arithmetic types and layout.
Nothing else.
Interesting. With those, you can build everything and we see this like you know like uh like jason everything's
being expressed with string object vector or sorry array and you know the arithmetic types
throw in a nums and boolean in there, too.
Outside that, I just... And every time the compiler upgrades, it does change ABI.
They fix bugs.
Yeah, there's a constant small ABI breakages happening, it seems.
But I guess most of the time it doesn't affect the average user.
Well, that's like the UB argument, isn't it?
Hey, I don't agree with it. I'm just...
The UB doesn't affect it. It works on my machine.
Yeah, it works on my machine. Yeah. I don't know how many times. Well, less and less often these
days. But oh, my goodness, back in the early 2000s, how many people would say, oh, well, you know, the stupid compiler is broken.
If I compile in dash O three, then my project no longer works.
No, no, that just means you have undefined behavior in your project.
And that's one place where constexpr is amazing.
It helps you not do the things that would cause that.
And, you know, you now have you now have static asserts instead of,
so it breaks right away.
And in CLion, I've seen you use it in a couple of videos.
It's now telling me live that, hey, and why,
my static assert failed while I'm coding.
It's awesome.
I didn't even have to compile because clang d is
taking all my cpu that is true my laptop can get a little hot when i'm programming sometimes
yeah but yeah um yeah like uh i i hope i i hope like you know like everyone talks about how they
want um the the library and c++ for for JSON that maps directly to data structures,
like, you know, like Serde and Rust.
The inspiration I had was C Sharp
and where they had, you could just say,
you know, expose an object to the web services.
And this was probably five years ago,
so it's probably out of date now,
but it just blew my mind.
Like, I have a structure i just opted
in said make it serializable and all of a sudden i can use it as a web service and i think that's
where we'd like i'd like to see uh c++ go like one of the you know if there's side project one
of the other things i'm sort of half working on is um taking boost uh beast and allowing you to because
now because we have the whole type system in you can do a standard function like approach to
uh providing a function you know like a json rpc type thing or a web service so it now knows how
to serialize your call your invocable and and the results And so you give it a path, you give it a function.
We still have to decorate it with, you know, like we do with function.
We can't just infer function traits because it's just finicky.
But yeah, I think we just need to get these libraries
that are higher level out there.
Yeah.
Yeah, one question I had on here that I wanted to ask you,
which I increasingly getting here is completely irrelevant,
but I still want to go ahead and bring it up.
Now, the question I was planning to ask you was,
do you use any like custom allocation strategies
to get the kind of performance you have?
Because that's what most other JSON parsers do.
But it sounds like you never allocate anything
so but i went down this path it's it was a 50 performance boost by using a custom locator
um so because you're so you have you know you have your strings you have your vector
there's a locator protocol where either passes the last argument or the the first with that type uh tag type yeah so i if you call the locator uh like from jason
a lock i i just kept it on a whole separate path at the top there just to make it easier
um it will now check if you're constructible with either of those at compile time and if you are
it'll pass it.
So without PMR, you're getting like PMR type of location
because it's using the same allocator
for every object that can use it.
And so even because you're now,
even though you're using the iterator interface to say vector,
because the types above that are using the same allocator,
you're still getting... and so i threw in
a bump a locator you know just it never delocated just kept going i just gave it a big enough buffer
that i wouldn't go past right and i went from like uh it was like 34 no i bought one gig to
one and a half gigs in the test i was doing a second. It was amazing. So like in the vectors and strings and maps and such that are contained in your custom types that I'm passing into your parser, I can also.
Those were standard types.
Right, right, right.
Yeah.
But I have to pass in.
You're saying what I'm trying to understand or make sure I understand is if I pass in an allocator along with the parse, then you just use it.
Yeah. Okay. Assuming the typ, then you just use it. Yeah.
Okay.
Assuming the typo is constructible with it.
Right, right.
So we still have to follow these allocator-aware constructs
and you detect them and use them.
Yeah, because we can check if it's invocable with that.
Right.
But that also means that your type,
it wouldn't be standard vector anymore.
It'd be standard vector T, whatever, my locator.
Or you could use standard PMR and just pass in a PMR type.
It should work the same way from your perspective.
I kind of wish we had that from the beginning
and we just used that as the default.
Right.
It would have been, you know,
then you can just use the right allocator for the job
but your interface is always the same if we're talking about abi right right yeah but yeah so
yeah i it it i was quite amazed um vector and string were the big mostly vector depending but
the maps and the sequent um the associated types, because they're, you know, they didn't seem to be as much of a benefit I remember.
Maybe I remember it wrong, but I don't seem to remember getting as much out of them.
Because vector will really optimize if you give it a random iterator.
Right.
And that's one of the places you can shut it off but um when constructing vectors
in particular i will say i'm a random iterator but i only have added the the subtraction operator
because uh then it'll do the disc that distance check i i often know because i uh the way it's
parsing i have to skip values because i need have to skip values because I'm doing the constructor for this type right now.
And I have to move the cursor to that part of the JSON file.
I can't just parse it out of order from that.
So what I'll do is I'll know where it is at that point.
And for some things like arrays, strings, I'll count things
like the number of elements
or the first place where I have to go slow
because there's an escape in the string
or if it doesn't have any.
And then I can later on optimize on that
because I now know the bounds.
I know the number of elements.
I can provide that subtraction operator,
do the little lie.
You can turn it off, but it works on two to three implementations consistently.
And, and, you know, but it, and you go from the, but vector, and this is where I want,
you know, if ranges to, or, you know, like the,, the, uh, having a brain block, uh, on the rate,
it's the ranges, uh, it's the Sentinel, uh, iterator or the Sentinel type vector needs
that constructor so much because if a size Sentinel and, uh, it, it, it seems to come
up where I don't have a random access iterator, but I have size sentinel and it goes fast um i threw on i've thrown i've built up
uh iterators with uh like uh where you just throw in like a function a callable into them like kind
of like a map or uh transform and it like uh doing an fma you're getting all the vectorized
instructions all of a sudden and it doesn't have to sit there and uh because now you're getting all the vectorized instructions all of a sudden. And it doesn't have to sit there because now you're also getting guaranteed copy lesion.
It doesn't have any of the code for the delocation
because it doesn't have to move out in the assembly
when you look at it on, say, Compiler Explorer.
Okay.
And so that's probably what the only place i
i kind of cheat like that but it seems pretty safe because the only thing it can do is just
not have the operations it can't you know do uh you know an operator plus five uh on on those
iterators or or something like that or an index so it'll just fail to compile if it's not going to work and okay but yeah very nice so what uh compilers does this work on then um so gcmsvc
in the ci i have the three of those going clang uh apple clang also but that's just six month old
gcc uh sorry clang i right. But, and I've tested
lately as far back as GCC 10 and 9.
Before I do the version 3,
I'm going to test again.
The website has the ones I tested
when I released version 2.
But it's starting to get to the point
where, you know, GCC 9, C++ 17 support.
Well, they weren't even production ready for GCC 17 until I think it was GCC 11.
And there's a few things where if you throw it, they just start blowing it.
Like the older compilers will start using a lot of memory, whereas the new ones don't.
Right.
And if you don't have...
Sorry? Oh, i'm sorry finish
please i was just gonna say if you don't have a computer with you know a lot of memory and you're
doing but most things don't need a lot for the compile it's when you get the you know 200 in
some of the benchmarks they have these classes where there's like 200 members or something like that and it it really stresses the the the templates because
uh you know i had 14 i got it down to 10k but or a little under 10k but i was like 14 or 15
kilobyte uh symbol names at one point oh wow and those tests like where the yeah i just
so the compilers didn't like that normal Normal stuff, it's actually smaller than what you'll get
because there's only a parser there for the types that you're invoking and that.
So you mentioned that the library is currently version 2.
What do you have planned in version 3?
Anything worth sharing?
So version 3, it's going to have the less uh the more implicit
uh mapping so you just say you know link this member to this type like in a c++ type you don't
have to say json number json string for most things um there's some type you can say construct
my thing as if it was a string or like this other thing there's aliasing uh in
that way in that way so um performance increases the library is a lot cleaner um in the last in
the last bit um there was a bunch uh those are the two that are recently that are come to mind
um everything that's worked before should keep working. It's been
mostly API stable.
Actually, no. I broke
it for version 3. That's right.
I changed the way you do options because
they're getting too long. That's how I reduced the symbol size.
I'm using
just a single option.
You put the options into a function.
If you want to go from the defaults instead of supplying an individual option.
And CNTP is going to be amazing for policy classes where, you know, we're so wide on the templates before.
And now we can have one and construct it like a normal class instead of having a num here or a type here
and a type here for different types of things
just to make when you're putting your template options in.
Yeah, I hadn't thought about that for policy template options.
And I guess for our listeners, we should explain,
you are saying class non-type template parameters.
Yes, sorry. Yeah.
Yeah, so the non-type, parameters. Yes, sorry. We should just call them
non-type templates.
Yeah, but those existed
as values forever.
True. I'm really excited about
the P1985
universal template
parameters.
You can mix
you can have one that can be either a
type or a value.
Oh, okay. Yeah.
So it makes, you know, when you do
that template template
and all of a sudden it doesn't work
generically because you threw a standard array at
it and it's got a number.
Right. Yeah. So you'll
be able to deal with stuff like that.
Hopefully it comes, I'm hopeful for that one. That's cool. Yeah. So you'll be able to deal with stuff like that. Hopefully it comes. I'm hopeful for that one.
Hmm.
Yeah.
That's cool.
Yeah.
So for our listeners here,
and if they want to do any of these things that we've talked about,
constexpr parsing or custom allocators and all that stuff,
are there examples on the website for how these things work?
There are.
The test folder has a lot of it's mostly just examples plus some stuff that's labeled details testing but and then
there's a cookbook section on there where it's got some more high level plus the the main readme
it's got a bunch stuff on on uh how to how to approach you, do a few simple things. But there's quite a few examples in the testing.
Okay.
And that's also, you know, that's also how I test my documentation.
I wish there was a way to link to it in the markdown,
but I take the example in the markdown, throw it into a test,
and they're all labeled cook, and then, you know, it's a fully working example.
Oh,
okay.
Yeah.
Now for,
uh,
do you suggest that people go to develop and start straight from version three
right now?
Or do you suggest they use your last release version to develop is going to
break.
Um,
uh,
but I would say go with the release.
The,
the differences are pretty minor.
It's,
and if you stay if you're
using the defaults you're not going to ever notice them and most things you're going to use the
defaults anyways like most people still parse their json to double um you know they you know
they may not but you do see a lot uh people want that un64 or you know but it even supports uh
things like you know some uh where even supports things like, you know,
oh, that was one of the things that came up in the data.
Because if you're getting your data from a webpage,
it sometimes quotes your numbers.
And then sometimes it doesn't if you do math on it later on.
Oh.
So, you know, there's options for stuff like that.
You know, like, is it a quoted number?
Is it unquoted?
Or maybe.
Oh, right, right.
And then there's one less branch there or not, you know,
and it's going to use that to do less checking or more checking.
When do you think V3 library is going to be released officially?
When I finish the documenting the changes.
So we're looking, I want to give myself a month or so.
It's pretty
close to being
used how I want to use it.
But there's
I want good docs
and lots of them
because
From what I see on GitHub, you already have
pretty good API documentation.
Doxygen looks like it's pretty easy to read through.
Yeah.
I wish there was something better than Doxygen.
Okay.
Well, Daryl, it's been great having you on the show.
Listeners should definitely go check out your GitHub page for a dog JSON link.
Anything else you want to plug before we let you go?
I just want to say thank you very much for having me.
It's been a pleasure to talk about C++. Certainly. what's happening on thanks so much for listening in as we chat
about c++ we'd love to hear what you think of the podcast please let us know if we're discussing the
stuff you're interested in or if you have a suggestion for a topic we'd love to hear about
that too you can email all your thoughts to feedback at cppcast.com we'd also appreciate
if you can like cppcast on facebook and follow cppcast oncom. We'd also appreciate if you can like CppCast on Facebook and follow
CppCast on Twitter.
You can also follow me at RobWIrving
and Jason at Lefticus on Twitter.
We'd also like to thank all our patrons
who help support the show through Patreon.
If you'd like to support us on Patreon,
you can do so at patreon.com
slash cppcast. And of course,
you can find all that info and the show notes
on the podcast website at cppcast.com.
Theme music for this episode was provided by podcastthemes.com.